UI/FormRegionEncryptionStatus.cs
author Dean Looyengoed
Fri, 15 Jan 2016 01:12:58 +0100
changeset 279 93fa916f4bc9
parent 277 f3195b41b414
child 280 dd7ed070e7d0
permissions -rw-r--r--
Make the encryption status form region control the state of the encryption manager.
Dean@159
     1
´╗┐using pEpCOMServerAdapterLib;
Dean@159
     2
using System;
vb@133
     3
using System.Collections.Generic;
Dean@159
     4
using System.Diagnostics;
vb@133
     5
using System.Linq;
Dean@159
     6
using System.Runtime.InteropServices;
vb@133
     7
using System.Windows.Forms;
Dean@159
     8
using Color = System.Drawing.Color;
vb@133
     9
using Outlook = Microsoft.Office.Interop.Outlook;
vb@133
    10
vb@133
    11
namespace pEp
vb@133
    12
{
Dean@159
    13
    /// <summary>
Dean@159
    14
    /// Partial class for the encryption status panel that is displayed below every outlook message.
Dean@159
    15
    /// </summary>
Dean@196
    16
    partial class FormRegionEncryptionStatus
vb@133
    17
    {
Dean@244
    18
        private const int SELECTION_LIST_OPEN_THRESHOLD = 1; // Selection list will open if greater or equal to this value
Dean@244
    19
vb@133
    20
        #region Form Region Factory
vb@133
    21
vb@133
    22
        [Microsoft.Office.Tools.Outlook.FormRegionMessageClass(Microsoft.Office.Tools.Outlook.FormRegionMessageClassAttribute.Note)]
Dean@196
    23
        [Microsoft.Office.Tools.Outlook.FormRegionName("pEp.FormRegionEncryptionStatus")]
Dean@196
    24
        public partial class FormRegionEncryptionStatusFactory
vb@133
    25
        {
vb@133
    26
            // Occurs before the form region is initialized.
vb@133
    27
            // To prevent the form region from appearing, set e.Cancel to true.
vb@133
    28
            // Use e.OutlookItem to get a reference to the current Outlook item.
Dean@196
    29
            private void FormRegionEncryptionStatus_FormRegionInitializing(object sender, Microsoft.Office.Tools.Outlook.FormRegionInitializingEventArgs e)
vb@133
    30
            {
vb@133
    31
            }
vb@133
    32
        }
vb@133
    33
vb@133
    34
        #endregion
vb@133
    35
Dean@159
    36
        /* Notes:
Dean@179
    37
         * 
Dean@159
    38
         * Use this.OutlookItem to get a reference to the current Outlook item.
Dean@159
    39
         * Use this.OutlookFormRegion to get a reference to the form region.
Dean@179
    40
         * 
Dean@179
    41
         * UI State Managment:
Dean@179
    42
         * 
Dean@179
    43
         * The UI state is almost entirely set from the associated mail item data.
Dean@179
    44
         * However, a separate state class is maintained to represent the UI as some separation is needed.
Dean@179
    45
         * This logical separation MUST be maintained throughout the code.
Dean@179
    46
         * Specific cases are noted where possible.
Dean@179
    47
         * 
Dean@259
    48
         * The separate encryption status manager form state is also managed here.
Dean@259
    49
         * 
Dean@159
    50
         */
Dean@159
    51
Dean@170
    52
        private CryptableMailItem associatedMailItem = null;
Dean@179
    53
        private bool              refreshOngoing     = false;
Dean@179
    54
        private bool              eventsAreConnected = false;
Dean@170
    55
Dean@259
    56
        private FormManageEncryptionStatus managerForm = null;
Dean@259
    57
Dean@250
    58
        // Data or controls not stored in the UI
Dean@179
    59
        private _pEp_color stateUIColorRating; // WARNING: Do NOT use this directly
vb@133
    60
Dean@159
    61
        /**************************************************************
Dean@159
    62
         * 
Dean@159
    63
         * Methods
Dean@159
    64
         * 
Dean@159
    65
         *************************************************************/
Dean@159
    66
Dean@171
    67
        /// <summary>
Dean@170
    68
        /// Sets the cryptable mail item associated with this encryption status panel.
Dean@170
    69
        /// The associated mail item can then be accessed through its local variable.
Dean@170
    70
        /// </summary>
Dean@170
    71
        private void SetAssociatedMailItem()
Dean@170
    72
        {
Dean@170
    73
            bool errorOccurred = false;
Dean@170
    74
            Outlook.MailItem omi = null;
Dean@170
    75
Dean@170
    76
            // Null check
Dean@170
    77
            if (!errorOccurred)
Dean@170
    78
            {
Dean@170
    79
                try
Dean@170
    80
                {
Dean@170
    81
                    if (this.OutlookItem == null)
Dean@170
    82
                    {
Dean@170
    83
                        errorOccurred = true;
Dean@170
    84
                    }
Dean@170
    85
                }
Dean@170
    86
                catch (COMException)
Dean@170
    87
                {
Dean@170
    88
                    errorOccurred = true;
Dean@170
    89
                }
Dean@170
    90
            }
Dean@170
    91
Dean@170
    92
            // Attempt to get and cast the outlook mail item
Dean@170
    93
            if (!errorOccurred)
Dean@170
    94
            {
Dean@170
    95
                try
Dean@170
    96
                {
Dean@170
    97
                    omi = (Outlook.MailItem)this.OutlookItem;
Dean@170
    98
                }
Dean@170
    99
                catch
Dean@170
   100
                {
Dean@170
   101
                    errorOccurred = true;
Dean@170
   102
                }
Dean@170
   103
            }
Dean@170
   104
Dean@170
   105
            // Finally set the associated mail item
Dean@170
   106
            if ((errorOccurred) ||
Dean@170
   107
                (omi == null))
Dean@170
   108
            {
Dean@170
   109
                this.associatedMailItem = null;
Dean@170
   110
            }
Dean@170
   111
            else
Dean@170
   112
            {
Dean@170
   113
                // Check if the associated mail item has already been set
Dean@170
   114
                if (this.associatedMailItem != null)
Dean@170
   115
                {
Dean@170
   116
                    // Only re-set the mail item if the EntryID has changed
Dean@170
   117
                    if (this.associatedMailItem.EntryID != omi.EntryID)
Dean@170
   118
                    {
Dean@170
   119
                        this.associatedMailItem = new CryptableMailItem(omi);
Dean@170
   120
                    }
Dean@170
   121
                }
Dean@170
   122
                else
Dean@170
   123
                {
Dean@170
   124
                    this.associatedMailItem = new CryptableMailItem(omi);
Dean@170
   125
                }
Dean@170
   126
            }
Dean@170
   127
Dean@170
   128
            return;
Dean@170
   129
        }
Dean@170
   130
Dean@179
   131
        /// <summary>
Dean@179
   132
        /// Starts the handshake process where the identity of a partner can be confirmed.
Dean@179
   133
        /// </summary>
Dean@179
   134
        /// <param name="identityPartner">The identity of the partner to complete the handshake with.</param>
Dean@179
   135
        private void DoHandshake(pEp_identity_s identityPartner)
vb@133
   136
        {
Dean@155
   137
            string ownShort;
Dean@155
   138
            string ownLong;
Dean@155
   139
            string ownFpr;
Dean@155
   140
            string partnerShort;
Dean@155
   141
            string partnerLong;
Dean@155
   142
            string partnerFpr;
Dean@155
   143
            string[] lines;
Dean@179
   144
            DialogResult result;
Dean@155
   145
            pEp_identity_s me;
Dean@155
   146
            FormHandshake handshakeDialog;
Dean@155
   147
            FormHandshake.State state = new FormHandshake.State();
markus@201
   148
Dean@190
   149
            Globals.ThisAddIn.LogVerbose("doHandshake");
Dean@190
   150
            Globals.ThisAddIn.LogVerbose(identityPartner.address);
vb@139
   151
vb@132
   152
            if (identityPartner.username == "")
vb@133
   153
                identityPartner.username = identityPartner.address;
Dean@190
   154
            Globals.ThisAddIn.LogVerbose(identityPartner.username);
vb@133
   155
dean@144
   156
            identityPartner.user_id = CryptableMailItem.GetUserIDFromAddress(identityPartner.address, identityPartner.username);
Dean@190
   157
            Globals.ThisAddIn.LogVerbose(identityPartner.user_id);
vb@133
   158
Dean@173
   159
            if (this.associatedMailItem.IsIncoming)
vb@133
   160
            {
Dean@173
   161
                string entryID = this.associatedMailItem.ReceivedByEntryID;
vb@133
   162
                string address = "";
vb@133
   163
markus@201
   164
                foreach (Outlook.Account a in Globals.ThisAddIn.Application.Session.Accounts)
markus@201
   165
                {
markus@201
   166
                    if (a.CurrentUser.EntryID == entryID)
markus@201
   167
                    {
vb@133
   168
                        address = a.SmtpAddress;
vb@133
   169
                        break;
vb@133
   170
                    }
vb@133
   171
                }
vb@133
   172
vb@133
   173
                if (address == "")
Dean@190
   174
                    address = Globals.ThisAddIn.Application.Session.Accounts[1].SmtpAddress;
vb@133
   175
Dean@190
   176
                me = Globals.ThisAddIn.mySelf(address);
vb@133
   177
            }
vb@133
   178
            else // outgoing
vb@133
   179
            {
Dean@190
   180
                Globals.ThisAddIn.LogVerbose("mailItem.from_address: " + this.associatedMailItem.FromAddress);
Dean@190
   181
                me = Globals.ThisAddIn.mySelf(this.associatedMailItem.FromAddress);
vb@133
   182
            }
vb@133
   183
Dean@190
   184
            Globals.ThisAddIn.LogVerbose(me.fpr);
vb@139
   185
Dean@155
   186
            ownShort = ThisAddIn.pEp.trustwords(me.fpr, max_words: 5).ToLower();
markus@201
   187
            ownLong = ThisAddIn.pEp.trustwords(me.fpr).ToLower();
markus@201
   188
            ownFpr = this.ToQuadruple(me.fpr);
vb@133
   189
Dean@190
   190
            Globals.ThisAddIn.LogVerbose(identityPartner.fpr);
vb@139
   191
Dean@155
   192
            partnerShort = ThisAddIn.pEp.trustwords(identityPartner.fpr, max_words: 5).ToLower();
markus@201
   193
            partnerLong = ThisAddIn.pEp.trustwords(identityPartner.fpr).ToLower();
markus@201
   194
            partnerFpr = this.ToQuadruple(identityPartner.fpr);
vb@133
   195
Dean@155
   196
            if (ownFpr.CompareTo(partnerFpr) > 0)
vb@133
   197
            {
Dean@155
   198
                state.TrustwordsShort = partnerShort + ownShort;
markus@201
   199
                state.TrustwordsFull = partnerLong + ownLong;
Dean@155
   200
Dean@155
   201
                lines = new string[3];
Dean@155
   202
                lines[0] = pEp.Properties.Resources.TrustwordsPartnershortPartner + partnerFpr;
Dean@155
   203
                lines[2] = pEp.Properties.Resources.TrustwordsPartnershortMyself + ownFpr;
Dean@155
   204
                state.Fingerprint = lines;
vb@133
   205
            }
vb@133
   206
            else
vb@133
   207
            {
Dean@155
   208
                state.TrustwordsShort = ownShort + " " + partnerShort;
markus@201
   209
                state.TrustwordsFull = ownLong + " " + partnerLong;
Dean@155
   210
Dean@155
   211
                lines = new string[3];
Dean@155
   212
                lines[0] = pEp.Properties.Resources.TrustwordsOwnshortMyself + ownFpr;
Dean@155
   213
                lines[2] = pEp.Properties.Resources.TrustwordsOwnshortPartner + partnerFpr;
Dean@155
   214
                state.Fingerprint = lines;
vb@133
   215
            }
vb@133
   216
Dean@190
   217
            Globals.ThisAddIn.LogVerbose("try to show dialog");
vb@139
   218
Dean@155
   219
            // Create and show handshake dialog
Dean@155
   220
            handshakeDialog = new FormHandshake(state);
Dean@179
   221
            handshakeDialog.StartPosition = FormStartPosition.CenterScreen;
Dean@179
   222
            result = handshakeDialog.ShowDialog(this);
Dean@155
   223
Dean@190
   224
            Globals.ThisAddIn.LogVerbose("handshakeDialog.ShowDialog(this) => " + result.ToString());
vb@133
   225
vb@133
   226
            switch (result)
vb@133
   227
            {
vb@133
   228
                case DialogResult.Yes:
Dean@279
   229
                    {
Dean@279
   230
                        identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   231
                        identityPartner = ThisAddIn.pEp.trust_personal_key(ref identityPartner);
Dean@279
   232
                        identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   233
Dean@279
   234
                        // Save any manager form data
Dean@279
   235
                        if (this.managerForm != null)
Dean@279
   236
                        {
Dean@279
   237
                            this.SetManagerState(this.managerForm.CopyUIToState());
Dean@279
   238
                        }
Dean@279
   239
Dean@279
   240
                        this.UpdateUIFromMailItem();
Dean@279
   241
Dean@279
   242
                        // Update the manager form state
Dean@279
   243
                        if (this.managerForm != null)
Dean@279
   244
                        {
Dean@279
   245
                            this.managerForm.CopyStateToUI(this.GetManagerState());
Dean@279
   246
                        }
Dean@279
   247
Dean@279
   248
                        break;
Dean@279
   249
                    }
vb@133
   250
                case DialogResult.No:
Dean@279
   251
                    {
Dean@279
   252
                        identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   253
                        ThisAddIn.pEp.key_compromized(ref identityPartner);
Dean@279
   254
                        identityPartner.comm_type = _pEp_comm_type.pEp_ct_compromized;
Dean@279
   255
                        identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   256
Dean@279
   257
                        // Save any manager form data
Dean@279
   258
                        if (this.managerForm != null)
Dean@279
   259
                        {
Dean@279
   260
                            this.SetManagerState(this.managerForm.CopyUIToState());
Dean@279
   261
                        }
Dean@279
   262
Dean@279
   263
                        this.UpdateUIFromMailItem();
Dean@279
   264
Dean@279
   265
                        // Update the manager form state
Dean@279
   266
                        if (this.managerForm != null)
Dean@279
   267
                        {
Dean@279
   268
                            this.managerForm.CopyStateToUI(this.GetManagerState());
Dean@279
   269
                        }
Dean@279
   270
Dean@279
   271
                        break;
Dean@279
   272
                    }
vb@133
   273
            }
Dean@279
   274
Dean@279
   275
            return;
vb@133
   276
        }
vb@133
   277
Dean@179
   278
        /// <summary>
Dean@179
   279
        /// Reverses any past handshake confirmation by unconfirming the given identity partner.
Dean@179
   280
        /// </summary>
Dean@179
   281
        /// <param name="identityPartner">The identity of the partner to unconfirm.</param>
Dean@179
   282
        private void UndoHandshake(pEp_identity_s identityPartner)
vb@133
   283
        {
Dean@279
   284
            identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   285
            ThisAddIn.pEp.reset_trust(ref identityPartner);
Dean@279
   286
            identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@279
   287
Dean@279
   288
            // Save any manager form data
Dean@279
   289
            if (this.managerForm != null)
Dean@279
   290
            {
Dean@279
   291
                this.SetManagerState(this.managerForm.CopyUIToState());
Dean@279
   292
            }
markus@201
   293
Dean@179
   294
            this.UpdateUIFromMailItem();
Dean@279
   295
Dean@279
   296
            // Update the manager form state
Dean@279
   297
            if (this.managerForm != null)
Dean@279
   298
            {
Dean@279
   299
                this.managerForm.CopyStateToUI(this.GetManagerState());
Dean@279
   300
            }
Dean@279
   301
Dean@279
   302
            return;
vb@133
   303
        }
vb@133
   304
Dean@161
   305
        /// <summary>
Dean@161
   306
        /// Formats the given text string as separated 4-character groups.
Dean@161
   307
        /// Example: 49422235FC99585B891C --> 4942 2235 FC99 585B 891C
Dean@161
   308
        /// </summary>
Dean@161
   309
        /// <param name="text">The text to format in 4-character groups.</param>
Dean@161
   310
        /// <returns>The re-formatted string.</returns>
Dean@161
   311
        private string ToQuadruple(string text)
Dean@159
   312
        {
Dean@159
   313
            List<string> result = new List<string>();
Dean@159
   314
Dean@161
   315
            if (text != null)
Dean@159
   316
            {
Dean@161
   317
                for (int i = 0; i < text.Length; i += 4)
Dean@159
   318
                {
Dean@161
   319
                    try
Dean@161
   320
                    {
Dean@161
   321
                        result.Add(text.Substring(i, 4));
Dean@161
   322
                    }
Dean@161
   323
                    catch (ArgumentOutOfRangeException)
Dean@161
   324
                    {
Dean@161
   325
                        result.Add(text.Substring(i));
Dean@161
   326
                        break;
Dean@161
   327
                    }
Dean@159
   328
                }
Dean@159
   329
            }
Dean@159
   330
Dean@159
   331
            return String.Join(" ", result);
Dean@159
   332
        }
markus@201
   333
Dean@196
   334
        /// <summary>
Dean@196
   335
        /// Makes the unencrypted preview form.
Dean@196
   336
        /// This gets the active form region then fills it's content.
Dean@196
   337
        /// </summary>
Dean@198
   338
        /// <returns>True if successful, otherwise false.</returns>
Dean@198
   339
        private bool MakePreview()
Dean@159
   340
        {
Dean@198
   341
            bool success = true;
Dean@198
   342
            bool isSuccessful;
Dean@198
   343
            byte[] rtfBody;
Dean@198
   344
            string subject;
Dean@159
   345
            WindowFormRegionCollection formRegions;
markus@201
   346
Dean@198
   347
            formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveExplorer()];
Dean@159
   348
Dean@198
   349
            if ((formRegions != null) &&
Dean@198
   350
                (formRegions.FormRegionPreviewUnencrypted != null) &&
Dean@198
   351
                (formRegions.FormRegionPreviewUnencrypted.Visible))
Dean@198
   352
            {
Dean@198
   353
                // Attempt to the the RTF body
Dean@198
   354
                isSuccessful = this.associatedMailItem.MirrorTryGetRTFBody(out rtfBody);
Dean@198
   355
                if (isSuccessful == false)
Dean@198
   356
                {
Dean@198
   357
                    return (false);
Dean@198
   358
                }
Dean@159
   359
Dean@198
   360
                // Attempt to get the subject
Dean@198
   361
                isSuccessful = this.associatedMailItem.MirrorTryGetSubject(out subject);
Dean@198
   362
                if (isSuccessful == false)
Dean@159
   363
                {
Dean@198
   364
                    return (false);
Dean@159
   365
                }
Dean@196
   366
Dean@198
   367
                // Add data to the form
markus@201
   368
                formRegions.FormRegionPreviewUnencrypted.RichTextBoxPreview.Rtf = System.Text.Encoding.ASCII.GetString(rtfBody, 0, rtfBody.Length);
markus@201
   369
                formRegions.FormRegionPreviewUnencrypted.TextBoxSubject.Text = subject;
markus@201
   370
                formRegions.FormRegionPreviewUnencrypted.TextBoxFrom.Text = this.associatedMailItem.FromUsername + " <" + this.associatedMailItem.FromAddress + ">";
Dean@198
   371
            }
Dean@198
   372
            else
Dean@198
   373
            {
Dean@198
   374
                success = false;
Dean@198
   375
            }
Dean@198
   376
Dean@198
   377
            return (success);
Dean@159
   378
        }
markus@201
   379
Dean@179
   380
        /// <summary>
Dean@279
   381
        /// Copies any necessary data from the given manager form state back into this encryption status/mail item current state.
Dean@259
   382
        /// </summary>
Dean@279
   383
        /// <param name="state">The state to copy data from.</param>
Dean@279
   384
        private void SetManagerState(FormManageEncryptionStatus.State state)
Dean@259
   385
        {
Dean@279
   386
            if (state != null)
Dean@279
   387
            {
Dean@279
   388
                // Save send unencrypted
Dean@279
   389
                if (state.IsIncoming == false)
Dean@279
   390
                {
Dean@279
   391
                    switch (state.SendUnencrypted)
Dean@279
   392
                    {
Dean@279
   393
                        case CheckState.Checked:
Dean@279
   394
                            {
Dean@279
   395
                                // Set the mail item to checked
Dean@279
   396
                                this.associatedMailItem.SendUnencrypted = CheckState.Checked;
Dean@279
   397
                                break;
Dean@279
   398
                            }
Dean@279
   399
                        case CheckState.Unchecked:
Dean@279
   400
                            {
Dean@279
   401
                                // Set the mail item to unchecked ONLY if it was previously checked
Dean@279
   402
                                // This is necessary because the UI will default to unchecked if interminate
Dean@279
   403
                                if (this.associatedMailItem.SendUnencrypted == CheckState.Checked)
Dean@279
   404
                                {
Dean@279
   405
                                    this.associatedMailItem.SendUnencrypted = CheckState.Unchecked;
Dean@279
   406
                                }
Dean@279
   407
                                break;
Dean@279
   408
                            }
Dean@279
   409
                        case CheckState.Indeterminate:
Dean@279
   410
                            {
Dean@279
   411
                                // Set the mail item to indeterminate
Dean@279
   412
                                this.associatedMailItem.SendUnencrypted = CheckState.Indeterminate;
Dean@279
   413
                                break;
Dean@279
   414
                            }
Dean@279
   415
                    }
Dean@279
   416
Dean@279
   417
                    this.UpdateUIFromMailItem();
Dean@279
   418
                }
Dean@279
   419
            }
Dean@279
   420
Dean@279
   421
            return;
Dean@279
   422
        }
Dean@279
   423
Dean@279
   424
        /// <summary>
Dean@279
   425
        /// Builds a new manager form state using this encryption state/mail item current state.
Dean@279
   426
        /// </summary>
Dean@279
   427
        /// <returns>A new manager form state.</returns>
Dean@279
   428
        private FormManageEncryptionStatus.State GetManagerState()
Dean@279
   429
        {
Dean@259
   430
            pEp_identity_s[] identities;
Dean@259
   431
            pEp_identity_s incomingIdent;
Dean@259
   432
            pEp_identity_s identityPartner;
Dean@259
   433
            _pEp_color identityPartnerColor;
Dean@259
   434
            SelectionItem item;
Dean@279
   435
            EncryptionState state = this.CopyUIToState();
Dean@279
   436
            FormManageEncryptionStatus.State managerState = new FormManageEncryptionStatus.State();
Dean@259
   437
Dean@279
   438
            managerState.VisualState = state.Copy();
Dean@279
   439
            managerState.SendUnencrypted = this.associatedMailItem.SendUnencrypted;
Dean@279
   440
            managerState.IsIncoming = this.associatedMailItem.IsIncoming;
Dean@279
   441
            managerState.EncryptionStatusReason = this.BuildEncryptionStatusReason(state.EncryptionStatus);
Dean@259
   442
Dean@259
   443
            if (this.associatedMailItem.IsIncoming)
Dean@259
   444
            {
Dean@259
   445
                identities = new pEp_identity_s[1];
Dean@259
   446
Dean@259
   447
                // Add only one identity
Dean@259
   448
                incomingIdent = new pEp_identity_s();
Dean@259
   449
                incomingIdent.address = this.associatedMailItem.FromAddress;
Dean@259
   450
                incomingIdent.username = this.associatedMailItem.FromUsername;
Dean@259
   451
                incomingIdent.user_id = CryptableMailItem.GetUserIDFromAddress(incomingIdent.address, incomingIdent.username);
Dean@259
   452
Dean@259
   453
                identities[0] = incomingIdent;
Dean@259
   454
            }
Dean@259
   455
            else
Dean@259
   456
            {
Dean@259
   457
                identities = this.associatedMailItem.Addresses;
Dean@259
   458
            }
Dean@259
   459
Dean@279
   460
            // Add identities
Dean@279
   461
            managerState.Identities.Clear();
Dean@259
   462
            foreach (pEp_identity_s ident in identities)
Dean@259
   463
            {
Dean@259
   464
                identityPartner = ThisAddIn.pEp.update_identity(ident);
Dean@259
   465
                identityPartnerColor = ThisAddIn.pEp.identity_color(identityPartner);
Dean@259
   466
Dean@259
   467
                item = new SelectionItem();
Dean@259
   468
                item.TextLine1 = identityPartner.username;
Dean@259
   469
                item.TextLine2 = identityPartner.address;
Dean@259
   470
Dean@259
   471
                // Set image
Dean@259
   472
                switch (identityPartnerColor)
Dean@259
   473
                {
Dean@259
   474
                    case _pEp_color.pEp_rating_trusted:
Dean@259
   475
                    case _pEp_color.pEp_rating_trusted_and_anonymized:
Dean@259
   476
                        item.ItemImage = pEp.Properties.Resources.green;
Dean@259
   477
                        break;
Dean@259
   478
                    case _pEp_color.pEp_rating_reliable:
Dean@259
   479
                        item.ItemImage = pEp.Properties.Resources.yellow;
Dean@259
   480
                        break;
Dean@259
   481
                    case _pEp_color.pEp_rating_under_attack:
Dean@259
   482
                        item.ItemImage = pEp.Properties.Resources.red;
Dean@259
   483
                        break;
Dean@259
   484
                    default:
Dean@259
   485
                        item.ItemImage = null;
Dean@259
   486
                        break;
Dean@259
   487
                }
Dean@259
   488
Dean@259
   489
                // Set button
Dean@259
   490
                if (identityPartner.comm_type >= _pEp_comm_type.pEp_ct_confirmed_encryption)
Dean@259
   491
                {
Dean@259
   492
                    // Undo handshake
Dean@277
   493
                    item.TextButton = pEp.Properties.Resources.StopTrusting;
Dean@259
   494
                    item.IsButtonVisible = true;
Dean@259
   495
                    item.OnClick = (x, y) => { this.UndoHandshake(ident); };
Dean@259
   496
                }
Dean@259
   497
                else if (identityPartner.comm_type >= _pEp_comm_type.pEp_ct_unconfirmed_encryption &&
Dean@259
   498
                         identityPartner.comm_type < _pEp_comm_type.pEp_ct_confirmed_encryption)
Dean@259
   499
                {
Dean@259
   500
                    // Do handshake
Dean@277
   501
                    item.TextButton = pEp.Properties.Resources.Handshake;
Dean@259
   502
                    item.IsButtonVisible = true;
Dean@259
   503
                    item.OnClick = (x, y) => { this.DoHandshake(identityPartner); };
Dean@259
   504
                }
Dean@259
   505
                else
Dean@259
   506
                {
Dean@259
   507
                    // No button, just view
Dean@259
   508
                    item.IsButtonVisible = false;
Dean@259
   509
                }
Dean@259
   510
Dean@279
   511
                managerState.Identities.Add(item);
Dean@259
   512
            }
Dean@259
   513
Dean@279
   514
            return (managerState);
Dean@279
   515
        }
Dean@279
   516
Dean@279
   517
        /// <summary>
Dean@279
   518
        /// Builds the latest state of the encryption status manager then shows the UI.
Dean@279
   519
        /// </summary>
Dean@279
   520
        private void BuildAndShowManager()
Dean@279
   521
        {
Dean@279
   522
            DialogResult result;
Dean@279
   523
            FormManageEncryptionStatus form;
Dean@279
   524
            FormManageEncryptionStatus.State stateOut;
Dean@279
   525
Dean@259
   526
            // Show the form
Dean@259
   527
            form = new FormManageEncryptionStatus();
Dean@259
   528
            form.StartPosition = FormStartPosition.CenterScreen;
Dean@259
   529
Dean@259
   530
            this.managerForm = form;
Dean@279
   531
            result = form.ShowDialog(this.ParentForm, this.GetManagerState(), out stateOut); // Must show as dialog to block code
Dean@259
   532
Dean@259
   533
            if (result == DialogResult.OK)
Dean@259
   534
            {
Dean@279
   535
                this.SetManagerState(stateOut);
Dean@259
   536
            }
Dean@259
   537
Dean@259
   538
            return;
Dean@259
   539
        }
Dean@259
   540
Dean@259
   541
        /// <summary>
Dean@259
   542
        /// Builds the reason string for the given color rating of the associated mail item.
Dean@259
   543
        /// </summary>
Dean@259
   544
        /// <param name="colorRating">The encryption status color rating to get the reason for.</param>
Dean@259
   545
        /// <returns>The encryption status reason string or null.</returns>
Dean@259
   546
        private string BuildEncryptionStatusReason(_pEp_color colorRating)
Dean@259
   547
        {
Dean@259
   548
            string reason = null;
Dean@259
   549
            string keyinfo;
Dean@259
   550
            string[] keys;
Dean@259
   551
Dean@259
   552
            switch (colorRating)
Dean@259
   553
            {
Dean@259
   554
                case (_pEp_color.pEp_rating_green):
Dean@259
   555
                    {
Dean@266
   556
                        // Add all keys the message is encrypted with
Dean@266
   557
                        try
Dean@266
   558
                        {
Dean@266
   559
                            keys = this.associatedMailItem.Keylist;
Dean@259
   560
Dean@266
   561
                            if (keys.Length > 0)
Dean@266
   562
                            {
Dean@266
   563
                                if (keys.Length > 1)
Dean@266
   564
                                {
Dean@266
   565
                                    reason = String.Format(pEp.Properties.Resources.EncryptionStatusClickMessageMultiple + " {0}.",
Dean@266
   566
                                                           String.Join(", ", keys));
Dean@266
   567
                                }
Dean@266
   568
                                else
Dean@266
   569
                                {
Dean@266
   570
                                    reason = String.Format(pEp.Properties.Resources.EncryptionStatusClickMessageSingle + " {0}.",
Dean@266
   571
                                                           keys[0]);
Dean@266
   572
                                }
Dean@266
   573
                            }
Dean@266
   574
                        }
Dean@266
   575
                        catch (Exception) { }
Dean@266
   576
                        break;
Dean@266
   577
                    }
Dean@266
   578
                case (_pEp_color.pEp_rating_yellow):
Dean@266
   579
                    {
Dean@266
   580
                        // Reason is empty -- a handshake dialog will be shown
Dean@266
   581
                        break;
Dean@266
   582
                    }
Dean@266
   583
                case (_pEp_color.pEp_rating_unencrypted):
Dean@266
   584
                    {
Dean@266
   585
                        if (this.associatedMailItem.IsIncoming)
Dean@259
   586
                        {
Dean@266
   587
                            reason = pEp.Properties.Resources.RatingUnencryptedMessageboxReasonBody;
Dean@266
   588
                        }
Dean@266
   589
                        else
Dean@266
   590
                        {
Dean@266
   591
                            if (this.associatedMailItem.SendUnencrypted == CheckState.Checked)
Dean@259
   592
                            {
Dean@277
   593
                                reason = pEp.Properties.Resources.RatingUnencryptedMessageboxReasonBody2;
Dean@259
   594
                            }
Dean@259
   595
                            else
Dean@259
   596
                            {
Dean@266
   597
                                // Add all identity comm types
Dean@266
   598
                                try
Dean@266
   599
                                {
Dean@266
   600
                                    reason = "";
Dean@266
   601
                                    foreach (pEp_identity_s identity in this.associatedMailItem.Addresses)
Dean@266
   602
                                    {
Dean@266
   603
                                        if (identity.comm_type < _pEp_comm_type.pEp_ct_security_by_obscurity)
Dean@266
   604
                                        {
Dean@266
   605
                                            if (reason != "")
Dean@266
   606
                                            {
Dean@266
   607
                                                reason += "\n";
Dean@266
   608
                                            }
Dean@266
   609
Dean@266
   610
                                            // TODO: reason string in English language only and trivial
Dean@266
   611
                                            string ct = identity.comm_type.ToString();
Dean@266
   612
                                            ct = new string(ct.Skip(7).ToArray());
Dean@266
   613
                                            ct = ct.Replace("_", " ");
Dean@266
   614
                                            reason += identity.username + " <" + identity.address + ">: " + ct;
Dean@266
   615
                                        }
Dean@266
   616
                                    }
Dean@266
   617
                                }
Dean@266
   618
                                catch (COMException) { }
Dean@259
   619
                            }
Dean@259
   620
                        }
Dean@266
   621
                        break;
Dean@259
   622
                    }
Dean@259
   623
                case (_pEp_color.pEp_rating_cannot_decrypt):
Dean@259
   624
                case (_pEp_color.pEp_rating_have_no_key):
Dean@259
   625
                    {
Dean@266
   626
                        try
Dean@266
   627
                        {
Dean@266
   628
                            keys = this.associatedMailItem.Keylist;
Dean@259
   629
Dean@266
   630
                            if (keys.Length > 1)
Dean@259
   631
                            {
Dean@266
   632
                                if (keys.Length == 2)
Dean@266
   633
                                {
Dean@266
   634
                                    reason = pEp.Properties.Resources.RatingHavenokeyMessageboxReasonBodyNokey;
Dean@266
   635
                                }
Dean@266
   636
                                else
Dean@266
   637
                                {
Dean@266
   638
                                    reason = string.Format(pEp.Properties.Resources.RatingHavenokeyMessageboxReasonBodySomekey,
Dean@266
   639
                                                           keys.Length - 1);
Dean@266
   640
                                }
Dean@266
   641
Dean@266
   642
                                // Add each key
Dean@266
   643
                                keyinfo = "";
Dean@266
   644
                                foreach (string key in keys)
Dean@266
   645
                                {
Dean@266
   646
                                    if (key.Length >= 8)
Dean@266
   647
                                        keyinfo += "\n" + key;
Dean@266
   648
                                }
Dean@266
   649
Dean@266
   650
                                reason += keyinfo;
Dean@266
   651
                            }
Dean@266
   652
                            else if (keys.Length == 1)
Dean@266
   653
                            {
Dean@266
   654
                                reason = pEp.Properties.Resources.RatingHavenokeyMessageboxReasonError + keys[0];
Dean@259
   655
                            }
Dean@259
   656
                            else
Dean@259
   657
                            {
Dean@266
   658
                                reason = pEp.Properties.Resources.RatingHavenokeyMessageboxReasonUnknownformat;
Dean@259
   659
                            }
Dean@266
   660
                        }
Dean@266
   661
                        catch (COMException) { }
Dean@259
   662
Dean@266
   663
                        break;
Dean@259
   664
                    }
Dean@259
   665
                default:
Dean@266
   666
                    {
Dean@266
   667
                        // No reason
Dean@266
   668
                        break;
Dean@266
   669
                    }
Dean@259
   670
            }
Dean@259
   671
Dean@259
   672
            return (reason);
Dean@259
   673
        }
Dean@259
   674
Dean@259
   675
        /// <summary>
Dean@179
   676
        /// Updates the status of the UI state based on the associated mail item.
Dean@179
   677
        /// Any previous state changes in the UI are preserved.
Dean@179
   678
        /// </summary>
Dean@179
   679
        private void UpdateUIFromMailItem()
Dean@159
   680
        {
Dean@266
   681
            EncryptionState state;
Dean@159
   682
Dean@173
   683
            if (this.associatedMailItem != null)
Dean@159
   684
            {
Dean@179
   685
                if (this.associatedMailItem.SendUnencrypted == CheckState.Checked)
Dean@159
   686
                {
Dean@179
   687
                    // Always set to unencrypted
Dean@266
   688
                    state = new EncryptionState(_pEp_color.pEp_rating_unencrypted);
Dean@159
   689
                }
Dean@159
   690
                else
Dean@159
   691
                {
Dean@266
   692
                    state = new EncryptionState(this.associatedMailItem.ColorRating);
Dean@159
   693
                }
Dean@179
   694
Dean@179
   695
                this.CopyStateToUI(state);
Dean@159
   696
            }
Dean@159
   697
Dean@179
   698
            return;
Dean@159
   699
        }
Dean@159
   700
Dean@172
   701
        #region StateMethods
Dean@172
   702
Dean@172
   703
        /// <summary>
Dean@172
   704
        /// Connects or disconnects all control events from the UI.
Dean@172
   705
        /// </summary>
Dean@172
   706
        /// <param name="connect">True to connect events, false to disconnect.</param>
Dean@172
   707
        private void ConnectEvents(bool connect)
Dean@172
   708
        {
Dean@172
   709
            // Connect events only if not already connected
markus@201
   710
            if ((connect == true) &&
Dean@172
   711
                (this.eventsAreConnected == false))
Dean@172
   712
            {
markus@201
   713
                this.ButtonEncryptionStatus.Click += this.ButtonEncryptionStatus_Click;
markus@201
   714
                this.ButtonEncryptionStatus.MouseUp += this.ButtonEncryptionStatus_MouseUp;
Dean@179
   715
                this.LinkLabelExplanation.LinkClicked += this.LinkLabelExplanation_LinkClicked;
Dean@179
   716
markus@201
   717
                this.PictureBoxOptions.Click += this.PictureBoxOptions_Click;
Dean@179
   718
                this.PictureBoxOptions.MouseHover += this.PictureBoxOptions_MouseHover;
Dean@179
   719
Dean@172
   720
                this.eventsAreConnected = true;
Dean@172
   721
            }
Dean@172
   722
            // Always attempt to disconnect
Dean@172
   723
            else if (connect == false)
Dean@172
   724
            {
markus@201
   725
                this.ButtonEncryptionStatus.Click -= this.ButtonEncryptionStatus_Click;
markus@201
   726
                this.ButtonEncryptionStatus.MouseUp -= this.ButtonEncryptionStatus_MouseUp;
Dean@179
   727
                this.LinkLabelExplanation.LinkClicked -= this.LinkLabelExplanation_LinkClicked;
Dean@179
   728
markus@201
   729
                this.PictureBoxOptions.Click -= this.PictureBoxOptions_Click;
Dean@179
   730
                this.PictureBoxOptions.MouseHover -= this.PictureBoxOptions_MouseHover;
Dean@179
   731
Dean@172
   732
                this.eventsAreConnected = false;
Dean@172
   733
            }
Dean@172
   734
Dean@172
   735
            return;
Dean@172
   736
        }
Dean@172
   737
Dean@172
   738
        /// <summary>
Dean@172
   739
        /// Refreshes the UI by reloading the state.
Dean@172
   740
        /// </summary>
Dean@172
   741
        private void RefreshUI()
Dean@172
   742
        {
Dean@172
   743
            this.CopyStateToUI(this.CopyUIToState());
Dean@172
   744
            return;
Dean@172
   745
        }
Dean@172
   746
Dean@172
   747
        /// <summary>
Dean@172
   748
        /// Copies the given state to the UI.
Dean@172
   749
        /// Events are turned off until the process is complete.
Dean@172
   750
        /// </summary>
Dean@172
   751
        /// <param name="state">The state to set to the UI.</param>
Dean@266
   752
        private void CopyStateToUI(EncryptionState state)
Dean@172
   753
        {
Dean@172
   754
            this.ConnectEvents(false);
markus@201
   755
Dean@172
   756
            ///////////////////////////////////////////////////////////
Dean@172
   757
            // Set UI data
Dean@172
   758
            ///////////////////////////////////////////////////////////
Dean@172
   759
Dean@179
   760
            // Save UI state maintained outside of controls
Dean@259
   761
            this.stateUIColorRating = state.EncryptionStatus;
Dean@179
   762
Dean@259
   763
            this.ButtonEncryptionStatus.BackColor = state.BackgroundColor;
Dean@259
   764
            this.ButtonEncryptionStatus.ForeColor = state.ForegroundColor;
Dean@259
   765
            this.ButtonEncryptionStatus.Text = state.ShortText;
Dean@259
   766
            this.LinkLabelExplanation.Text = state.LongText;
Dean@172
   767
Dean@172
   768
            this.ConnectEvents(true);
Dean@172
   769
Dean@172
   770
            return;
Dean@172
   771
        }
Dean@172
   772
Dean@172
   773
        /// <summary>
Dean@172
   774
        /// Copies the UI to a new state.
Dean@172
   775
        /// </summary>
Dean@172
   776
        /// <returns>The state of the UI.</returns>
Dean@266
   777
        private EncryptionState CopyUIToState()
Dean@172
   778
        {
Dean@266
   779
            return (new EncryptionState(this.stateUIColorRating));
Dean@172
   780
        }
Dean@172
   781
Dean@172
   782
        #endregion
Dean@172
   783
Dean@159
   784
        /**************************************************************
Dean@159
   785
         * 
Dean@159
   786
         * Event Handling
Dean@159
   787
         * 
Dean@159
   788
         *************************************************************/
Dean@159
   789
Dean@159
   790
        /// <summary>
Dean@159
   791
        /// Event handler that is called before the form region is displayed.
Dean@159
   792
        /// </summary>
Dean@196
   793
        private void FormRegionEncryptionStatus_FormRegionShowing(object sender, System.EventArgs e)
Dean@159
   794
        {
Dean@173
   795
            this.SetAssociatedMailItem();
Dean@173
   796
Dean@199
   797
            // Connect cryptable mail item events
Dean@189
   798
            if (this.associatedMailItem != null)
Dean@159
   799
            {
Dean@159
   800
                try
Dean@159
   801
                {
Dean@189
   802
                    this.associatedMailItem.PropertyChange += MailItem_PropertyChange;
Dean@179
   803
Dean@189
   804
                    if (this.associatedMailItem.IsInEncryptedStore &&
Dean@198
   805
                        this.associatedMailItem.IsPGPEncrypted)
Dean@159
   806
                    {
Dean@189
   807
                        this.associatedMailItem.Open += MailItem_Open;
Dean@159
   808
                    }
Dean@159
   809
                }
Dean@159
   810
                catch { }
Dean@179
   811
            }
Dean@159
   812
Dean@179
   813
            // Set the default UI state
Dean@266
   814
            this.CopyStateToUI(new EncryptionState());
Dean@179
   815
Dean@199
   816
            // Call the timer tick method manually to refresh data
Dean@199
   817
            this.TimerRefresh_Tick(null, new EventArgs());
Dean@179
   818
Dean@179
   819
            return;
Dean@159
   820
        }
Dean@159
   821
Dean@159
   822
        /// <summary>
Dean@159
   823
        /// Event handler for when the form region is closed.
Dean@159
   824
        /// </summary>
Dean@196
   825
        private void FormRegionEncryptionStatus_FormRegionClosed(object sender, System.EventArgs e)
Dean@159
   826
        {
Dean@199
   827
            // Disconnect cryptable mail item events
Dean@190
   828
            if (this.associatedMailItem != null)
Dean@179
   829
            {
Dean@179
   830
                try
Dean@179
   831
                {
Dean@190
   832
                    this.associatedMailItem.PropertyChange -= MailItem_PropertyChange;
markus@201
   833
                    this.associatedMailItem.Open -= MailItem_Open;
Dean@179
   834
                }
Dean@179
   835
                catch { }
Dean@179
   836
            }
Dean@179
   837
Dean@179
   838
            return;
Dean@179
   839
        }
Dean@179
   840
Dean@179
   841
        /// <summary>
Dean@179
   842
        /// Event handler called after the refresh timer has elapsed.
Dean@179
   843
        /// </summary>
Dean@179
   844
        private void TimerRefresh_Tick(object sender, EventArgs e)
Dean@179
   845
        {
Dean@199
   846
            bool tryAgain = false;
Dean@199
   847
            bool isSuccessful;
Dean@179
   848
            this.TimerRefresh.Enabled = false; // Only once
markus@201
   849
Dean@179
   850
            // Ensure the tick method is not called more than once
Dean@179
   851
            if (refreshOngoing == false)
Dean@179
   852
            {
Dean@179
   853
                this.refreshOngoing = true;
Dean@179
   854
Dean@179
   855
                if (this.associatedMailItem != null)
Dean@179
   856
                {
Dean@179
   857
                    if (this.associatedMailItem.DownloadState == Outlook.OlDownloadState.olFullItem)
Dean@179
   858
                    {
Dean@179
   859
                        this.UpdateUIFromMailItem();
Dean@199
   860
Dean@199
   861
                        /* Create the unencrypted preview if the mail item is encrypted and
Dean@199
   862
                         * it is in an encrypted (untrusted) store
Dean@199
   863
                         * 
Dean@199
   864
                         * This is done here because FormRegionEncryptionStatus has the cryptable mail item and
Dean@199
   865
                         * it also is initialized after FormRegionPreviewUnencrypted.
Dean@199
   866
                         */
Dean@199
   867
                        if (this.associatedMailItem.IsInEncryptedStore &&
Dean@199
   868
                            this.associatedMailItem.IsPGPEncrypted)
Dean@199
   869
                        {
Dean@199
   870
                            isSuccessful = this.MakePreview();
Dean@199
   871
Dean@199
   872
                            if (isSuccessful == false)
Dean@199
   873
                            {
Dean@199
   874
                                tryAgain = true;
Dean@199
   875
                            }
Dean@199
   876
                        }
Dean@179
   877
                    }
Dean@179
   878
                    else
Dean@179
   879
                    {
Dean@179
   880
                        this.associatedMailItem.MarkForDownload = Outlook.OlRemoteStatus.olMarkedForDownload;
Dean@199
   881
                        tryAgain = true;
Dean@179
   882
                    }
Dean@179
   883
                }
Dean@179
   884
Dean@199
   885
                // Set the timer to refresh again later automatically
Dean@199
   886
                if (tryAgain)
Dean@199
   887
                {
Dean@199
   888
                    this.TimerRefresh.Interval = 100;
Dean@199
   889
                    this.TimerRefresh.Enabled = true;
Dean@199
   890
                }
Dean@199
   891
Dean@179
   892
                this.refreshOngoing = false;
Dean@179
   893
            }
Dean@175
   894
Dean@159
   895
            return;
Dean@159
   896
        }
Dean@159
   897
Dean@169
   898
        /// <summary>
Dean@169
   899
        /// Event handler for when a mail item is being opened in an inspector.
Dean@180
   900
        /// See: https://msdn.microsoft.com/en-us/library/office/ff865989.aspx
Dean@169
   901
        /// </summary>
Dean@169
   902
        /// <param name="cancel">Whether to cancel the event: Value is False when the event occurs. 
Dean@169
   903
        /// If the event procedure sets this argument to True, the open operation is not completed 
Dean@169
   904
        /// and the inspector is not displayed.</param>
Dean@169
   905
        private void MailItem_Open(ref bool cancel)
Dean@159
   906
        {
Dean@173
   907
            if (this.associatedMailItem != null && this.associatedMailItem.MirrorDisplay())
Dean@169
   908
            {
Dean@169
   909
                cancel = true;
Dean@169
   910
            }
Dean@169
   911
Dean@169
   912
            return;
Dean@159
   913
        }
Dean@159
   914
Dean@169
   915
        /// <summary>
Dean@169
   916
        /// Event handler for when a mail item property is changed.
Dean@169
   917
        /// See: https://msdn.microsoft.com/en-us/library/office/ff866739.aspx
Dean@169
   918
        /// </summary>
Dean@169
   919
        /// <param name="propertyName">The name of the property that was changed.</param>
Dean@169
   920
        private void MailItem_PropertyChange(string propertyName)
Dean@159
   921
        {
Dean@179
   922
            switch (propertyName.ToUpper())
Dean@159
   923
            {
Dean@179
   924
                case "TO":
Dean@179
   925
                    // Start the refresh timer
Dean@179
   926
                    this.TimerRefresh.Enabled = true;
Dean@159
   927
                    break;
Dean@159
   928
                // Outlook bug: there are always both events, so one is enough
Dean@159
   929
                //case "CC":
Dean@179
   930
                //    // Start the refresh timer
Dean@179
   931
                //    this.TimerRefresh.Enabled = true;
Dean@159
   932
                //    break;
Dean@159
   933
            }
Dean@169
   934
Dean@169
   935
            return;
Dean@159
   936
        }
Dean@159
   937
Dean@179
   938
        /// <summary>
Dean@179
   939
        /// Event handler for when the encryption status button is clicked.
Dean@179
   940
        /// </summary>
Dean@178
   941
        private void ButtonEncryptionStatus_Click(object sender, EventArgs e)
vb@133
   942
        {
Dean@179
   943
            string reason;
Dean@266
   944
            EncryptionState state = this.CopyUIToState();
Dean@250
   945
            pEp_identity_s identityPartner;
Dean@250
   946
            List<pEp_identity_s> partnersToCheck;
markus@201
   947
Dean@259
   948
            switch (state.EncryptionStatus)
vb@133
   949
            {
vb@133
   950
                case _pEp_color.pEp_rating_yellow:
vb@133
   951
                    {
Dean@266
   952
                        try
vb@133
   953
                        {
Dean@266
   954
                            // Incoming
Dean@266
   955
                            if (this.associatedMailItem.IsIncoming)
Dean@266
   956
                            {
Dean@266
   957
                                identityPartner = new pEp_identity_s();
Dean@266
   958
                                identityPartner.address = this.associatedMailItem.FromAddress;
Dean@266
   959
                                identityPartner.username = this.associatedMailItem.FromUsername;
Dean@266
   960
                                identityPartner.user_id = CryptableMailItem.GetUserIDFromAddress(identityPartner.address, identityPartner.username);
vb@139
   961
vb@133
   962
                                try
vb@133
   963
                                {
Dean@266
   964
                                    identityPartner = ThisAddIn.pEp.update_identity(identityPartner);
Dean@266
   965
                                }
Dean@266
   966
                                catch
Dean@266
   967
                                {
Dean@266
   968
                                    state = new EncryptionState(_pEp_color.pEp_rating_undefined);
Dean@266
   969
                                    this.CopyStateToUI(state);
Dean@266
   970
                                    return;
Dean@266
   971
                                }
Dean@259
   972
Dean@266
   973
                                this.DoHandshake(identityPartner);
Dean@266
   974
                            }
Dean@266
   975
                            // Outgoing
Dean@266
   976
                            else
Dean@266
   977
                            {
Dean@266
   978
                                // Build list of handshake partners
Dean@266
   979
                                partnersToCheck = new List<pEp_identity_s>();
Dean@266
   980
                                foreach (pEp_identity_s identity in this.associatedMailItem.Addresses)
Dean@266
   981
                                {
Dean@266
   982
                                    try
vb@133
   983
                                    {
Dean@266
   984
                                        identityPartner = ThisAddIn.pEp.update_identity(identity);
Dean@266
   985
Dean@266
   986
                                        if (identityPartner.comm_type >= _pEp_comm_type.pEp_ct_unconfirmed_encryption &&
Dean@266
   987
                                            identityPartner.comm_type < _pEp_comm_type.pEp_ct_confirmed_encryption)
Dean@266
   988
                                        {
Dean@266
   989
                                            partnersToCheck.Add(identityPartner);
Dean@266
   990
                                        }
vb@133
   991
                                    }
Dean@266
   992
                                    catch { }
vb@133
   993
                                }
vb@133
   994
Dean@266
   995
                                if (partnersToCheck.Count == 0)
Dean@266
   996
                                {
Dean@266
   997
                                    state = new EncryptionState(_pEp_color.pEp_rating_undefined);
Dean@266
   998
                                    this.CopyStateToUI(state);
Dean@266
   999
                                    return;
Dean@266
  1000
                                }
Dean@266
  1001
                                else if (partnersToCheck.Count == 1)
Dean@266
  1002
                                {
Dean@266
  1003
                                    this.DoHandshake(partnersToCheck[0]);
Dean@266
  1004
                                }
Dean@266
  1005
                                else if (partnersToCheck.Count > 1)
Dean@266
  1006
                                {
Dean@266
  1007
                                    this.BuildAndShowManager();
Dean@266
  1008
                                }
vb@133
  1009
                            }
vb@133
  1010
                        }
Dean@266
  1011
                        catch (COMException) { }
Dean@266
  1012
                        catch (Exception) { }
Dean@266
  1013
                        break;
vb@133
  1014
                    }
Dean@259
  1015
                default:
Dean@266
  1016
                    {
Dean@266
  1017
                        reason = this.BuildEncryptionStatusReason(state.EncryptionStatus);
Dean@259
  1018
Dean@266
  1019
                        if ((reason != null) &&
Dean@266
  1020
                            (reason != ""))
Dean@266
  1021
                        {
Dean@266
  1022
                            MessageBox.Show(reason, "",
Dean@266
  1023
                                            MessageBoxButtons.OK,
Dean@266
  1024
                                            MessageBoxIcon.Information);
Dean@266
  1025
                        }
Dean@266
  1026
                        break;
vb@133
  1027
                    }
vb@133
  1028
            }
Dean@179
  1029
Dean@179
  1030
            return;
vb@133
  1031
        }
vb@133
  1032
Dean@179
  1033
        /// <summary>
Dean@179
  1034
        /// Event handler for when a mouse button is released over the encryption status button.
Dean@179
  1035
        /// </summary>
Dean@179
  1036
        private void ButtonEncryptionStatus_MouseUp(object sender, MouseEventArgs e)
vb@133
  1037
        {
Dean@179
  1038
            if ((sender != null) &&
Dean@179
  1039
                (e.Button == System.Windows.Forms.MouseButtons.Right))
markus@201
  1040
            {
Dean@259
  1041
                this.BuildAndShowManager();
vb@133
  1042
            }
Dean@179
  1043
Dean@179
  1044
            return;
vb@133
  1045
        }
vb@133
  1046
Dean@179
  1047
        /// <summary>
Dean@179
  1048
        /// Event handler for when the explanation link label is clicked.
Dean@179
  1049
        /// </summary>
Dean@179
  1050
        private void LinkLabelExplanation_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
Dean@179
  1051
        {
Dean@259
  1052
            this.BuildAndShowManager();
Dean@179
  1053
            return;
vb@133
  1054
        }
Dean@151
  1055
Dean@151
  1056
        /// <summary>
Dean@151
  1057
        /// Event handler for when the options picture box is clicked.
Dean@151
  1058
        /// This will open the options form for user editing.
Dean@151
  1059
        /// </summary>
Dean@151
  1060
        private void PictureBoxOptions_Click(object sender, EventArgs e)
Dean@151
  1061
        {
Dean@159
  1062
            DialogResult result;
Dean@203
  1063
            FormOptions frm;
Dean@203
  1064
            FormOptions.State stateIn;
Dean@203
  1065
            FormOptions.State stateOut;
Dean@203
  1066
Dean@203
  1067
            // Build form and state
Dean@203
  1068
            frm = new FormOptions();
Dean@154
  1069
            frm.StartPosition = FormStartPosition.CenterScreen;
Dean@203
  1070
            stateIn = Globals.ThisAddIn.GetOptionsState();
Dean@203
  1071
Dean@203
  1072
            result = frm.ShowDialog(this.ParentForm, stateIn, out stateOut); // Must show as dialog to block code
Dean@203
  1073
Dean@203
  1074
            if (result == DialogResult.OK)
Dean@203
  1075
            {
Dean@203
  1076
                Globals.ThisAddIn.SetOptionsState(stateOut);
Dean@203
  1077
            }
Dean@151
  1078
Dean@151
  1079
            return;
Dean@151
  1080
        }
Dean@151
  1081
Dean@151
  1082
        /// <summary>
Dean@151
  1083
        /// Event handler for when the mouse hovers over the options picture box.
Dean@151
  1084
        /// This is a work-around to show a tool tip.
Dean@151
  1085
        /// </summary>
Dean@151
  1086
        private void PictureBoxOptions_MouseHover(object sender, EventArgs e)
Dean@151
  1087
        {
Dean@151
  1088
            ToolTip toolTip = new ToolTip();
Dean@277
  1089
            toolTip.SetToolTip(this.PictureBoxOptions, pEp.Properties.Resources.ToolTipOptions);
Dean@151
  1090
            return;
Dean@151
  1091
        }
vb@133
  1092
    }
vb@133
  1093
}