UI/RibbonCustomizations.cs
author Thomas
Tue, 30 Jul 2019 08:18:44 +0200
branchsync
changeset 2687 f7f12cd4dd77
parent 2682 e16dba4f04d7
child 2695 273816414b64
permissions -rw-r--r--
OUT-386: Add Reset Trust context menu entry for contacts

´╗┐using pEp.UI;
using pEpCOMServerAdapterLib;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Input;
using Office = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace pEp
{
    [ComVisible(true)]
    public class RibbonCustomizations : Office.IRibbonExtensibility
    {
        /* Note: Only one instance of the RibbonCustomizations class is created in Outlook.
         * Any class variables will therefore be global between any relevant UI.
         *
         * Additionally, the Ribbon_Load event will also only be called once and only one instance of the ribbon
         * will exist. For this reason, it's safe to make the ribbon reference a static variable.
         * Making this static allows for a simple refresh ribbon method.
         */
        private static Office.IRibbonUI ribbon;

        private static bool        DISABLE_FORCE_PROTECTION_DEFAULT    = false;
        private static bool        FORCE_PROTECTION_DEFAULT            = false;
        private static bool        FORCE_UNENCRYPTED_DEFAULT           = false;
        private static bool        IS_DRAFT_DEFAULT                    = false;
        private static bool        NEVER_UNSECURE_DEFAULT              = false;
        private static pEpRating   RATING_DEFAULT                      = pEpRating.pEpRatingUndefined;

        private enum MessageProperties
        {
            DisableForceProtection,
            ForceProtection,
            ForceUnencrypted,
            IsDraft,
            NeverUnsecure,
            Rating
        }

        /**************************************************************
         * 
         * Constructors
         * 
         *************************************************************/

        /// <summary>
        /// Default constructor.
        /// </summary>
        public RibbonCustomizations()
        {
        }

        /**************************************************************
         * 
         * Property accessors
         * 
         *************************************************************/

        /// <summary>
        /// Gets whether the Force Protection option is disabled for the current mail item.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <returns>True if the Force Protection option is disabled for the current mail item, otherwise false.</returns>
        internal bool GetDisableForceProtection(Office.IRibbonControl control)
        {
            return RibbonCustomizations.GetRibbonProperty(control, MessageProperties.DisableForceProtection);
        }

        /// <summary>
        /// Sets whether the Force Protection option should be disabled for the current mail item.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <param name="disable">Whether to disable the Force Protection option or not</param>
        internal void SetDisableForceProtection(Office.IRibbonControl control, bool disable)
        {
            try
            {
                RibbonCustomizations.SetRibbonProperty(control, MessageProperties.DisableForceProtection, disable);
            }
            catch (Exception ex)
            {
                Log.Error("SetDisableForceProtection: Error setting value. " + ex.ToString());
            }
        }

        /// <summary>
        /// Gets whether the current mail item is forcefully protected.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <returns>True if the current mail item is forcefully protected, otherwise false.</returns>
        internal bool GetForceProtection(Office.IRibbonControl control)
        {
            return RibbonCustomizations.GetRibbonProperty(control, MessageProperties.ForceProtection);
        }

        /// <summary>
        /// Sets whether the current mail item should be forcefully protected or not.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <param name="forceProtection">Whether to enable Force Protection or not.</param>
        internal void SetForceProtection(Office.IRibbonControl control, bool forceProtection)
        {
            try
            {
                RibbonCustomizations.SetRibbonProperty(control, MessageProperties.ForceProtection, forceProtection);
            }
            catch (Exception ex)
            {
                Log.Error("SetForceProtection: Error setting value. " + ex.ToString());
            }
        }

        /// <summary>
        /// Gets whether the current mail item is forcefully unencrypted.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <returns>True if the current mail item is forcefully unencrypted, otherwise false.</returns>
        internal bool GetForceUnencrypted(Office.IRibbonControl control)
        {
            return RibbonCustomizations.GetRibbonProperty(control, MessageProperties.ForceUnencrypted);
        }

        /// <summary>
        /// Sets whether the current mail item should be forcefully unencrypted or not.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <param name="forceUnencrypted">Whether to enable Force Unencrypted or not.</param>
        internal void SetForceUnencrypted(Office.IRibbonControl control, bool forceUnencrypted)
        {
            try
            {
                RibbonCustomizations.SetRibbonProperty(control, MessageProperties.ForceUnencrypted, forceUnencrypted);
            }
            catch (Exception ex)
            {
                Log.Error("SetForceUnencrypted: Error setting value. " + ex.ToString());
            }
        }

        /// <summary>
        /// Gets whether the current mail item has the Never Unsecure option set
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <returns>True if the current mail item has the Never Unsecure option set, otherwise false.</returns>
        internal bool GetNeverUnsecure(Office.IRibbonControl control)
        {
            return RibbonCustomizations.GetRibbonProperty(control, MessageProperties.NeverUnsecure);
        }

        /// <summary>
        /// Sets whether the current mail item should be forcefully unencrypted or not.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <param name="neverUnsecure">Whether to enable Never Unsecure or not.</param>
        internal void SetNeverUnsecure(Office.IRibbonControl control, bool neverUnsecure)
        {
            try
            {
                RibbonCustomizations.SetRibbonProperty(control, MessageProperties.NeverUnsecure, neverUnsecure);
            }
            catch (Exception ex)
            {
                Log.Error("SetNeverUnsecure: Error setting value. " + ex.ToString());
            }
        }

        /// <summary>
        /// Gets the current UI rating as determined in the associated form region.
        /// </summary>
        /// <param name="control">The current button control.</param>
        /// <returns>The pEpRating of the current message or undefined if an error occured.</returns>
        private pEpRating GetRating(Office.IRibbonControl control)
        {
            return RibbonCustomizations.GetRibbonProperty(control, MessageProperties.Rating);
        }

        /**************************************************************
         * 
         * Methods
         * 
         *************************************************************/

        /// <summary>
        /// Invalidates the associated ribbon causing it to be refreshed.
        /// This is static as Outlook will maintain only one instance of the ribbon.
        /// </summary>
        public static void Invalidate()
        {
            RibbonCustomizations.ribbon?.Invalidate();
        }

        /// <summary>
        /// Gets the FormRegionPrivacyStatus that is associated with a given control's parent
        /// window (Inspector / Explorer). Can return null.
        /// </summary>
        /// <param name="control">The control to get the associated form region for.</param>
        /// <returns>The associated FormRegionPrivacyStatus or null if an error occured.</returns>
        private FormRegionPrivacyStatus GetFormRegionPrivacyStatus(Office.IRibbonControl control)
        {
            dynamic window = null;
            FormRegionPrivacyStatus formRegion = null;

            try
            {
                // Get the parent window
                window = control.Context as Outlook.Explorer;
                if (window == null)
                {
                    window = control.Context as Outlook.Inspector;
                }

                if (window != null)
                {
                    formRegion = Globals.FormRegions[window].FormRegionPrivacyStatus;
                }
            }
            catch (Exception ex)
            {
                formRegion = null;
                Log.Error("GetFormRegionPrivacyStatus: Error getting form region. " + ex.ToString());
            }
            finally
            {
                window = null;
            }

            return formRegion;
        }

        /// <summary>
        /// Gets a ribbon property value.
        /// </summary>
        /// <param name="control">The control to get the property value for.</param>
        /// <param name="property">The property to get its value.</param>
        /// <returns>The property value.</returns>
        private static dynamic GetRibbonProperty(Office.IRibbonControl control, MessageProperties property)
        {
            WatchedWindow window = Globals.ThisAddIn?.GetWatchedWindow(control?.Context);

            switch (property)
            {
                case MessageProperties.DisableForceProtection:
                    {
                        return window?.DisableForceProtection ?? RibbonCustomizations.DISABLE_FORCE_PROTECTION_DEFAULT;
                    }
                case MessageProperties.ForceProtection:
                    {
                        return window?.ForceProtection ?? RibbonCustomizations.FORCE_PROTECTION_DEFAULT;
                    }
                case MessageProperties.ForceUnencrypted:
                    {
                        return window?.ForceUnencrypted ?? RibbonCustomizations.FORCE_UNENCRYPTED_DEFAULT;
                    }
                case MessageProperties.IsDraft:
                    {
                        return window?.IsDraft ?? RibbonCustomizations.IS_DRAFT_DEFAULT;
                    }
                case MessageProperties.NeverUnsecure:
                    {
                        return window?.NeverUnsecure ?? RibbonCustomizations.NEVER_UNSECURE_DEFAULT;
                    }
                case MessageProperties.Rating:
                    {
                        return window?.Rating ?? RibbonCustomizations.RATING_DEFAULT;
                    }
                default:
                    break;
            }

            return null;
        }

        /// <summary>
        /// Sets a ribbon property.
        /// </summary>
        /// <param name="control">The control to set its property for.</param>
        /// <param name="property">The property to set.</param>
        /// <param name="value">The value to set.</param>
        private static void SetRibbonProperty(Office.IRibbonControl control, MessageProperties property, dynamic value)
        {
            WatchedWindow window = Globals.ThisAddIn?.GetWatchedWindow(control.Context);

            if (window != null)
            {
                switch (property)
                {
                    case MessageProperties.DisableForceProtection:
                        {
                            window.DisableForceProtection = (bool)value;
                        }
                        break;
                    case MessageProperties.ForceProtection:
                        {
                            window.ForceProtection = (bool)value;
                        }
                        break;
                    case MessageProperties.ForceUnencrypted:
                        {
                            window.ForceUnencrypted = (bool)value;
                        }
                        break;
                    case MessageProperties.IsDraft:
                        {
                            window.IsDraft = (bool)value;
                        }
                        break;
                    case MessageProperties.NeverUnsecure:
                        {
                            window.NeverUnsecure = (bool)value;
                        }
                        break;
                    case MessageProperties.Rating:
                        {
                            window.SetRating((pEpRating)value);
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// Gets the Outlook contact item that is associated with a given control's parent
        /// window (Inspector / Explorer). Can return null.
        /// </summary>
        /// <param name="control">The control to get the associated contact item for.</param>
        /// <returns>The associated contact item or null if an error occured.</returns>
        private Outlook.ContactItem GetContactItem(Office.IRibbonControl control)
        {
            Outlook.ContactItem oci = null;
            Outlook.Inspector inspector = null;
            Outlook.Explorer explorer = null;
            Outlook.Selection selection = null;

            try
            {
                inspector = control.Context as Outlook.Inspector;
                if (inspector != null)
                {
                    oci = inspector.CurrentItem as Outlook.ContactItem;
                }
                else
                {
                    explorer = control.Context as Outlook.Explorer;
                    if (explorer != null)
                    {
                        selection = explorer.Selection;
                        if (selection.Count > 0)
                        {
                            oci = selection[1] as Outlook.ContactItem;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                oci = null;
                Log.Error("GetFormRegionPrivacyStatus: Error getting form region. " + ex.ToString());
            }
            finally
            {
                inspector = null;
                explorer = null;
                selection = null;
            }

            return oci;
        }

        /// <summary>
        /// Gets whether S/MIME encryption or signature is enabled.
        /// </summary>
        /// <returns>True if S/MIME encryption or signature is enabled, otherwise false.</returns>
        private bool GetIsSMIMEEnabled(Office.IRibbonControl control)
        {
            bool isEnabled = false;
            Outlook.MailItem omi = null;

            try
            {
                omi = this.GetMailItem(control);
                isEnabled = (omi?.GetIsSMIMEEnabled() == true);
            }
            catch (Exception ex)
            {
                isEnabled = false;
                Log.Error("RibbonCustomizations.GetIsSMIMEEnabled: Error getting whether S/MIME processing is enabled. " + ex.ToString());
            }
            finally
            {
                omi = null;
            }

            return isEnabled;
        }

        /// <summary>
        /// Gets the Outlook mail item that is associated with a given control's parent
        /// window (Inspector / Explorer). Can return null.
        /// </summary>
        /// <param name="control">The control to get the associated mail item for.</param>
        /// <returns>The associated mail item or null if an error occured.</returns>
        private Outlook.MailItem GetMailItem(Office.IRibbonControl control)
        {
            Outlook.MailItem omi = null;
            Outlook.Inspector inspector = null;
            Outlook.Explorer explorer = null;
            Outlook.Selection selection = null;

            try
            {
                inspector = control.Context as Outlook.Inspector;
                if (inspector != null)
                {
                    omi = inspector.CurrentItem as Outlook.MailItem;
                }
                else
                {
                    explorer = control.Context as Outlook.Explorer;
                    if (explorer != null)
                    {
                        selection = explorer.Selection;
                        if (selection.Count > 0)
                        {
                            omi = selection[1] as Outlook.MailItem;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                omi = null;
                Log.Error("GetFormRegionPrivacyStatus: Error getting form region. " + ex.ToString());
            }
            finally
            {
                inspector = null;
                explorer = null;
                selection = null;
            }

            return omi;
        }

        /// <summary>
        /// Shows the options form with the given page selected.
        /// This will manage/save states as well.
        /// </summary>
        /// <param name="page">The page to open the options form to.</param>
        private void ShowOptions(FormControlOptions.State.OptionPages page = FormControlOptions.State.OptionPages.Accounts)
        {
            DialogResult result;
            FormOptions form;
            FormControlOptions.State state;

            try
            {
                // Update working state
                state = Globals.ThisAddIn.GetOptionsState();
                state.SelectedPage = page;

                // Build form and state
                form = new FormOptions
                {
                    StartPosition = FormStartPosition.CenterParent,
                    DisplayState = state
                };

                result = form.ShowDialog(); // Must show as dialog to block code

                if (result == DialogResult.OK)
                {
                    Globals.ThisAddIn.SetOptionsState(form.DisplayState);
                    RibbonCustomizations.Invalidate();
                }
            }
            catch (Exception ex)
            {
                Globals.StopAndSendCrashReport(ex);
            }

            return;
        }

        /// <summary>
        /// Determines if the active UI mail item has pEp enabled for it.
        /// </summary>
        /// <returns>True if the mail item has pEp enabled, otherwise false.</returns>
        private bool GetIsPEPEnabled(Office.IRibbonControl control)
        {
            Outlook.MailItem omi = null;
            bool isEnabled = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;

            try
            {
                omi = this.GetMailItem(control);
                isEnabled = omi?.GetIsPEPEnabled() ?? PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
            }
            catch (Exception ex)
            {
                isEnabled = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
                Log.Error("GetIsPEPEnabled: Error occured. " + ex.ToString());
            }
            finally
            {
                omi = null;
            }

            return isEnabled;
        }

        /// <summary>
        /// Determines whether the Decrypt Always option is enabled for the current mail item.
        /// </summary>
        /// <returns>True if the Decrypt Always option is enabled for the current mail item, otherwise false.</returns>
        private bool GetIsDecryptAlwaysEnabled(Office.IRibbonControl control)
        {
            Outlook.MailItem omi = null;
            bool isEnabled = PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;

            try
            {
                omi = this.GetMailItem(control);
                isEnabled = omi?.GetIsDecryptAlwaysEnabled() ?? PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;
            }
            catch (Exception ex)
            {
                isEnabled = PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;
                Log.Error("GetIsDecryptAlwaysEnabled: Error occured. " + ex.ToString());
            }
            finally
            {
                omi = null;
            }

            return isEnabled;
        }

        /// <summary>
        /// Gets a property of the item associated with the active UI.
        /// </summary>
        /// <param name="property">The property to get the value for.</param>
        /// <returns>The property value.</returns>
        private object GetProperty(Office.IRibbonControl control,
                                   MailItemExtensions.PEPProperty property)
        {
            object propValue;
            object result = null;
            Outlook.MailItem omi = null;
            Outlook.ContactItem oci = null;

            // Set the default
            result = MailItemExtensions.GetPEPPropertyDefault(property);

            // If the current item is a mail item
            omi = this.GetMailItem(control);
            if (omi != null)
            {
                try
                {
                    switch (property)
                    {
                        case (MailItemExtensions.PEPProperty.ForceUnencrypted):
                            {
                                // Return status can be ignored here, using the auto default value is good enough
                                omi.GetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, out propValue);
                                result = (bool)propValue;
                                break;
                            }
                        case (MailItemExtensions.PEPProperty.ForceProtection):
                            {
                                // Return status can be ignored here, using the auto default value is good enough
                                omi.GetPEPProperty(MailItemExtensions.PEPProperty.ForceProtection, out propValue);
                                result = propValue as string;
                                break;
                            }
                        case (MailItemExtensions.PEPProperty.NeverUnsecure):
                            {
                                // Return status can be ignored here, using the auto default value is good enough
                                omi.GetPEPProperty(MailItemExtensions.PEPProperty.NeverUnsecure, out propValue);
                                result = (bool)propValue;
                                break;
                            }
                        case (MailItemExtensions.PEPProperty.EnableProtection):
                            {
                                // Return status can be ignored here, using the auto default value is good enough
                                omi.GetPEPProperty(MailItemExtensions.PEPProperty.EnableProtection, out propValue);
                                result = (bool)propValue;
                                break;
                            }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("GetProperty: Error occured. " + ex.ToString());
                }
                finally
                {
                    omi = null;
                }
            }
            else
            {
                // If the current item is a contact item
                oci = this.GetContactItem(control);
                if (oci != null)
                {
                    try
                    {
                        switch (property)
                        {
                            case (MailItemExtensions.PEPProperty.ForceUnencrypted):
                                {
                                    propValue = oci.GetForceUnencrypted();

                                    // Don't replace the default if the value is null
                                    if (propValue != null)
                                    {
                                        result = (bool)propValue;
                                    }

                                    break;
                                }
                            case (MailItemExtensions.PEPProperty.NeverUnsecure):
                                {
                                    // Not supported
                                    break;
                                }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error("GetProperty: Error occured. " + ex.ToString());

                    }
                    finally
                    {
                        oci = null;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Sets the given property of the item associated with the active UI.
        /// Warning: This will call .Save() on the MailItem.
        /// </summary>
        /// <param name="property">The property to set the value for.</param>
        /// <param name="value">The value of the property to set.</param>
        private void SetProperty(Office.IRibbonControl control,
                                 MailItemExtensions.PEPProperty property,
                                 object value)
        {
            bool? propertyValue;
            Outlook.MailItem omi = null;
            Outlook.ContactItem oci = null;

            omi = this.GetMailItem(control);

            // MailItem
            if (omi != null)
            {
                try
                {
                    switch (property)
                    {
                        case (MailItemExtensions.PEPProperty.ForceProtection):
                            {
                                // Return status can be ignored
                                omi.SetPEPProperty(MailItemExtensions.PEPProperty.ForceProtection, value);

                                // Update UI
                                if (string.IsNullOrEmpty(value as string))
                                {
                                    Globals.ThisAddIn.GetWatchedWindow(control.Context)?.RequestRatingAndUIUpdate();
                                }
                                else
                                {
                                    Globals.ThisAddIn.GetWatchedWindow(control.Context)?.SetRating(pEpRating.pEpRatingReliable);
                                }
                                break;
                            }
                        case (MailItemExtensions.PEPProperty.ForceUnencrypted):
                            {
                                if ((value as bool?) != null)
                                {
                                    // Return status can be ignored
                                    omi.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, value);

                                    // Update UI
                                    this.UpdateUI(control);
                                }

                                break;
                            }
                        case (MailItemExtensions.PEPProperty.NeverUnsecure):
                            {
                                if ((value as bool?) != null)
                                {
                                    // Return status can be ignored
                                    omi.SetPEPProperty(MailItemExtensions.PEPProperty.NeverUnsecure, value);
                                }

                                break;
                            }
                        case (MailItemExtensions.PEPProperty.EnableProtection):
                            {
                                if ((value as bool?) != null)
                                {
                                    // Return status can be ignored
                                    omi.SetPEPProperty(MailItemExtensions.PEPProperty.EnableProtection, value);

                                    // Update UI
                                    Globals.ThisAddIn.GetWatchedWindow(control.Context)?.RequestRatingAndUIUpdate();
                                }

                                break;
                            }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("SetProperty: Error occured. " + ex.ToString());
                }
                finally
                {
                    omi = null;
                }
            }
            else
            {
                // ContactItem
                oci = this.GetContactItem(control);
                if (oci != null)
                {
                    try
                    {
                        switch (property)
                        {
                            case (MailItemExtensions.PEPProperty.ForceUnencrypted):
                                {
                                    if ((value as bool?) != null)
                                    {
                                        if ((value as bool?) == true)
                                        {
                                            oci.SetForceUnencrypted(true);
                                        }
                                        else
                                        {
                                            propertyValue = oci.GetForceUnencrypted();

                                            // Set the mail item value to false ONLY if it was previously true.
                                            // This is necessary because the UI will default to false if null (indeterminate).
                                            if (propertyValue == true)
                                            {
                                                oci.SetForceUnencrypted(false);
                                            }
                                        }
                                    }

                                    break;
                                }
                            case (MailItemExtensions.PEPProperty.NeverUnsecure):
                                {
                                    // Not supported
                                    break;
                                }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error("SetProperty: Error occured. " + ex.ToString());
                    }
                    finally
                    {
                        oci = null;
                    }
                }
            }
        }

        /// <summary>
        /// Updates the UI (ribbon and form region).
        /// </summary>
        /// <param name="control">The control to get its form region.</param>
        private void UpdateUI(Office.IRibbonControl control)
        {
            RibbonCustomizations.Invalidate();
            Globals.ThisAddIn.GetWatchedWindow(control?.Context)?.UpdatePrivacyStateAndUI();
        }

        /**************************************************************
         * 
         * Callbacks
         * 
         *************************************************************/

        ///////////////////////////////////////////////////////////
        // ContextMenuKeyImport
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Callback to get the store context menu key import button text.
        /// </summary>
        public string ContextMenuKeyImport_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.StoreContextMenu_KeyImportText;
        }

        /// <summary>
        /// Callback to get the visibility of the store context menu key import button.
        /// </summary>
        public bool ContextMenuKeyImport_GetVisible(Office.IRibbonControl control)
        {
            bool visible = false;
            Outlook.Account account = null;
            Outlook.Store store = null;

            try
            {
                // If this store has an associated account, show button
                store = control.Context as Outlook.Store;
                account = store?.GetAccount();

                visible = (account != null);
            }
            catch (Exception ex)
            {
                visible = false;
                Log.Error("ContextMenuKeyImport_GetVisible: Error determining visibility. " + ex.ToString());
            }
            finally
            {
                account = null;
                store = null;
            }

            return visible;
        }

        /// <summary>
        /// Callback to get the store context menu key import button image.
        /// </summary>
        public System.Drawing.Bitmap ContextMenuKeyImport_GetImage(Office.IRibbonControl control)
        {
            return Properties.Resources.ImageLogoIcon;
        }

        ///////////////////////////////////////////////////////////
        // ContextMenuKeyImportButtonPEP
        ///////////////////////////////////////////////////////////   

        /// <summary>
        /// Callback to get the store context menu key import button text.
        /// </summary>
        public string ContextMenuKeyImportButtonPEP_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.StoreContextMenu_OpenPEPKeyImportWizard;
        }

        ///////////////////////////////////////////////////////////
        // ContextMenuKeyImportButtonPGP
        ///////////////////////////////////////////////////////////   

        /// <summary>
        /// Callback to get the store context menu key import button text.
        /// </summary>
        public string ContextMenuKeyImportButtonPGP_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.StoreContextMenu_OpenPGPKeyImportWizard;
        }

        ///////////////////////////////////////////////////////////
        // ContextMenuResetContactTrust
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Callback to get the store context menu key import button text.
        /// </summary>
        public string ContextMenuResetContactTrust_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.PrivacyStatus_ResetTrust;
        }

        /// <summary>
        /// Callback to get the store context menu key import button image.
        /// </summary>
        public System.Drawing.Bitmap ContextMenuResetContactTrust_GetImage(Office.IRibbonControl control)
        {
            return Properties.Resources.ImageLogoIcon;
        }

        ///////////////////////////////////////////////////////////
        // ButtonPrivacyStatus
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the Privacy Status button is clicked.
        /// This will open the Options dialog.
        /// </summary>
        public void ButtonPrivacyStatus_Click(Office.IRibbonControl control)
        {
            try
            {
                Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
                Globals.ThisAddIn.GetWatchedWindow(control.Context)?.BuildAndShowManager();
            }
            catch (Exception ex)
            {
                Globals.StopAndSendCrashReport(ex);
            }
        }

        /// <summary>
        /// Callback to get the image of the ButtonPrivacyStatus.
        /// </summary>
        public System.Drawing.Bitmap ButtonPrivacyStatus_GetImage(Office.IRibbonControl control)
        {
            return Globals.ThisAddIn.GetWatchedWindow(control?.Context)?.PrivacyState?.Image;
        }

        /// <summary>
        /// Callback to get the label of the ButtonPrivacyStatus.
        /// </summary>
        public string ButtonPrivacyStatus_GetLabel(Office.IRibbonControl control)
        {
            string label = Globals.ThisAddIn.GetWatchedWindow(control?.Context)?.PrivacyState?.Label;

            // Workaround to show ampersands correctly
            if (label?.Contains(" & ") == true)
            {
                label = label.Replace(" & ", " && ");
            }
            return label;
        }

        /// <summary>
        /// Callback to get the supertip of the ButtonPrivacyStatus.
        /// </summary>
        public string ButtonPrivacyStatus_GetScreentip(Office.IRibbonControl control)
        {
            return Properties.Resources.PrivacyStatus_FormText;
        }

        /// <summary>
        /// Callback to get whether the ButtonPrivacyStatus is visible.
        /// </summary>
        public bool ButtonPrivacyStatus_GetVisible(Office.IRibbonControl control)
        {
            /* Visible if pEp enabled.
             * If pEp is disabled, only visible in draft windows (so user can Enable Protection)
             * or if DecryptAlways option is set.
             */
            bool visible = true;

            if (this.GetIsPEPEnabled(control) == false)
            {
                visible = false;
                dynamic window = null;
                Outlook.MailItem omi = null;

                try
                {
                    // Get the parent window
                    window = control.Context as Outlook.Explorer;
                    if (window != null)
                    {
                        visible = this.GetIsDecryptAlwaysEnabled(control);
                    }
                    else
                    {
                        window = control.Context as Outlook.Inspector;
                        if (window != null)
                        {
                            omi = this.GetMailItem(control);
                            visible = ((omi?.GetIsDraft() == true) ||
                                       (this.GetIsDecryptAlwaysEnabled(control)));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("ButtonPrivacyStatus_GetVisible: Error occured. " + ex.ToString());
                }
                finally
                {
                    omi = null;
                    window = null;
                }
            }

            return visible;
        }

        /// <summary>
        /// Event handler for when the builtin Encrypt Message button is clicked.
        /// </summary>
        public void ButtonSMIME_Clicked(Office.IRibbonControl control, bool pressed, ref bool cancel)
        {
            cancel = false;
            Globals.ThisAddIn.GetWatchedWindow(control.Context)?.RequestRatingAndUIUpdate();
        }

        ///////////////////////////////////////////////////////////
        // ToggleButtonForceUnencrypted
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the ToggleButtonForceUnencrypted is clicked.
        /// </summary>
        public void ToggleButtonForceUnencrypted_Click(Office.IRibbonControl control, bool isPressed)
        {
            this.SetForceUnencrypted(control, isPressed);

            // Disable Force Protection and Never Unsecure if needed
            if (isPressed)
            {
                this.SetForceProtection(control, false);
                this.SetNeverUnsecure(control, false);
            }

            this.UpdateUI(control);
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceUnencrypted is enabled.
        /// </summary>
        public bool ToggleButtonForceUnencrypted_GetEnabled(Office.IRibbonControl control)
        {
            /* The button is disabled if
             *  - Rating is lower than reliable
             *  - Force Protection or Never Unsecure are enabled and not overridden
             */
            if (((this.GetRating(control) < pEpRating.pEpRatingReliable) ||
                 (this.GetNeverUnsecure(control))) ||
                 ((this.GetForceProtection(control)) && (this.GetDisableForceProtection(control) == false)))
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// Callback to get the label text for the ToggleButtonForceUnencrypted.
        /// </summary>
        public string ToggleButtonForceUnencrypted_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceUnencrypted;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceUnencrypted is pressed.
        /// </summary>
        public bool ToggleButtonForceUnencrypted_GetPressed(Office.IRibbonControl control)
        {
            return this.GetForceUnencrypted(control);
        }

        /// <summary>
        /// Callback to get the supertip/description text for the ToggleButtonForceUnencrypted.
        /// </summary>
        public string ToggleButtonForceUnencrypted_GetSupertip(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceUnencryptedDesc;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceUnencrypted is visible.
        /// </summary>
        public bool ToggleButtonForceUnencrypted_GetVisible(Office.IRibbonControl control)
        {
            return ((Globals.RELEASE_MODE != Globals.ReleaseMode.Reader) &&
                    (this.GetIsPEPEnabled(control)));
        }

        ///////////////////////////////////////////////////////////
        // ToggleButtonEnableProtection
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the ToggleButtonEnableProtection is clicked.
        /// </summary>
        public void ToggleButtonEnableProtection_Click(Office.IRibbonControl control, bool isPressed)
        {
            this.SetProperty(control, MailItemExtensions.PEPProperty.EnableProtection, isPressed);

            // If protection is disabled, disable also force protected and never unsecure
            if (isPressed == false)
            {
                this.SetForceProtection(control, false);
                this.SetNeverUnsecure(control, false);
            }
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonEnableProtection is enabled.
        /// </summary>
        public bool ToggleButtonEnableProtection_GetEnabled(Office.IRibbonControl control)
        {
            // If button is visible, it is also enabled
            return true;
        }

        /// <summary>
        /// Callback to get the label text for the ToggleButtonEnableProtection.
        /// </summary>
        public string ToggleButtonEnableProtection_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_EnableProtection;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonEnableProtection is pressed.
        /// </summary>
        public bool ToggleButtonEnableProtection_GetPressed(Office.IRibbonControl control)
        {
            return ((this.GetProperty(control, MailItemExtensions.PEPProperty.EnableProtection) as bool?) ?? false);
        }

        /// <summary>
        /// Callback to get the supertip/description text for the ToggleButtonEnableProtection.
        /// </summary>
        public string ToggleButtonEnableProtection_GetSupertip(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_EnableProtectionDesc);
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonEnableProtection is visible.
        /// </summary>
        public bool ToggleButtonEnableProtection_GetVisible(Office.IRibbonControl control)
        {
            return ((Globals.RELEASE_MODE != Globals.ReleaseMode.Reader) &&
                    (this.GetIsPEPEnabled(control)) == false);
        }

        ///////////////////////////////////////////////////////////
        // ToggleButtonForceProtection
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the ToggleButtonForceProtection is clicked.
        /// </summary>
        public void ToggleButtonForceProtection_Click(Office.IRibbonControl control, bool isPressed)
        {
            this.SetForceProtection(control, isPressed);

            // If protection is disabled, disable also never unsecure
            if (isPressed == false)
            {
                this.SetNeverUnsecure(control, isPressed);
            }

            this.UpdateUI(control);
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceProtection is enabled
        /// </summary>
        public bool ToggleButtonForceProtection_GetEnabled(Office.IRibbonControl control)
        {
            bool enabled = false;

            /* The button is enabled when:
             * 1. No S/MIME option is enabled
             * 2. Force Unencrypted is not enabled
             * 3. Rating is Unsecure
             */
            if ((this.GetIsSMIMEEnabled(control)) ||
                (this.GetDisableForceProtection(control)))
            {
                return false;
            }

            if (this.GetIsPEPEnabled(control))
            {
                enabled = ((this.GetRating(control) == pEpRating.pEpRatingUnencrypted) &&
                           (this.GetForceUnencrypted(control) == false));
            }
            else
            {
                enabled = ((this.GetRating(control) == pEpRating.pEpRatingUnencrypted) &&
                           ((this.GetProperty(control, MailItemExtensions.PEPProperty.EnableProtection) as bool?) ?? false));
            }

            return enabled;
        }

        /// <summary>
        /// Callback to get the label text for the ToggleButtonForceProtection.
        /// </summary>
        public string ToggleButtonForceProtection_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceProtection;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceProtection is pressed.
        /// </summary>
        public bool ToggleButtonForceProtection_GetPressed(Office.IRibbonControl control)
        {
            return ((this.GetForceProtection(control)) &&
                    (this.GetDisableForceProtection(control) == false));
        }

        /// <summary>
        /// Callback to get the supertip/description text for the ToggleButtonForceProtection.
        /// </summary>
        public string ToggleButtonForceProtection_GetSupertip(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceProtectionDesc;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceProtection is visible.
        /// </summary>
        public bool ToggleButtonForceProtection_GetVisible(Office.IRibbonControl control)
        {
            // Disabled for the moment
            return false;

            // Visible if not in Reader mode
            //return (Globals.RELEASE_MODE != Globals.ReleaseMode.Reader);
        }

        ///////////////////////////////////////////////////////////
        // ToggleButtonNeverUnsecure
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the ToggleButtonNeverUnsecure is clicked.
        /// </summary>
        public void ToggleButtonNeverUnsecure_Click(Office.IRibbonControl control, bool isPressed)
        {
            this.SetNeverUnsecure(control, isPressed);
            this.UpdateUI(control);
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonNeverUnsecure is enabled.
        /// </summary>
        public bool ToggleButtonNeverUnsecure_GetEnabled(Office.IRibbonControl control)
        {
            // Enabled if not forcefully unencrypted, rating >= Reliable (or force protection), no S/MIME enabled and no BCC recipients
            return (((this.GetRating(control) >= pEpRating.pEpRatingReliable) || (this.GetForceProtection(control)) && (this.ToggleButtonForceProtection_GetEnabled(control))) &&
                    (this.GetForceUnencrypted(control) == false) &&
                    (this.GetIsSMIMEEnabled(control) == false));
        }

        /// <summary>
        /// Callback to get the label text for the ToggleButtonNeverUnsecure.
        /// </summary>
        public string ToggleButtonNeverUnsecure_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_NeverUnsecure;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonNeverUnsecure is pressed.
        /// </summary>
        public bool ToggleButtonNeverUnsecure_GetPressed(Office.IRibbonControl control)
        {
            return this.GetNeverUnsecure(control);
        }

        /// <summary>
        /// Callback to get the supertip/description text for the ToggleButtonNeverUnsecure.
        /// </summary>
        public string ToggleButtonNeverUnsecure_GetSupertip(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_NeverUnsecureDesc;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonNeverUnsecure is visible.
        /// </summary>
        public bool ToggleButtonNeverUnsecure_GetVisible(Office.IRibbonControl control)
        {
            return (Globals.ThisAddIn.Settings.IsNeverUnsecureOptionVisible &&
                    (Globals.RELEASE_MODE != Globals.ReleaseMode.Reader));
        }

        ///////////////////////////////////////////////////////////
        // ButtonUpgradePEP
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the Upgrade pEp button is clicked.
        /// </summary>
        public void ButtonUpgradePEP_Click(Office.IRibbonControl control)
        {
            try
            {
                Process.Start(Globals.PEP_WEBSITE_UPGRADE_LINK);
            }
            catch (Exception ex)
            {
                Log.Error("ButtonUpgradePEP_Click: Unable to open website link, " + ex.ToString());
            }
        }

        /// <summary>
        /// Callback to get whether the ButtonUpgradePEP is enabled.
        /// </summary>
        public bool ButtonUpgradePEP_GetEnabled(Office.IRibbonControl control)
        {
            // Always true, as it has to be clickable while shown
            return true;
        }

        /// <summary>
        /// Callback to get the image for the ButtonUpgradePEP.
        /// </summary>
        public System.Drawing.Bitmap ButtonUpgradePEP_GetImage(Office.IRibbonControl control)
        {
            return Properties.Resources.ImageUpgradePEP;
        }

        /// <summary>
        /// Callback to get the label text for the ButtonUpgradePEP.
        /// </summary>
        public string ButtonUpgradePEP_GetLabel(Office.IRibbonControl control)
        {
            return (Environment.NewLine + Properties.Resources.Ribbon_UpgradePEP);
        }

        /// <summary>
        /// Callback to get the supertip/description text for the ButtonUpgradePEP.
        /// </summary>
        public string ButtonUpgradePEP_GetSupertip(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_UpgradePEPDesc;
        }

        /// <summary>
        /// Callback to get whether the ButtonUpgradePEP is visible.
        /// </summary>
        public bool ButtonUpgradePEP_GetVisible(Office.IRibbonControl control)
        {
            // Only visible in reader mode
            return (Globals.RELEASE_MODE == Globals.ReleaseMode.Reader);
        }

        ///////////////////////////////////////////////////////////
        // Groups
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Callback to get whether the GroupPEPNewMailMessage is visible.
        /// </summary>
        public bool GroupPEPNewMailMessage_GetVisible(Office.IRibbonControl control)
        {
            // Always needed
            return true;
        }

        /**************************************************************
         *
         * Callbacks (Contact Inspector Ribbon)
         *
         *************************************************************/

        ///////////////////////////////////////////////////////////
        // ToggleButtonForceUnencryptedContact
        ///////////////////////////////////////////////////////////

        /// <summary>
        /// Event handler for when the ToggleButtonForceUnencryptedContact is clicked.
        /// </summary>
        public void ToggleButtonForceUnencryptedContact_Click(Office.IRibbonControl control, bool isPressed)
        {
            this.SetProperty(control, MailItemExtensions.PEPProperty.ForceUnencrypted, isPressed);
            this.UpdateUI(control);
        }

        /// <summary>
        /// Callback to get the image for the ToggleButtonForceUnencryptedContact.
        /// </summary>
        public System.Drawing.Bitmap ToggleButtonForceUnencryptedContact_GetImage(Office.IRibbonControl control)
        {
            if ((bool)this.GetProperty(control, MailItemExtensions.PEPProperty.ForceUnencrypted))
            {
                return Properties.Resources.ImageForceUnencOn;
            }
            else
            {
                return Properties.Resources.ImageForceUnencOff;
            }
        }

        /// <summary>
        /// Callback to get the label text for the ToggleButtonForceUnencryptedContact.
        /// </summary>
        public string ToggleButtonForceUnencryptedContact_GetLabel(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceUnencrypted;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceUnencryptedContact is pressed.
        /// </summary>
        public bool ToggleButtonForceUnencryptedContact_GetPressed(Office.IRibbonControl control)
        {
            return (bool)this.GetProperty(control, MailItemExtensions.PEPProperty.ForceUnencrypted);
        }

        /// Callback to get the supertip/description text for the ToggleButtonForceUnencryptedContact.
        /// </summary>
        public string ToggleButtonForceUnencryptedContact_GetSupertip(Office.IRibbonControl control)
        {
            return Properties.Resources.Ribbon_ForceUnencryptedDesc;
        }

        /// <summary>
        /// Callback to get whether the ToggleButtonForceUnencryptedContact is visible.
        /// </summary>
        public bool ToggleButtonForceUnencryptedContact_GetVisible(Office.IRibbonControl control)
        {
            return true;
        }

        /// <summary>
        /// Callback to get whether the GroupPEPContact is visible.
        /// </summary>
        public bool GroupPEPContact_GetVisible(Office.IRibbonControl control)
        {
            return (Globals.ThisAddIn.Settings.IsDisableProtectionForContactsEnabled &&
                    (Globals.RELEASE_MODE != Globals.ReleaseMode.Reader));
        }

        /**************************************************************
         *
         * Callbacks (Backstage)
         *
         *************************************************************/

        /// <summary>
        /// Callback to get the image for the ButtonAccounts.
        /// </summary>
        public System.Drawing.Bitmap ButtonAccounts_GetImage(Office.IRibbonControl control)
        {
            return (Properties.Resources.ImageBackstageAccounts);
        }

        /// <summary>
        /// Callback to get the image for the ButtonCompatibility.
        /// </summary>
        public System.Drawing.Bitmap ButtonCompatibility_GetImage(Office.IRibbonControl control)
        {
            return (Properties.Resources.ImageBackstageCompatibility);
        }

        /// <summary>
        /// Callback to get the image for the ButtonCompatibility.
        /// </summary>
        public System.Drawing.Bitmap ButtonSync_GetImage(Office.IRibbonControl control)
        {
            return (Properties.Resources.ImageBackstageCompatibility);
        }

        /// <summary>
        /// Callback to get the image for the ImageControlLogo.
        /// </summary>
        public System.Drawing.Bitmap ImageControlLogo_GetImage(Office.IRibbonControl control)
        {
            return (Properties.Resources.ImageLogoMedium);
        }

        /// <summary>
        /// Callback to get the helper text for the GroupAccounts.
        /// </summary>
        public string GroupAccounts_GetHelperText(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_GroupAccountsHelperText);
        }

        /// <summary>
        /// Callback to get the helper text for the GroupCompatibility.
        /// </summary>
        public string GroupCompatibility_GetHelperText(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_GroupCompatibilityHelperText);
        }

        /// <summary>
        /// Callback to get the label text for the GroupAccounts.
        /// </summary>
        public string GroupAccounts_GetLabel(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_GroupAccountsLabel);
        }

        /// <summary>
        /// Callback to get the label text for the GroupCompatibility.
        /// </summary>
        public string GroupCompatibility_GetLabel(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_GroupCompatibilityLabel);
        }

        /// <summary>
        /// Callback to get the visibility of the GroupPEPHome.
        /// </summary>
        public bool GroupPEPHome_GetVisible(Office.IRibbonControl control)
        {
            bool visible = true;

            /* In Outlook 2010, there is no inline response.
             * IMPORTANT: Never call Explorer.ActiveInlineResponse on Outlook 2010
             *            as this might lead to a crash of Outlook (even inside a
             *            try/catch block)
             */
            if (Globals.OutlookVersion != Globals.Version.Outlook2010)
            {
                Outlook.Explorer explorer = null;
                try
                {
                    // Show only if no inline response is open
                    explorer = control.Context as Outlook.Explorer;
                    if (explorer != null)
                    {
                        visible = (explorer.ActiveInlineResponse == null);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("GroupPEPHome_GetVisible: Error occured. " + ex.ToString());
                }
                finally
                {
                    explorer = null;
                }
            }

            return visible;
        }

        /// <summary>
        /// Callback to get the label text for the ButtonAccounts.
        /// </summary>
        public string ButtonAccounts_GetLabel(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_ButtonAccountsLabel);
        }

        /// <summary>
        /// Callback to get the label text for the ButtonCompatibility.
        /// </summary>
        public string ButtonCompatibility_GetLabel(Office.IRibbonControl control)
        {
            return (Properties.Resources.Ribbon_ButtonCompatibilityLabel);
        }

        /// <summary>
        /// Callback to get the label text for the LabelControlName.
        /// </summary>
        public string LabelControlName_GetLabel(Office.IRibbonControl control)
        {
            return (Globals.RELEASE_MODE == Globals.ReleaseMode.Reader ? Globals.PEP_DISPLAY_NAME_READER : Globals.PEP_DISPLAY_NAME);
        }

        /// <summary>
        /// Callback to get the label text for the LabelControlVersion.
        /// </summary>
        public string LabelControlVersion_GetLabel(Office.IRibbonControl control)
        {
            return (Globals.GetPEPVersion());
        }

        /// <summary>
        /// Callback to get the label text for the LabelControlCopyright.
        /// </summary>
        public string LabelControlCopyright_GetLabel(Office.IRibbonControl control)
        {
            return (Globals.PEP_COPYRIGHT);
        }

        /**************************************************************
         *
         * Event Handling
         *
         *************************************************************/

        /// <summary>
        /// Event handler for when the ribbon loads.
        /// </summary>
        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            RibbonCustomizations.ribbon = ribbonUI;
        }

        /**************************************************************
         *
         * Event Handling (Context menu)
         *
         *************************************************************/

        /// <summary>
        /// Event handler for when the key import context menu button is clicked.
        /// </summary>
        public void ContextMenuKeyImportButton_Click(Office.IRibbonControl control)
        {
            Outlook.Store store = null;
            PEPIdentity ownIdentity = null;

            try
            {
                // Get own pEp identity of this store
                store = control.Context as Outlook.Store;
                ownIdentity = store.GetPEPIdentity(true);

                // Open wizard if identity has been successfully retrieved.
                if (ownIdentity != null)
                {
                    // Get wizard type (event can be raised from different buttons)
                    var wizardType = (control?.Id.Equals("ContextMenuKeyImportButtonPGP") == true) ? KeySyncWizard.WizardType.PGP : KeySyncWizard.WizardType.pEp;
                    KeySyncWizard.Wizard = new KeySyncWizard(wizardType, true, ownIdentity);
                    KeySyncWizard.Wizard?.Show();
                }
                else
                {
                    Log.Error("ContextMenuKeyImport_Click: Error getting own identity.");
                }
            }
            catch (Exception ex)
            {
                Log.Error("ContextMenuKeyImport_Click: Error opening wizard. " + ex.ToString());
            }
            finally
            {
                store = null;
            }
        }

        /// <summary>
        /// Event handler for when the reset contact context menu button is clicked.
        /// </summary>
        public void ContextMenuResetContactTrustButton_Click(Office.IRibbonControl control)
        {
            Outlook.Selection selection;
            Outlook.ContactItem contact;

            try
            {
                // Get the selected contact(s) and reset their trust
                selection = control.Context as Outlook.Selection;

                for (int i = 1; i <= selection.Count; i++)
                {
                    contact = selection[i];
                    string id = contact.EntryID;
                    ThisAddIn.PEPEngine.KeyResetUser(id, null);
                    contact = null;
                }
            }
            catch (Exception ex)
            {
                Log.Error("ContextMenuResetContactTrustButton_Click: Error occured. " + ex.ToString());
            }
            finally
            {
                contact = null;
                selection = null;
            }
        }

        /**************************************************************
         *
         * Event Handling (Backstage)
         *
         *************************************************************/

        /// <summary>
        /// Event handler for when the accounts button is clicked.
        /// This will open the options form.
        /// </summary>
        public void ButtonAccounts_Click(Office.IRibbonControl control)
        {
            this.ShowOptions(FormControlOptions.State.OptionPages.Accounts);
        }

        /// <summary>
        /// Event handler for when the compatiblity button is clicked.
        /// This will open the options form.
        /// </summary>
        public void ButtonCompatibility_Click(Office.IRibbonControl control)
        {
            this.ShowOptions(FormControlOptions.State.OptionPages.Compatibility);
        }

        /// <summary>
        /// Event handler for when the about button is clicked.
        /// This will open the options form.
        /// </summary>
        public void ButtonAbout_Click(Office.IRibbonControl control)
        {
            this.ShowOptions(FormControlOptions.State.OptionPages.About);
        }

        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            switch (ribbonID)
            {
                case "Microsoft.Outlook.Explorer":
                    if (Globals.OutlookVersion == Globals.Version.Outlook2010)
                    {
                        return GetResourceText("pEp.UI.RibbonCustomizationsExplorer2010.xml");
                    }
                    else
                    {
                        return GetResourceText("pEp.UI.RibbonCustomizationsExplorer.xml");
                    }
                case "Microsoft.Outlook.Mail.Compose":
                    return GetResourceText("pEp.UI.RibbonCustomizationsCompose.xml");
                case "Microsoft.Outlook.Mail.Read":
                    return GetResourceText("pEp.UI.RibbonCustomizationsRead.xml");
                default:
                    return GetResourceText("pEp.UI.RibbonCustomizations.xml");
            }
        }

        #endregion

        #region Helpers

        private static string GetResourceText(string resourceName)
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] resourceNames = asm.GetManifestResourceNames();
            for (int i = 0; i < resourceNames.Length; ++i)
            {
                if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
                {
                    using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
                    {
                        if (resourceReader != null)
                        {
                            return resourceReader.ReadToEnd();
                        }
                    }
                }
            }
            return null;
        }

        #endregion
    }
}