OUT-139: Support changing whether pEp is enabled/disabled from the SendUsingAccount in drafts.
authorDean
Thu, 27 Oct 2016 12:36:01 +0200
changeset 1390223d68887143
parent 1389 1221bbd9fdb8
child 1391 a89f6f88f14e
OUT-139: Support changing whether pEp is enabled/disabled from the SendUsingAccount in drafts.
MailItemExtensions.cs
ThisAddIn.cs
UI/FormRegionPreviewUnencrypted.cs
UI/FormRegionPrivacyStatus.Designer.cs
UI/FormRegionPrivacyStatus.cs
UI/RibbonCustomizations.cs
     1.1 --- a/MailItemExtensions.cs	Thu Oct 27 10:51:09 2016 +0200
     1.2 +++ b/MailItemExtensions.cs	Thu Oct 27 12:36:01 2016 +0200
     1.3 @@ -177,29 +177,59 @@
     1.4          }
     1.5  
     1.6          /// <summary>
     1.7 -        /// Determines if the given mail item is in a pEp enabled store.
     1.8 +        /// Determines if the given mail item has pEp enabled for it.
     1.9 +        /// This will handle drafts (using sending account) as well as saved mail items (using store).
    1.10          /// </summary>
    1.11          /// <param name="omi">The outlook mail item to process with.</param>
    1.12 -        /// <returns>True if the mail item is in a pEp enabled store, otherwise false.</returns>
    1.13 -        public static bool GetIsInPEPEnabledStore(this Outlook.MailItem omi)
    1.14 +        /// <returns>True if the given mail item has pEp enabled, otherwise false.</returns>
    1.15 +        public static bool GetIsPEPEnabled(this Outlook.MailItem omi)
    1.16          {
    1.17              bool isEnabled = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
    1.18 +            bool success = false;
    1.19              Outlook.Folder folder = null;
    1.20              Outlook.Store store = null;
    1.21 +            Outlook.Account acct = null;
    1.22  
    1.23              try
    1.24              {
    1.25 -                folder = (Outlook.Folder)omi.Parent;
    1.26 -                store = folder.Store;
    1.27 -                isEnabled = Globals.ThisAddIn.GetIsPEPEnabled(store);
    1.28 +                // Try using the SendUsingAccount for drafts
    1.29 +                try
    1.30 +                {
    1.31 +                    if (omi.GetIsDraft())
    1.32 +                    {
    1.33 +                        acct = omi.SendUsingAccount;
    1.34 +                        isEnabled = Globals.ThisAddIn.GetIsPEPEnabled(acct);
    1.35 +                        success = true;
    1.36 +                    }
    1.37 +                }
    1.38 +                catch
    1.39 +                {
    1.40 +                    success = false;
    1.41 +                    Log.Warning("GetIsPEPEnabled: failed using SendUsingAccount.");
    1.42 +                }
    1.43 +
    1.44 +                // Try using the store
    1.45 +                if (success == false)
    1.46 +                {
    1.47 +                    folder = (Outlook.Folder)omi.Parent;
    1.48 +                    store = folder.Store;
    1.49 +                    isEnabled = Globals.ThisAddIn.GetIsPEPEnabled(store);
    1.50 +                    success = true;
    1.51 +                }
    1.52              }
    1.53              catch
    1.54              {
    1.55 -                Log.Error("GetIsInPEPEnabledStore: failure occured, returning default.");
    1.56 +                Log.Error("GetIsPEPEnabled: failure occured, returning default.");
    1.57              }
    1.58              finally
    1.59              {
    1.60                  // Release objects
    1.61 +                if (acct != null)
    1.62 +                {
    1.63 +                    Marshal.ReleaseComObject(acct);
    1.64 +                    acct = null;
    1.65 +                }
    1.66 +
    1.67                  if (folder != null)
    1.68                  {
    1.69                      Marshal.ReleaseComObject(folder);
     2.1 --- a/ThisAddIn.cs	Thu Oct 27 10:51:09 2016 +0200
     2.2 +++ b/ThisAddIn.cs	Thu Oct 27 12:36:01 2016 +0200
     2.3 @@ -1781,11 +1781,48 @@
     2.4          }
     2.5  
     2.6          /// <summary>
     2.7 -        /// Determines if the given outlook store has pEp enabled by comparing against the account settings.
     2.8 +        /// Determines if the given Outlook account has pEp enabled by comparing against the account settings.
     2.9 +        /// </summary>
    2.10 +        /// <param name="acct">The Outlook account to check pEp enabled status for.</param>
    2.11 +        /// <returns>True if the given Outlook account has pEp enabled, otherwise false.</returns>
    2.12 +        internal bool GetIsPEPEnabled(Outlook.Account acct)
    2.13 +        {
    2.14 +            bool defaultResult = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
    2.15 +            bool result = defaultResult;
    2.16 +            PEPSettings.PEPAccountSettings acctSettings;
    2.17 +
    2.18 +            try
    2.19 +            {
    2.20 +                if (acct != null)
    2.21 +                {
    2.22 +                    acctSettings = this._Settings.GetAccountSettings(acct.SmtpAddress,
    2.23 +                                                                     acct.AccountType.ToString());
    2.24 +                    if (acctSettings != null)
    2.25 +                    {
    2.26 +                        result = acctSettings.IsPEPEnabled;
    2.27 +                    }
    2.28 +                }
    2.29 +                else
    2.30 +                {
    2.31 +                    result = defaultResult;
    2.32 +                    Log.Warning("GetIsPEPEnabled: null account, returning default.");
    2.33 +                }
    2.34 +            }
    2.35 +            catch (Exception ex)
    2.36 +            {
    2.37 +                result = defaultResult;
    2.38 +                Log.Error("GetIsPEPEnabled: Failure occured, returning default. " + ex.ToString());
    2.39 +            }
    2.40 +
    2.41 +            return (result);
    2.42 +        }
    2.43 +
    2.44 +        /// <summary>
    2.45 +        /// Determines if the given Outlook store has pEp enabled by comparing against the account settings.
    2.46          /// The assumption is each account has it's own unique data store (which may not be true for POP3).
    2.47          /// </summary>
    2.48 -        /// <param name="store">The outlook store to check pEp enabled status for.</param>
    2.49 -        /// <returns>True if the given outlook store has pEp enabled, otherwise false.</returns>
    2.50 +        /// <param name="store">The Outlook store to check pEp enabled status for.</param>
    2.51 +        /// <returns>True if the given Outlook store has pEp enabled, otherwise false.</returns>
    2.52          internal bool GetIsPEPEnabled(Outlook.Store store)
    2.53          {
    2.54              bool defaultResult = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
    2.55 @@ -1794,7 +1831,6 @@
    2.56              Outlook.Account account = null;
    2.57              Outlook.Accounts accounts = null;
    2.58              Outlook.NameSpace ns = null;
    2.59 -            PEPSettings.PEPAccountSettings acctSettings;
    2.60  
    2.61              try
    2.62              {
    2.63 @@ -1822,18 +1858,8 @@
    2.64                          if ((deliveryStore != null) &&
    2.65                              (deliveryStore.StoreID == store.StoreID))
    2.66                          {
    2.67 -                            acctSettings = this._Settings.GetAccountSettings(account.SmtpAddress,
    2.68 -                                                                             account.AccountType.ToString());
    2.69 -                            if (acctSettings != null)
    2.70 -                            {
    2.71 -                                result = acctSettings.IsPEPEnabled;
    2.72 -                                break;
    2.73 -                            }
    2.74 -                            else
    2.75 -                            {
    2.76 -                                result = defaultResult;
    2.77 -                                break;
    2.78 -                            }
    2.79 +                            result = this.GetIsPEPEnabled(account);
    2.80 +                            break;
    2.81                          }
    2.82  
    2.83                          if (account != null)
    2.84 @@ -1852,13 +1878,13 @@
    2.85                  else
    2.86                  {
    2.87                      result = defaultResult;
    2.88 -                    Log.Warning("GetIsEncrypted: null store, returning default.");
    2.89 +                    Log.Warning("GetIsPEPEnabled: null store, returning default.");
    2.90                  }
    2.91              }
    2.92              catch (Exception ex)
    2.93              {
    2.94                  result = defaultResult;
    2.95 -                Log.Error("GetIsEncrypted: Failure occured, returning default. " + ex.ToString());
    2.96 +                Log.Error("GetIsPEPEnabled: Failure occured, returning default. " + ex.ToString());
    2.97              }
    2.98              finally
    2.99              {
   2.100 @@ -2592,7 +2618,7 @@
   2.101                          omi = ns.GetItemFromID(eid);
   2.102  
   2.103                          // Only process if pEp is enabled
   2.104 -                        if (omi.GetIsInPEPEnabledStore())
   2.105 +                        if (omi.GetIsPEPEnabled())
   2.106                          {
   2.107                              cmi = new CryptableMailItem(omi);
   2.108  
   2.109 @@ -2642,7 +2668,7 @@
   2.110                  omi = (Outlook.MailItem)item;
   2.111  
   2.112                  // Only process if pEp is enabled
   2.113 -                if (omi.GetIsInPEPEnabledStore())
   2.114 +                if (omi.GetIsPEPEnabled())
   2.115                  {
   2.116                      cmi = new CryptableMailItem(omi);
   2.117  
     3.1 --- a/UI/FormRegionPreviewUnencrypted.cs	Thu Oct 27 10:51:09 2016 +0200
     3.2 +++ b/UI/FormRegionPreviewUnencrypted.cs	Thu Oct 27 12:36:01 2016 +0200
     3.3 @@ -34,7 +34,7 @@
     3.4  
     3.5                  // Do not load if the mail item itself is not stored encrypted or pEp is disabled
     3.6                  e.Cancel = ((omi.GetIsSecurelyStored() == false) ||
     3.7 -                            (omi.GetIsInPEPEnabledStore() == false));
     3.8 +                            (omi.GetIsPEPEnabled() == false));
     3.9  
    3.10                  return;
    3.11              }
     4.1 --- a/UI/FormRegionPrivacyStatus.Designer.cs	Thu Oct 27 10:51:09 2016 +0200
     4.2 +++ b/UI/FormRegionPrivacyStatus.Designer.cs	Thu Oct 27 12:36:01 2016 +0200
     4.3 @@ -24,9 +24,10 @@
     4.4                  components.Dispose();
     4.5              }
     4.6  
     4.7 -            if (disposing && (this.associatedMailItem != null))
     4.8 +            if (disposing && (this.cryptableMailItem != null))
     4.9              {
    4.10 -                this.associatedMailItem.Dispose();
    4.11 +                this.cryptableMailItem.Dispose();
    4.12 +                this.cryptableMailItem = null;
    4.13              }
    4.14  
    4.15              base.Dispose(disposing);
     5.1 --- a/UI/FormRegionPrivacyStatus.cs	Thu Oct 27 10:51:09 2016 +0200
     5.2 +++ b/UI/FormRegionPrivacyStatus.cs	Thu Oct 27 12:36:01 2016 +0200
     5.3 @@ -41,9 +41,6 @@
     5.4                      return;
     5.5                  }
     5.6  
     5.7 -                // Do not load if pEp is disabled
     5.8 -                e.Cancel = (omi.GetIsInPEPEnabledStore() == false);
     5.9 -
    5.10                  //WindowFormRegionCollection formRegions;
    5.11  
    5.12                  /* There is a Microsoft bug at least in Outlook 2013 and Windows 8.1
    5.13 @@ -91,7 +88,6 @@
    5.14           * Specific cases are noted where possible.
    5.15           * 
    5.16           * The separate privacy status manager form state is also managed here.
    5.17 -         * 
    5.18           */
    5.19  
    5.20          /// <summary>
    5.21 @@ -99,13 +95,14 @@
    5.22          /// </summary>
    5.23          public event EventHandler Expanded;
    5.24  
    5.25 -        private CryptableMailItem       associatedMailItem     = null;
    5.26 -        private bool                    initialized            = false;
    5.27 +        private CryptableMailItem       cryptableMailItem      = null;
    5.28 +        private bool                    displayMirrorRequested = false;
    5.29 +        private bool                    isEnabled              = true;
    5.30          private bool?                   isExpandedPrevious     = null;
    5.31 +        private bool                    isManagerFormEnabled   = true;
    5.32 +        private bool                    isStarted              = false;
    5.33          private FormManagePrivacyStatus managerForm            = null;
    5.34 -        private bool                    managerFormEnabled     = true;
    5.35          private bool                    refreshOngoing         = false;
    5.36 -        private bool                    displayMirrorRequested = false;
    5.37  
    5.38          /**************************************************************
    5.39           * 
    5.40 @@ -170,70 +167,6 @@
    5.41          }
    5.42  
    5.43          /// <summary>
    5.44 -        /// Sets the cryptable mail item associated with this encryption status panel.
    5.45 -        /// The associated mail item can then be accessed through its local variable.
    5.46 -        /// </summary>
    5.47 -        private void SetAssociatedMailItem()
    5.48 -        {
    5.49 -            bool errorOccurred = false;
    5.50 -            Outlook.MailItem omi = null;
    5.51 -
    5.52 -            // Null check
    5.53 -            if (!errorOccurred)
    5.54 -            {
    5.55 -                try
    5.56 -                {
    5.57 -                    if (this.OutlookItem == null)
    5.58 -                    {
    5.59 -                        errorOccurred = true;
    5.60 -                    }
    5.61 -                }
    5.62 -                catch
    5.63 -                {
    5.64 -                    errorOccurred = true;
    5.65 -                }
    5.66 -            }
    5.67 -
    5.68 -            // Attempt to get and cast the outlook mail item
    5.69 -            if (!errorOccurred)
    5.70 -            {
    5.71 -                try
    5.72 -                {
    5.73 -                    omi = (Outlook.MailItem)this.OutlookItem;
    5.74 -                }
    5.75 -                catch
    5.76 -                {
    5.77 -                    errorOccurred = true;
    5.78 -                }
    5.79 -            }
    5.80 -
    5.81 -            // Finally set the associated mail item
    5.82 -            if ((errorOccurred) ||
    5.83 -                (omi == null))
    5.84 -            {
    5.85 -                this.associatedMailItem = null;
    5.86 -            }
    5.87 -            else
    5.88 -            {
    5.89 -                // Check if the associated mail item has already been set
    5.90 -                if (this.associatedMailItem != null)
    5.91 -                {
    5.92 -                    // Only re-set the mail item if the EntryID has changed
    5.93 -                    if (this.associatedMailItem.EntryID != omi.EntryID)
    5.94 -                    {
    5.95 -                        this.associatedMailItem = new CryptableMailItem(omi);
    5.96 -                    }
    5.97 -                }
    5.98 -                else
    5.99 -                {
   5.100 -                    this.associatedMailItem = new CryptableMailItem(omi);
   5.101 -                }
   5.102 -            }
   5.103 -
   5.104 -            return;
   5.105 -        }
   5.106 -
   5.107 -        /// <summary>
   5.108          /// Completes the handshake process when the identity of a partner was previously marked as mistrusted.
   5.109          /// </summary>
   5.110          /// <param name="myself">The personal identity to complete the handshake with.</param>
   5.111 @@ -389,7 +322,7 @@
   5.112              SelectionItem item;
   5.113              FormControlManagePrivacyStatus.State managerState = new FormControlManagePrivacyStatus.State();
   5.114  
   5.115 -            if (this.associatedMailItem != null)
   5.116 +            if (this.cryptableMailItem != null)
   5.117              {
   5.118                  // Load all images from resources
   5.119                  imageForceUnencOn = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageForceUnencOn.png", UriKind.RelativeOrAbsolute));
   5.120 @@ -398,28 +331,19 @@
   5.121                  imageRed = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusRed.png", UriKind.RelativeOrAbsolute));
   5.122                  imageYellow = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusYellow.png", UriKind.RelativeOrAbsolute));
   5.123  
   5.124 -                /* Resolve all recipients -- this ensures the identities list is correctly populated
   5.125 -                 *
   5.126 -                 * Note: The PropertyChanged changed event must be disconnected before trying to resolve.
   5.127 -                 * This is because the resolve process can modify the contents of the mail item which triggers an event.
   5.128 -                 * The PropertyChanged event would then trigger a UI refresh cycle. However, because the GetManagerState itself 
   5.129 -                 * is called within the UI refresh, an infinite loop could occur trying to resolve a recipient that 
   5.130 -                 * cannot be resolved (no address).
   5.131 -                 */
   5.132 -                this.associatedMailItem.PropertyChanged -= MailItem_PropertyChanged;
   5.133 -                this.associatedMailItem.ResolveAllRecipients();
   5.134 -                this.associatedMailItem.PropertyChanged += MailItem_PropertyChanged;
   5.135 +                // Resolve all recipients -- this ensures the identities list is correctly populated
   5.136 +                this.ResolveAllRecipients();
   5.137  
   5.138                  managerState.Rating = this.FormControlPrivacyStatusChild.DisplayState.Rating;
   5.139 -                managerState.IsIncoming = this.associatedMailItem.IsIncoming;
   5.140 +                managerState.IsIncoming = this.cryptableMailItem.IsIncoming;
   5.141  
   5.142                  // Get identities
   5.143 -                identities = this.associatedMailItem.Recipients;
   5.144 -                myIdentity = this.associatedMailItem.Myself;
   5.145 +                identities = this.cryptableMailItem.Recipients;
   5.146 +                myIdentity = this.cryptableMailItem.Myself;
   5.147  
   5.148                  // Include the from identity for incoming messages at the beginning
   5.149 -                identity = this.associatedMailItem.From;
   5.150 -                if ((this.associatedMailItem.IsIncoming) &&
   5.151 +                identity = this.cryptableMailItem.From;
   5.152 +                if ((this.cryptableMailItem.IsIncoming) &&
   5.153                      (identity != null))
   5.154                  {
   5.155                      identities.Insert(0, identity);
   5.156 @@ -663,7 +587,10 @@
   5.157          /// </summary>
   5.158          public void RequestRatingAndUIUpdate()
   5.159          {
   5.160 -            this.TimerRefresh.Enabled = true;
   5.161 +            if (this.isEnabled)
   5.162 +            {
   5.163 +                this.TimerRefresh.Enabled = true;
   5.164 +            }
   5.165              return;
   5.166          }
   5.167  
   5.168 @@ -675,12 +602,13 @@
   5.169          /// </summary>
   5.170          private void ImmediateRatingAndUIUpdate()
   5.171          {
   5.172 -            if (this.associatedMailItem != null)
   5.173 +            if ((this.isEnabled) &&
   5.174 +                (this.cryptableMailItem != null))
   5.175              {
   5.176                  Log.Verbose("ImmediateRatingAndUIUpdate: Starting processing.");
   5.177  
   5.178                  // Start the rating calculation/decryption process
   5.179 -                this.associatedMailItem.StartProcessing();
   5.180 +                this.cryptableMailItem.StartProcessing();
   5.181              }
   5.182  
   5.183              return;
   5.184 @@ -729,6 +657,167 @@
   5.185              return;
   5.186          }
   5.187  
   5.188 +        /// <summary>
   5.189 +        /// Sets whether processing of the mail item is enabled.
   5.190 +        /// This should commonly be set from the .GetIsPEPEnabled() value.
   5.191 +        /// </summary>
   5.192 +        private void SetIsEnabled(bool enabled)
   5.193 +        {
   5.194 +            bool setByCache = false;
   5.195 +            PEPIdentity currIdent;
   5.196 +            Globals.ReturnStatus sts;
   5.197 +            Outlook.MailItem omi = null;
   5.198 +            Outlook.Recipient currUser = null;
   5.199 +            Outlook.Account currAccount = null;
   5.200 +            Outlook.Account sendingAccount = null;
   5.201 +            Outlook.NameSpace ns = null;
   5.202 +
   5.203 +            this.OutlookFormRegion.Visible = enabled;
   5.204 +            this.isEnabled = enabled;
   5.205 +
   5.206 +            if (enabled)
   5.207 +            {
   5.208 +                // Do not allow initialization more than once
   5.209 +                if (this.isStarted == false)
   5.210 +                {
   5.211 +                    /* It's possible for new draft MailItems to be created outside the context of an account.
   5.212 +                     * In this situation the SendUsingAccount will always be null which of course breaks several pEp operations.
   5.213 +                     * The operations themselves cannot make the assumption about what account information to use.
   5.214 +                     * Therefore, the situation is detected here and for draft mail items a null SendUsingAccount will be 
   5.215 +                     * set with the session's default account.
   5.216 +                     */
   5.217 +                    try
   5.218 +                    {
   5.219 +                        ns = Globals.ThisAddIn.Application.Session;
   5.220 +
   5.221 +                        if ((this.OutlookItem is Outlook.MailItem) &&
   5.222 +                            ((Outlook.MailItem)this.OutlookItem).GetIsDraft())
   5.223 +                        {
   5.224 +                            omi = this.OutlookItem as Outlook.MailItem;
   5.225 +                            sendingAccount = omi.SendUsingAccount;
   5.226 +                            currUser = ns.CurrentUser;
   5.227 +
   5.228 +                            if (sendingAccount == null)
   5.229 +                            {
   5.230 +                                sts = PEPIdentity.Create(currUser, out currIdent);
   5.231 +
   5.232 +                                if (sts == Globals.ReturnStatus.Success)
   5.233 +                                {
   5.234 +                                    currAccount = PEPIdentity.GetOwnAccount(currIdent.Address);
   5.235 +                                    omi.SendUsingAccount = currAccount;
   5.236 +                                }
   5.237 +                            }
   5.238 +                        }
   5.239 +                    }
   5.240 +                    catch { }
   5.241 +                    finally
   5.242 +                    {
   5.243 +                        if (omi != null)
   5.244 +                        {
   5.245 +                            Marshal.ReleaseComObject(omi);
   5.246 +                            omi = null;
   5.247 +                        }
   5.248 +
   5.249 +                        if (currUser != null)
   5.250 +                        {
   5.251 +                            Marshal.ReleaseComObject(currUser);
   5.252 +                            currUser = null;
   5.253 +                        }
   5.254 +
   5.255 +                        if (currAccount != null)
   5.256 +                        {
   5.257 +                            Marshal.ReleaseComObject(currAccount);
   5.258 +                            currAccount = null;
   5.259 +                        }
   5.260 +
   5.261 +                        if (sendingAccount != null)
   5.262 +                        {
   5.263 +                            Marshal.ReleaseComObject(sendingAccount);
   5.264 +                            sendingAccount = null;
   5.265 +                        }
   5.266 +
   5.267 +                        if (ns != null)
   5.268 +                        {
   5.269 +                            Marshal.ReleaseComObject(ns);
   5.270 +                            ns = null;
   5.271 +                        }
   5.272 +                    }
   5.273 +
   5.274 +                    // Set reader upgrade link visibility
   5.275 +                    if ((Globals.RELEASE_MODE == Globals.ReleaseMode.Reader) &&
   5.276 +                        (this.cryptableMailItem != null) &&
   5.277 +                        (this.cryptableMailItem.IsDraft))
   5.278 +                    {
   5.279 +                        this.FormControlPrivacyStatusChild.DisplayState.UpgradeLinkIsVisible = true;
   5.280 +                    }
   5.281 +                    else
   5.282 +                    {
   5.283 +                        this.FormControlPrivacyStatusChild.DisplayState.UpgradeLinkIsVisible = false;
   5.284 +                    }
   5.285 +
   5.286 +                    /* For a MailItem being forwarded or replied to it's import to check against the encrypted conversation cache.
   5.287 +                     * This is normally done within CryptableMailItem_EncryptedConversationCacheUpdated; however,
   5.288 +                     * for trusted servers that use an in-line reponse, the EncryptedConversationCacheUpdated event occurs
   5.289 +                     * BEFORE the new mail item is created. This means it never sees the event.
   5.290 +                     * To get around this issue, when the form region is first shown, also check if the mail item
   5.291 +                     * exists in the encrypted conversation cache and should be marked as formerly encrypted.
   5.292 +                     * If this check passes, never event connect the CryptableMailItem_EncryptedConversationCacheUpdated event.
   5.293 +                     */
   5.294 +                    if (this.cryptableMailItem != null)
   5.295 +                    {
   5.296 +                        setByCache = this.cryptableMailItem.SetIsOriginallyEncryptedByCache();
   5.297 +                    }
   5.298 +
   5.299 +                    // Connect events
   5.300 +                    if (setByCache == false) { CryptableMailItem.EncryptedConversationCacheUpdated += CryptableMailItem_EncryptedConversationCacheUpdated; }
   5.301 +                    this.FormControlPrivacyStatusChild.PrivacyViewClick += FormControlPrivacyStatusChild_PrivacyViewClick;
   5.302 +                    this.Expanded += FormRegionPrivacyStatus_Expanded;
   5.303 +
   5.304 +                    this.TimerRefresh.Tick += TimerRefresh_Tick;
   5.305 +                    this.isStarted = true;
   5.306 +                }
   5.307 +            }
   5.308 +            else
   5.309 +            {
   5.310 +                // Disconnect events
   5.311 +                CryptableMailItem.EncryptedConversationCacheUpdated -= CryptableMailItem_EncryptedConversationCacheUpdated;
   5.312 +                this.FormControlPrivacyStatusChild.PrivacyViewClick -= FormControlPrivacyStatusChild_PrivacyViewClick;
   5.313 +                this.Expanded -= FormRegionPrivacyStatus_Expanded;
   5.314 +
   5.315 +                // Stop and disconnect the refresh timer
   5.316 +                this.TimerRefresh.Stop();
   5.317 +                this.TimerRefresh.Enabled = false;
   5.318 +                this.TimerRefresh.Tick -= TimerRefresh_Tick;
   5.319 +
   5.320 +                this.isStarted = false;
   5.321 +            }
   5.322 +
   5.323 +            return;
   5.324 +        }
   5.325 +
   5.326 +        /// <summary>
   5.327 +        /// Resolves all recipients of the Outlook mail item.
   5.328 +        /// </summary>
   5.329 +        private void ResolveAllRecipients()
   5.330 +        {
   5.331 +            if ((this.isEnabled) &&
   5.332 +                (this.cryptableMailItem != null))
   5.333 +            {
   5.334 +                /*
   5.335 +                 * Note: The PropertyChanged changed event must be disconnected before trying to resolve.
   5.336 +                 * This is because the resolve process can modify the contents of the mail item which triggers an event.
   5.337 +                 * The PropertyChanged event would then trigger a UI refresh cycle. However, because the GetManagerState itself 
   5.338 +                 * is called within the UI refresh, an infinite loop could occur trying to resolve a recipient that
   5.339 +                 * cannot be resolved(no address).
   5.340 +                 */
   5.341 +                this.cryptableMailItem.PropertyChanged -= MailItem_PropertyChanged;
   5.342 +                this.cryptableMailItem.ResolveAllRecipients();
   5.343 +                this.cryptableMailItem.PropertyChanged += MailItem_PropertyChanged;
   5.344 +            }
   5.345 +
   5.346 +            return;
   5.347 +        }
   5.348 +
   5.349          /**************************************************************
   5.350           * 
   5.351           * Event Handling
   5.352 @@ -742,132 +831,41 @@
   5.353          /// </summary>
   5.354          private void FormRegionPrivacyStatus_FormRegionShowing(object sender, System.EventArgs e)
   5.355          {
   5.356 -            bool setByCache = false;
   5.357 -            PEPIdentity currIdent;
   5.358 -            Globals.ReturnStatus sts;
   5.359 -            Outlook.MailItem omi = null;
   5.360 -            Outlook.Recipient currUser = null;
   5.361 -            Outlook.Account currAccount = null;
   5.362 -            Outlook.Account sendingAccount = null;
   5.363 -            Outlook.NameSpace ns = Globals.ThisAddIn.Application.Session;
   5.364 +            // Set mail item
   5.365 +            if (this.OutlookItem is Outlook.MailItem)
   5.366 +            {
   5.367 +                this.cryptableMailItem = new CryptableMailItem((Outlook.MailItem)this.OutlookItem);
   5.368 +            }
   5.369 +            else
   5.370 +            {
   5.371 +                this.cryptableMailItem = null;
   5.372 +            }
   5.373  
   5.374 -            // Do not allow initialization more than once
   5.375 -            if (initialized == false)
   5.376 +            // Connect cryptable mail item events
   5.377 +            if (this.cryptableMailItem != null)
   5.378              {
   5.379 -                this.SetAssociatedMailItem();
   5.380 -
   5.381 -                /* It's possible for new draft MailItems to be created outside the context of an account.
   5.382 -                 * In this situation the SendUsingAccount will always be null which of course breaks several pEp operations.
   5.383 -                 * The operations themselves cannot make the assumption about what account information to use.
   5.384 -                 * Therefore, the situation is detected here and for draft mail items a null SendUsingAccount will be 
   5.385 -                 * set with the session's default account.
   5.386 -                 */
   5.387                  try
   5.388                  {
   5.389 -                    if ((this.OutlookItem is Outlook.MailItem) &&
   5.390 -                        ((Outlook.MailItem)this.OutlookItem).GetIsDraft())
   5.391 +                    this.cryptableMailItem.PropertyChanged += MailItem_PropertyChanged;
   5.392 +                    this.cryptableMailItem.ProcessingCompleted += MailItem_ProcessingCompleted;
   5.393 +                    this.cryptableMailItem.GetMirrorCompleted += MailItem_GetMirrorCompleted;
   5.394 +                    this.cryptableMailItem.Send += MailItem_Send;
   5.395 +
   5.396 +                    if (this.cryptableMailItem.IsSecurelyStored)
   5.397                      {
   5.398 -                        omi = this.OutlookItem as Outlook.MailItem;
   5.399 -                        sendingAccount = omi.SendUsingAccount;
   5.400 -                        currUser = ns.CurrentUser;
   5.401 -
   5.402 -                        if (sendingAccount == null)
   5.403 -                        {
   5.404 -                            sts = PEPIdentity.Create(currUser, out currIdent);
   5.405 -
   5.406 -                            if (sts == Globals.ReturnStatus.Success)
   5.407 -                            {
   5.408 -                                currAccount = PEPIdentity.GetOwnAccount(currIdent.Address);
   5.409 -                                omi.SendUsingAccount = currAccount;
   5.410 -                            }
   5.411 -                        }
   5.412 +                        this.cryptableMailItem.Open += MailItem_Open;
   5.413                      }
   5.414                  }
   5.415                  catch { }
   5.416 -                finally
   5.417 -                {
   5.418 -                    if (omi != null)
   5.419 -                    {
   5.420 -                        Marshal.ReleaseComObject(omi);
   5.421 -                        omi = null;
   5.422 -                    }
   5.423 -
   5.424 -                    if (currUser != null)
   5.425 -                    {
   5.426 -                        Marshal.ReleaseComObject(currUser);
   5.427 -                        currUser = null;
   5.428 -                    }
   5.429 -
   5.430 -                    if (currAccount != null)
   5.431 -                    {
   5.432 -                        Marshal.ReleaseComObject(currAccount);
   5.433 -                        currAccount = null;
   5.434 -                    }
   5.435 -
   5.436 -                    if (sendingAccount != null)
   5.437 -                    {
   5.438 -                        Marshal.ReleaseComObject(sendingAccount);
   5.439 -                        sendingAccount = null;
   5.440 -                    }
   5.441 -
   5.442 -                    if (ns != null)
   5.443 -                    {
   5.444 -                        Marshal.ReleaseComObject(ns);
   5.445 -                        ns = null;
   5.446 -                    }
   5.447 -                }
   5.448 -
   5.449 -                // Set reader upgrade link visibility
   5.450 -                if ((Globals.RELEASE_MODE == Globals.ReleaseMode.Reader) &&
   5.451 -                    (this.associatedMailItem != null) &&
   5.452 -                    (this.associatedMailItem.IsDraft))
   5.453 -                {
   5.454 -                    this.FormControlPrivacyStatusChild.DisplayState.UpgradeLinkIsVisible = true;
   5.455 -                }
   5.456 -                else
   5.457 -                {
   5.458 -                    this.FormControlPrivacyStatusChild.DisplayState.UpgradeLinkIsVisible = false;
   5.459 -                }
   5.460 -
   5.461 -                if (this.associatedMailItem != null)
   5.462 -                {
   5.463 -                    // Connect cryptable mail item events
   5.464 -                    try
   5.465 -                    {
   5.466 -                        this.associatedMailItem.PropertyChanged += MailItem_PropertyChanged;
   5.467 -                        this.associatedMailItem.ProcessingCompleted += MailItem_ProcessingCompleted;
   5.468 -                        this.associatedMailItem.GetMirrorCompleted += MailItem_GetMirrorCompleted;
   5.469 -                        this.associatedMailItem.Send += MailItem_Send;
   5.470 -
   5.471 -                        if (this.associatedMailItem.IsSecurelyStored)
   5.472 -                        {
   5.473 -                            this.associatedMailItem.Open += MailItem_Open;
   5.474 -                        }
   5.475 -                    }
   5.476 -                    catch { }
   5.477 -
   5.478 -                    /* For a MailItem being forwarded or replied to it's import to check against the encrypted conversation cache.
   5.479 -                     * This is normally done within CryptableMailItem_EncryptedConversationCacheUpdated; however,
   5.480 -                     * for trusted servers that use an in-line reponse, the EncryptedConversationCacheUpdated event occurs
   5.481 -                     * BEFORE the new mail item is created. This means it never sees the event.
   5.482 -                     * To get around this issue, when the form region is first shown, also check if the mail item
   5.483 -                     * exists in the encrypted conversation cache and should be marked as formerly encrypted.
   5.484 -                     * If this check passes, never event connect the CryptableMailItem_EncryptedConversationCacheUpdated event.
   5.485 -                     */
   5.486 -                    setByCache = this.associatedMailItem.SetIsOriginallyEncryptedByCache();
   5.487 -                }
   5.488 -
   5.489 -                // Connect events
   5.490 -                if (setByCache == false) { CryptableMailItem.EncryptedConversationCacheUpdated += CryptableMailItem_EncryptedConversationCacheUpdated; }
   5.491 -                this.FormControlPrivacyStatusChild.PrivacyViewClick += FormControlPrivacyStatusChild_PrivacyViewClick;
   5.492 -                this.Expanded += FormRegionPrivacyStatus_Expanded;
   5.493 -
   5.494 -                this.TimerRefresh.Tick += TimerRefresh_Tick;
   5.495 -                this.initialized = true;
   5.496              }
   5.497  
   5.498 -            // Call the timer tick method manually to refresh data with no delay
   5.499 -            this.TimerRefresh_Tick(null, new EventArgs());
   5.500 +            // Update pEp enabled status
   5.501 +            this.SetIsEnabled(((Outlook.MailItem)this.OutlookItem).GetIsPEPEnabled());
   5.502 +            if (this.isEnabled)
   5.503 +            {
   5.504 +                // Call the timer tick method manually to refresh data with no delay
   5.505 +                this.TimerRefresh_Tick(null, new EventArgs());
   5.506 +            }
   5.507  
   5.508              return;
   5.509          }
   5.510 @@ -877,29 +875,25 @@
   5.511          /// </summary>
   5.512          private void FormRegionPrivacyStatus_FormRegionClosed(object sender, System.EventArgs e)
   5.513          {
   5.514 -            // Disconnect cryptable mail item events
   5.515 -            if (this.associatedMailItem != null)
   5.516 +            // Disconnect cryptable mail item
   5.517 +            if (this.cryptableMailItem != null)
   5.518              {
   5.519                  try
   5.520                  {
   5.521 -                    this.associatedMailItem.PropertyChanged -= MailItem_PropertyChanged;
   5.522 -                    this.associatedMailItem.ProcessingCompleted -= MailItem_ProcessingCompleted;
   5.523 -                    this.associatedMailItem.GetMirrorCompleted -= MailItem_GetMirrorCompleted;
   5.524 -                    this.associatedMailItem.Open -= MailItem_Open;
   5.525 -                    this.associatedMailItem.Send -= MailItem_Send;
   5.526 +                    this.cryptableMailItem.PropertyChanged -= MailItem_PropertyChanged;
   5.527 +                    this.cryptableMailItem.ProcessingCompleted -= MailItem_ProcessingCompleted;
   5.528 +                    this.cryptableMailItem.GetMirrorCompleted -= MailItem_GetMirrorCompleted;
   5.529 +                    this.cryptableMailItem.Open -= MailItem_Open;
   5.530 +                    this.cryptableMailItem.Send -= MailItem_Send;
   5.531                  }
   5.532                  catch { }
   5.533 +
   5.534 +                this.cryptableMailItem.Dispose();
   5.535 +                this.cryptableMailItem = null;
   5.536              }
   5.537  
   5.538 -            // Disconnect events
   5.539 -            CryptableMailItem.EncryptedConversationCacheUpdated -= CryptableMailItem_EncryptedConversationCacheUpdated;
   5.540 -            this.FormControlPrivacyStatusChild.PrivacyViewClick -= FormControlPrivacyStatusChild_PrivacyViewClick;
   5.541 -            this.Expanded -= FormRegionPrivacyStatus_Expanded;
   5.542 -
   5.543 -            // Stop and disconnect the refresh timer
   5.544 -            this.TimerRefresh.Stop();
   5.545 -            this.TimerRefresh.Enabled = false;
   5.546 -            this.TimerRefresh.Tick -= TimerRefresh_Tick;
   5.547 +            // Disconnect other
   5.548 +            this.SetIsEnabled(false);
   5.549  
   5.550              return;
   5.551          }
   5.552 @@ -917,14 +911,7 @@
   5.553               * Since the click event occurs BEFORE the expanded event, this will disable opening the manage privacy status
   5.554               * form in this situation.
   5.555               */
   5.556 -            if (this.OutlookFormRegion.IsExpanded)
   5.557 -            {
   5.558 -                this.managerFormEnabled = true;
   5.559 -            }
   5.560 -            else
   5.561 -            {
   5.562 -                this.managerFormEnabled = false;
   5.563 -            }
   5.564 +            this.isManagerFormEnabled = this.OutlookFormRegion.IsExpanded;
   5.565  
   5.566              return;
   5.567          }
   5.568 @@ -988,16 +975,17 @@
   5.569               */
   5.570  
   5.571              // Ensure the tick method is not called more than once
   5.572 -            if (refreshOngoing == false)
   5.573 +            if ((this.isEnabled) &&
   5.574 +                (refreshOngoing == false))
   5.575              {
   5.576                  this.refreshOngoing = true;
   5.577  
   5.578 -                if (this.associatedMailItem != null)
   5.579 +                if (this.cryptableMailItem != null)
   5.580                  {
   5.581                      // Attempt to get the download state
   5.582                      try
   5.583                      {
   5.584 -                        dlState = this.associatedMailItem.DownloadState;
   5.585 +                        dlState = this.cryptableMailItem.DownloadState;
   5.586                      }
   5.587                      catch (Exception ex)
   5.588                      {
   5.589 @@ -1022,7 +1010,7 @@
   5.590                          // Try to mark the message for full download
   5.591                          try
   5.592                          {
   5.593 -                            this.associatedMailItem.MarkForDownload = Outlook.OlRemoteStatus.olMarkedForDownload;
   5.594 +                            this.cryptableMailItem.MarkForDownload = Outlook.OlRemoteStatus.olMarkedForDownload;
   5.595                              tryAgain = true;
   5.596                          }
   5.597                          catch (Exception ex)
   5.598 @@ -1058,34 +1046,37 @@
   5.599                  // Marshal code back to UI thread as necessary
   5.600                  this.Invoke(new Action(() =>
   5.601                      {
   5.602 -                        this.FormControlPrivacyStatusChild.DisplayState.Rating = e.Rating;
   5.603 -                        RibbonCustomizations.RefreshRibbon();
   5.604 -                        this.UpdateManagePrivacyStatusForm(true); // Only update the rating
   5.605 +                        if (this.isEnabled)
   5.606 +                        {
   5.607 +                            this.FormControlPrivacyStatusChild.DisplayState.Rating = e.Rating;
   5.608 +                            RibbonCustomizations.Invalidate();
   5.609 +                            this.UpdateManagePrivacyStatusForm(true); // Only update the rating
   5.610  
   5.611 -                        /* Create the unencrypted preview if the mail item is encrypted and
   5.612 -                         * it is in an encrypted (untrusted) store
   5.613 -                         * 
   5.614 -                         * This is done here because FormRegionPrivacyStatus has the cryptable mail item and
   5.615 -                         * it also is initialized after FormRegionPreviewUnencrypted.
   5.616 -                         */
   5.617 -                        try
   5.618 -                        {
   5.619 -                            if (this.associatedMailItem.IsSecurelyStored)
   5.620 +                            /* Create the unencrypted preview if the mail item is encrypted and
   5.621 +                             * it is in an encrypted (untrusted) store
   5.622 +                             * 
   5.623 +                             * This is done here because FormRegionPrivacyStatus has the cryptable mail item and
   5.624 +                             * it also is initialized after FormRegionPreviewUnencrypted.
   5.625 +                             */
   5.626 +                            try
   5.627                              {
   5.628 -                                Log.Verbose("MailItem_ProcessingComplete: Starting mirror location.");
   5.629 -                                this.associatedMailItem.StartGetMirror();
   5.630 +                                if (this.cryptableMailItem.IsSecurelyStored)
   5.631 +                                {
   5.632 +                                    Log.Verbose("MailItem_ProcessingComplete: Starting mirror location.");
   5.633 +                                    this.cryptableMailItem.StartGetMirror();
   5.634 +                                }
   5.635 +                                else
   5.636 +                                {
   5.637 +                                    this.ClearPreview();
   5.638 +                                }
   5.639                              }
   5.640 -                            else
   5.641 +                            catch (Exception ex)
   5.642                              {
   5.643 -                                this.ClearPreview();
   5.644 +                                // Error is possible in some situations where the mail item was deleted or moved while decryption was ongoing.
   5.645 +                                // While rare, just log the issue and stop the process
   5.646 +                                Log.Warning("MailItem_ProcessingComplete: Failed to start mirror location, " + ex.ToString());
   5.647                              }
   5.648                          }
   5.649 -                        catch (Exception ex)
   5.650 -                        {
   5.651 -                            // Error is possible in some situations where the mail item was deleted or moved while decryption was ongoing.
   5.652 -                            // While rare, just log the issue and stop the process
   5.653 -                            Log.Warning("MailItem_ProcessingComplete: Failed to start mirror location, " + ex.ToString());
   5.654 -                        }
   5.655                      }));
   5.656              }
   5.657              catch (Exception ex)
   5.658 @@ -1107,37 +1098,40 @@
   5.659                  // Marshal code back to UI thread as necessary
   5.660                  this.Invoke(new Action(() =>
   5.661                      {
   5.662 -                        WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveWindow()];
   5.663 +                        if (this.isEnabled)
   5.664 +                        {
   5.665 +                            WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveWindow()];
   5.666  
   5.667 -                        if ((e.Mirror == null) &&
   5.668 -                            (this.associatedMailItem.LastProcessedStatus == Globals.ReturnStatus.Failure))
   5.669 -                        {
   5.670 -                            this.ClearPreview(Properties.Resources.Message_OpenError);
   5.671 -                            Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, failure during decryption.");
   5.672 -                        }
   5.673 -                        else if ((e.Mirror == null) &&
   5.674 -                                 (this.associatedMailItem.LastProcessedStatus == Globals.ReturnStatus.FailureNoConnection))
   5.675 -                        {
   5.676 -                            this.ClearPreview(Properties.Resources.Message_DecryptionNoConnection);
   5.677 -                            Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, connection failure during decryption.");
   5.678 -                        }
   5.679 -                        else
   5.680 -                        {
   5.681 -                            if ((formRegions != null) &&
   5.682 -                                (formRegions.FormRegionPreviewUnencrypted != null) &&
   5.683 -                                (formRegions.FormRegionPreviewUnencrypted.Visible))
   5.684 +                            if ((e.Mirror == null) &&
   5.685 +                                (this.cryptableMailItem.LastProcessedStatus == Globals.ReturnStatus.Failure))
   5.686                              {
   5.687 -                                formRegions.FormRegionPreviewUnencrypted.SetMessage(e.Mirror);
   5.688 -                                Log.Verbose("MailItem_GetMirrorComplete: Mirror found and displayed.");
   5.689 +                                this.ClearPreview(Properties.Resources.Message_OpenError);
   5.690 +                                Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, failure during decryption.");
   5.691                              }
   5.692 -                        }
   5.693 +                            else if ((e.Mirror == null) &&
   5.694 +                                     (this.cryptableMailItem.LastProcessedStatus == Globals.ReturnStatus.FailureNoConnection))
   5.695 +                            {
   5.696 +                                this.ClearPreview(Properties.Resources.Message_DecryptionNoConnection);
   5.697 +                                Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, connection failure during decryption.");
   5.698 +                            }
   5.699 +                            else
   5.700 +                            {
   5.701 +                                if ((formRegions != null) &&
   5.702 +                                    (formRegions.FormRegionPreviewUnencrypted != null) &&
   5.703 +                                    (formRegions.FormRegionPreviewUnencrypted.Visible))
   5.704 +                                {
   5.705 +                                    formRegions.FormRegionPreviewUnencrypted.SetMessage(e.Mirror);
   5.706 +                                    Log.Verbose("MailItem_GetMirrorComplete: Mirror found and displayed.");
   5.707 +                                }
   5.708 +                            }
   5.709  
   5.710 -                        // Display the mirror if necessary
   5.711 -                        if ((this.associatedMailItem != null) &&
   5.712 -                            (this.displayMirrorRequested))
   5.713 -                        {
   5.714 -                            this.associatedMailItem.DisplayMirror();
   5.715 -                            this.displayMirrorRequested = false;
   5.716 +                            // Display the mirror if necessary
   5.717 +                            if ((this.cryptableMailItem != null) &&
   5.718 +                                (this.displayMirrorRequested))
   5.719 +                            {
   5.720 +                                this.cryptableMailItem.DisplayMirror();
   5.721 +                                this.displayMirrorRequested = false;
   5.722 +                            }
   5.723                          }
   5.724                      }));
   5.725              }
   5.726 @@ -1156,11 +1150,14 @@
   5.727          /// </summary>
   5.728          private void CryptableMailItem_EncryptedConversationCacheUpdated(object sender, EventArgs e)
   5.729          {
   5.730 -            // Process the mail item now that the cache is updated
   5.731 -            this.associatedMailItem.SetIsOriginallyEncryptedByCache();
   5.732 +            if (this.isEnabled)
   5.733 +            {
   5.734 +                // Process the mail item now that the cache is updated
   5.735 +                this.cryptableMailItem.SetIsOriginallyEncryptedByCache();
   5.736  
   5.737 -            // Remove the event handler -- this can only be processed once because it's timing dependent
   5.738 -            CryptableMailItem.EncryptedConversationCacheUpdated -= CryptableMailItem_EncryptedConversationCacheUpdated;
   5.739 +                // Remove the event handler -- this can only be processed once because it's timing dependent
   5.740 +                CryptableMailItem.EncryptedConversationCacheUpdated -= CryptableMailItem_EncryptedConversationCacheUpdated;
   5.741 +            }
   5.742  
   5.743              return;
   5.744          }
   5.745 @@ -1176,11 +1173,12 @@
   5.746          {
   5.747              bool result;
   5.748  
   5.749 -            if (this.associatedMailItem != null &&
   5.750 -                this.associatedMailItem.IsSecurelyStored)
   5.751 +            if ((this.isEnabled) &&
   5.752 +                (this.cryptableMailItem != null) &&
   5.753 +                (this.cryptableMailItem.IsSecurelyStored))
   5.754              {
   5.755                  // Try to open the mirror
   5.756 -                result = this.associatedMailItem.DisplayMirror();
   5.757 +                result = this.cryptableMailItem.DisplayMirror();
   5.758  
   5.759                  if (result == false)
   5.760                  {
   5.761 @@ -1206,42 +1204,45 @@
   5.762          {
   5.763              DialogResult result;
   5.764  
   5.765 -            if ((Globals.ThisAddIn.Settings.IsSecurityLossWarningEnabled) &&
   5.766 -                (this.associatedMailItem.IsOriginallyEncrypted) &&
   5.767 -                (this.FormControlPrivacyStatusChild.DisplayState.Rating < pEpRating.pEpRatingUnreliable))
   5.768 +            if (this.isEnabled)
   5.769              {
   5.770 +                if ((Globals.ThisAddIn.Settings.IsSecurityLossWarningEnabled) &&
   5.771 +                    (this.cryptableMailItem.IsOriginallyEncrypted) &&
   5.772 +                    (this.FormControlPrivacyStatusChild.DisplayState.Rating < pEpRating.pEpRatingUnreliable))
   5.773 +                {
   5.774  
   5.775  #if READER_RELEASE_MODE
   5.776 -                FormReaderSplash warningMessage = new FormReaderSplash(true);
   5.777 -                result = warningMessage.ShowDialog();
   5.778 +                    FormReaderSplash warningMessage = new FormReaderSplash(true);
   5.779 +                    result = warningMessage.ShowDialog();
   5.780  
   5.781 -                if (result != DialogResult.OK)
   5.782 +                    if (result != DialogResult.OK)
   5.783 +                    {
   5.784 +                        // Cancel sending
   5.785 +                        cancel = true;
   5.786 +                    }
   5.787 +#else
   5.788 +                    result = System.Windows.Forms.MessageBox.Show(this.ParentForm,
   5.789 +                                                                  pEp.Properties.Resources.Message_WarningSecurityLoss,
   5.790 +                                                                  pEp.Properties.Resources.Message_TitleConfirmOperation,
   5.791 +                                                                  MessageBoxButtons.YesNo,
   5.792 +                                                                  MessageBoxIcon.Warning);
   5.793 +
   5.794 +                    if (result == DialogResult.No)
   5.795 +                    {
   5.796 +                        // Cancel sending
   5.797 +                        cancel = true;
   5.798 +                    }
   5.799 +#endif
   5.800 +                }
   5.801 +
   5.802 +                // Stop and disconnect the refresh timer
   5.803 +                // This is necessary so an ongoing refresh doesn't try to access a mail item as it's being moved
   5.804 +                if (cancel == false)
   5.805                  {
   5.806 -                    // Cancel sending
   5.807 -                    cancel = true;
   5.808 +                    this.TimerRefresh.Stop();
   5.809 +                    this.TimerRefresh.Enabled = false;
   5.810 +                    this.TimerRefresh.Tick -= TimerRefresh_Tick;
   5.811                  }
   5.812 -#else
   5.813 -                result = System.Windows.Forms.MessageBox.Show(this.ParentForm,
   5.814 -                                                              pEp.Properties.Resources.Message_WarningSecurityLoss,
   5.815 -                                                              pEp.Properties.Resources.Message_TitleConfirmOperation,
   5.816 -                                                              MessageBoxButtons.YesNo,
   5.817 -                                                              MessageBoxIcon.Warning);
   5.818 -
   5.819 -                if (result == DialogResult.No)
   5.820 -                {
   5.821 -                    // Cancel sending
   5.822 -                    cancel = true;
   5.823 -                }
   5.824 -#endif
   5.825 -            }
   5.826 -
   5.827 -            // Stop and disconnect the refresh timer
   5.828 -            // This is necessary so an ongoing refresh doesn't try to access a mail item as it's being moved
   5.829 -            if (cancel == false)
   5.830 -            {
   5.831 -                this.TimerRefresh.Stop();
   5.832 -                this.TimerRefresh.Enabled = false;
   5.833 -                this.TimerRefresh.Tick -= TimerRefresh_Tick;
   5.834              }
   5.835  
   5.836              return;
   5.837 @@ -1256,13 +1257,41 @@
   5.838          {
   5.839              switch (e.PropertyName.ToUpperInvariant())
   5.840              {
   5.841 +                case "BCC":
   5.842 +                    {
   5.843 +                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   5.844 +                        break;
   5.845 +                    }
   5.846 +                case "CC":
   5.847 +                    {
   5.848 +                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   5.849 +                        break;
   5.850 +                    }
   5.851 +                case "SENTONBEHALFOFNAME":
   5.852 +                    {
   5.853 +                        // Always fired with "SENDUSINGACCOUNT" so is ignored
   5.854 +                        break;
   5.855 +                    }
   5.856 +                case "SENDUSINGACCOUNT":
   5.857 +                    {
   5.858 +                        // Update pEp enabled status
   5.859 +                        this.SetIsEnabled(((Outlook.MailItem)this.OutlookItem).GetIsPEPEnabled());
   5.860 +
   5.861 +                        // Refresh the UI
   5.862 +                        this.ResolveAllRecipients();
   5.863 +                        this.RequestRatingAndUIUpdate();
   5.864 +                        RibbonCustomizations.Invalidate();
   5.865 +
   5.866 +                        break;
   5.867 +                    }
   5.868                  case "TO":
   5.869 -                    this.RequestRatingAndUIUpdate();
   5.870 -                    break;
   5.871 -                    // Outlook bug: there are always both events, so one is enough
   5.872 -                    //case "CC":
   5.873 -                    //    this.RequestRatingAndUIUpdate();
   5.874 -                    //    break;
   5.875 +                    {
   5.876 +                        if (this.isEnabled)
   5.877 +                        {
   5.878 +                            this.RequestRatingAndUIUpdate();
   5.879 +                        }
   5.880 +                        break;
   5.881 +                    }
   5.882              }
   5.883  
   5.884              return;
   5.885 @@ -1305,7 +1334,7 @@
   5.886          /// </summary>
   5.887          private void FormControlPrivacyStatusChild_PrivacyViewClick(object sender, System.Windows.RoutedEventArgs e)
   5.888          {
   5.889 -            if (this.managerFormEnabled)
   5.890 +            if (this.isManagerFormEnabled)
   5.891              {
   5.892                  this.RequestRatingAndUIUpdate();
   5.893                  this.BuildAndShowManager();
     6.1 --- a/UI/RibbonCustomizations.cs	Thu Oct 27 10:51:09 2016 +0200
     6.2 +++ b/UI/RibbonCustomizations.cs	Thu Oct 27 12:36:01 2016 +0200
     6.3 @@ -46,7 +46,7 @@
     6.4          /// Invalidates the associated ribbon causing it to be refreshed.
     6.5          /// This is static as Outlook will maintain only one instance of the ribbon.
     6.6          /// </summary>
     6.7 -        public static void RefreshRibbon()
     6.8 +        public static void Invalidate()
     6.9          {
    6.10              RibbonCustomizations.ribbon?.Invalidate();
    6.11              return;
    6.12 @@ -79,7 +79,7 @@
    6.13                  if (result == DialogResult.OK)
    6.14                  {
    6.15                      Globals.ThisAddIn.SetOptionsState(form.DisplayState);
    6.16 -                    RibbonCustomizations.RefreshRibbon();
    6.17 +                    RibbonCustomizations.Invalidate();
    6.18                  }
    6.19              }
    6.20              catch (Exception ex)
    6.21 @@ -91,10 +91,10 @@
    6.22          }
    6.23  
    6.24          /// <summary>
    6.25 -        /// Determines if the active UI mail item is in a pEp enabled store.
    6.26 +        /// Determines if the active UI mail item has pEp enabled for it.
    6.27          /// </summary>
    6.28 -        /// <returns>True if the mail item is in a pEp enabled store, otherwise false.</returns>
    6.29 -        private bool GetIsInPEPEnabledStore()
    6.30 +        /// <returns>True if the mail item has pEp enabled, otherwise false.</returns>
    6.31 +        private bool GetIsPEPEnabled()
    6.32          {
    6.33              bool result = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
    6.34              Outlook.MailItem currMailItem = null;
    6.35 @@ -106,7 +106,7 @@
    6.36                  (insp.CurrentItem is Outlook.MailItem))
    6.37              {
    6.38                  currMailItem = (Outlook.MailItem)insp.CurrentItem;
    6.39 -                result = currMailItem.GetIsInPEPEnabledStore();
    6.40 +                result = currMailItem.GetIsPEPEnabled();
    6.41              }
    6.42  
    6.43              if (currMailItem != null)
    6.44 @@ -640,7 +640,7 @@
    6.45          {
    6.46              // Always needed in reader mode and only needed in standard mode when pEp is enabled
    6.47              return ((Globals.RELEASE_MODE == Globals.ReleaseMode.Reader) ||
    6.48 -                    (this.GetIsInPEPEnabledStore()));
    6.49 +                    (this.GetIsPEPEnabled()));
    6.50          }
    6.51  
    6.52          /// <summary>
    6.53 @@ -841,7 +841,7 @@
    6.54          public void ToggleButtonForceUnencrypted_Click(Office.IRibbonControl control, bool isPressed)
    6.55          {
    6.56              this.SetProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, isPressed);
    6.57 -            RibbonCustomizations.RefreshRibbon();
    6.58 +            RibbonCustomizations.Invalidate();
    6.59              return;
    6.60          }
    6.61  
    6.62 @@ -860,7 +860,7 @@
    6.63          public void ToggleButtonNeverUnsecure_Click(Office.IRibbonControl control, bool isPressed)
    6.64          {
    6.65              this.SetProperty(MailItemExtensions.PEPProperty.NeverUnsecure, isPressed);
    6.66 -            RibbonCustomizations.RefreshRibbon();
    6.67 +            RibbonCustomizations.Invalidate();
    6.68              return;
    6.69          }
    6.70  
    6.71 @@ -870,7 +870,7 @@
    6.72          public void ToggleButtonForceUnencryptedContact_Click(Office.IRibbonControl control, bool isPressed)
    6.73          {
    6.74              this.SetProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, isPressed);
    6.75 -            RibbonCustomizations.RefreshRibbon();
    6.76 +            RibbonCustomizations.Invalidate();
    6.77              return;
    6.78          }
    6.79