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