Add modified form region and control both ribbon and form region via PrivacyState OUT-514
authorThomas
Thu, 18 Oct 2018 12:27:44 +0200
branchOUT-514
changeset 24098908fefc77e3
parent 2408 f4f711fe1c98
child 2410 80c01cc1dec1
Add modified form region and control both ribbon and form region via PrivacyState
Properties/Resources.Designer.cs
Properties/Resources.resx
Resources/Dictionary.xaml
UI/FormRegionPrivacyStatus.Designer.cs
UI/FormRegionPrivacyStatus.cs
UI/PrivacyState.cs
UI/PrivacyView.xaml
UI/PrivacyView.xaml.cs
UI/RibbonCustomizations.cs
UI/UserControlPrivacyStatus.xaml
UI/UserControlPrivacyStatus.xaml.cs
pEpForOutlook.csproj
     1.1 --- a/Properties/Resources.Designer.cs	Wed Oct 17 08:04:35 2018 +0200
     1.2 +++ b/Properties/Resources.Designer.cs	Thu Oct 18 12:27:44 2018 +0200
     1.3 @@ -683,6 +683,16 @@
     1.4          /// <summary>
     1.5          ///   Looks up a localized resource of type System.Drawing.Bitmap.
     1.6          /// </summary>
     1.7 +        public static System.Drawing.Bitmap ImagePrivacyStatusGreenInvert {
     1.8 +            get {
     1.9 +                object obj = ResourceManager.GetObject("ImagePrivacyStatusGreenInvert", resourceCulture);
    1.10 +                return ((System.Drawing.Bitmap)(obj));
    1.11 +            }
    1.12 +        }
    1.13 +        
    1.14 +        /// <summary>
    1.15 +        ///   Looks up a localized resource of type System.Drawing.Bitmap.
    1.16 +        /// </summary>
    1.17          public static System.Drawing.Bitmap ImagePrivacyStatusGreenProtectionDisabled {
    1.18              get {
    1.19                  object obj = ResourceManager.GetObject("ImagePrivacyStatusGreenProtectionDisabled", resourceCulture);
    1.20 @@ -713,6 +723,16 @@
    1.21          /// <summary>
    1.22          ///   Looks up a localized resource of type System.Drawing.Bitmap.
    1.23          /// </summary>
    1.24 +        public static System.Drawing.Bitmap ImagePrivacyStatusNoColorInvert {
    1.25 +            get {
    1.26 +                object obj = ResourceManager.GetObject("ImagePrivacyStatusNoColorInvert", resourceCulture);
    1.27 +                return ((System.Drawing.Bitmap)(obj));
    1.28 +            }
    1.29 +        }
    1.30 +        
    1.31 +        /// <summary>
    1.32 +        ///   Looks up a localized resource of type System.Drawing.Bitmap.
    1.33 +        /// </summary>
    1.34          public static System.Drawing.Bitmap ImagePrivacyStatusRed {
    1.35              get {
    1.36                  object obj = ResourceManager.GetObject("ImagePrivacyStatusRed", resourceCulture);
    1.37 @@ -733,6 +753,16 @@
    1.38          /// <summary>
    1.39          ///   Looks up a localized resource of type System.Drawing.Bitmap.
    1.40          /// </summary>
    1.41 +        public static System.Drawing.Bitmap ImagePrivacyStatusYellowInvert {
    1.42 +            get {
    1.43 +                object obj = ResourceManager.GetObject("ImagePrivacyStatusYellowInvert", resourceCulture);
    1.44 +                return ((System.Drawing.Bitmap)(obj));
    1.45 +            }
    1.46 +        }
    1.47 +        
    1.48 +        /// <summary>
    1.49 +        ///   Looks up a localized resource of type System.Drawing.Bitmap.
    1.50 +        /// </summary>
    1.51          public static System.Drawing.Bitmap ImagePrivacyStatusYellowProtectionDisabled {
    1.52              get {
    1.53                  object obj = ResourceManager.GetObject("ImagePrivacyStatusYellowProtectionDisabled", resourceCulture);
    1.54 @@ -2041,7 +2071,7 @@
    1.55          }
    1.56          
    1.57          /// <summary>
    1.58 -        ///   Looks up a localized string similar to Secure &amp;&amp; Trusted.
    1.59 +        ///   Looks up a localized string similar to Secure &amp; Trusted.
    1.60          /// </summary>
    1.61          public static string PrivacyStatus_RatingTrustedText {
    1.62              get {
     2.1 --- a/Properties/Resources.resx	Wed Oct 17 08:04:35 2018 +0200
     2.2 +++ b/Properties/Resources.resx	Thu Oct 18 12:27:44 2018 +0200
     2.3 @@ -539,7 +539,7 @@
     2.4      <value>No action needed!</value>
     2.5    </data>
     2.6    <data name="PrivacyStatus_RatingTrustedText" xml:space="preserve">
     2.7 -    <value>Secure &amp;&amp; Trusted</value>
     2.8 +    <value>Secure &amp; Trusted</value>
     2.9    </data>
    2.10    <data name="PrivacyStatus_RatingUndefinedExplanation" xml:space="preserve">
    2.11      <value>This message does not contain enough information to determine if it is secure.</value>
    2.12 @@ -940,4 +940,13 @@
    2.13    <data name="ImagePrivacyStatusYellowProtectionDisabledInvert" type="System.Resources.ResXFileRef, System.Windows.Forms">
    2.14      <value>..\Resources\ImagePrivacyStatusYellowProtectionDisabledInvert.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    2.15    </data>
    2.16 +  <data name="ImagePrivacyStatusGreenInvert" type="System.Resources.ResXFileRef, System.Windows.Forms">
    2.17 +    <value>..\Resources\ImagePrivacyStatusGreenInvert.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    2.18 +  </data>
    2.19 +  <data name="ImagePrivacyStatusNoColorInvert" type="System.Resources.ResXFileRef, System.Windows.Forms">
    2.20 +    <value>..\Resources\ImagePrivacyStatusNoColorInvert.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    2.21 +  </data>
    2.22 +  <data name="ImagePrivacyStatusYellowInvert" type="System.Resources.ResXFileRef, System.Windows.Forms">
    2.23 +    <value>..\Resources\ImagePrivacyStatusYellowInvert.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
    2.24 +  </data>
    2.25  </root>
    2.26 \ No newline at end of file
     3.1 --- a/Resources/Dictionary.xaml	Wed Oct 17 08:04:35 2018 +0200
     3.2 +++ b/Resources/Dictionary.xaml	Thu Oct 18 12:27:44 2018 +0200
     3.3 @@ -66,7 +66,7 @@
     3.4                       Color="Black" />
     3.5      <SolidColorBrush x:Key="BrushTextWhite"
     3.6                       Color="White" />
     3.7 -
     3.8 +    
     3.9      <!--***********************************************************
    3.10       * 
    3.11       * Other
     4.1 --- a/UI/FormRegionPrivacyStatus.Designer.cs	Wed Oct 17 08:04:35 2018 +0200
     4.2 +++ b/UI/FormRegionPrivacyStatus.Designer.cs	Thu Oct 18 12:27:44 2018 +0200
     4.3 @@ -43,13 +43,44 @@
     4.4          {
     4.5              this.components = new System.ComponentModel.Container();
     4.6              this.TimerRefresh = new System.Windows.Forms.Timer(this.components);
     4.7 +            this.PanelPrivacyStatus = new System.Windows.Forms.Panel();
     4.8              this.ElementHostFormControl = new System.Windows.Forms.Integration.ElementHost();
     4.9 +            this.UserControlPrivacyStatus = new pEp.UI.UserControlPrivacyStatus();
    4.10 +            this.TimerMonitor = new System.Windows.Forms.Timer(this.components);
    4.11 +            this.PanelPrivacyStatus.SuspendLayout();
    4.12              this.SuspendLayout();
    4.13              // 
    4.14 +            // PanelPrivacyStatus
    4.15 +            // 
    4.16 +            this.PanelPrivacyStatus.BackColor = System.Drawing.Color.Transparent;
    4.17 +            this.PanelPrivacyStatus.Controls.Add(this.ElementHostFormControl);
    4.18 +            this.PanelPrivacyStatus.Dock = System.Windows.Forms.DockStyle.Fill;
    4.19 +            this.PanelPrivacyStatus.Location = new System.Drawing.Point(0, 0);
    4.20 +            this.PanelPrivacyStatus.Name = "PanelPrivacyStatus";
    4.21 +            this.PanelPrivacyStatus.Size = new System.Drawing.Size(500, 36);
    4.22 +            this.PanelPrivacyStatus.TabIndex = 0;
    4.23 +            // 
    4.24 +            // ElementHostFormControl
    4.25 +            // 
    4.26 +            this.ElementHostFormControl.Dock = System.Windows.Forms.DockStyle.Fill;
    4.27 +            this.ElementHostFormControl.Location = new System.Drawing.Point(0, 0);
    4.28 +            this.ElementHostFormControl.Name = "ElementHostFormControl";
    4.29 +            this.ElementHostFormControl.Size = new System.Drawing.Size(500, 36);
    4.30 +            this.ElementHostFormControl.TabIndex = 0;
    4.31 +            this.ElementHostFormControl.Child = this.UserControlPrivacyStatus;
    4.32 +            // 
    4.33              // FormRegionPrivacyStatus
    4.34              // 
    4.35 +            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    4.36 +            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    4.37 +            this.Controls.Add(this.PanelPrivacyStatus);
    4.38 +            this.Name = "FormRegionPrivacyStatus";
    4.39 +            this.Size = new System.Drawing.Size(500, 36);
    4.40              this.FormRegionShowing += new System.EventHandler(this.FormRegionPrivacyStatus_FormRegionShowing);
    4.41              this.FormRegionClosed += new System.EventHandler(this.FormRegionPrivacyStatus_FormRegionClosed);
    4.42 +            this.PanelPrivacyStatus.ResumeLayout(false);
    4.43 +            this.ResumeLayout(false);
    4.44 +
    4.45          }
    4.46  
    4.47          #endregion
    4.48 @@ -71,7 +102,10 @@
    4.49          #endregion
    4.50  
    4.51          private System.Windows.Forms.Timer TimerRefresh;
    4.52 +        private System.Windows.Forms.Panel PanelPrivacyStatus;
    4.53          private System.Windows.Forms.Integration.ElementHost ElementHostFormControl;
    4.54 +        private UI.UserControlPrivacyStatus UserControlPrivacyStatus;
    4.55 +        private System.Windows.Forms.Timer TimerMonitor;
    4.56  
    4.57          public partial class FormRegionPrivacyStatusFactory : Microsoft.Office.Tools.Outlook.IFormRegionFactory
    4.58          {
     5.1 --- a/UI/FormRegionPrivacyStatus.cs	Wed Oct 17 08:04:35 2018 +0200
     5.2 +++ b/UI/FormRegionPrivacyStatus.cs	Thu Oct 18 12:27:44 2018 +0200
     5.3 @@ -105,11 +105,6 @@
     5.4           *************************************************************/
     5.5  
     5.6          /// <summary>
     5.7 -        /// The rating of this message.
     5.8 -        /// </summary>
     5.9 -        private pEpRating _Rating = pEpRating.pEpRatingUndefined;
    5.10 -
    5.11 -        /// <summary>
    5.12          /// Gets or sets whether to disable the Force Protection option.
    5.13          /// </summary>
    5.14          public bool DisableForceProtection { get; set; } = false;
    5.15 @@ -147,12 +142,14 @@
    5.16          public bool NeverUnsecure { get; set; } = false;
    5.17  
    5.18          /// <summary>
    5.19 +        /// The privacy state of this form region.
    5.20 +        /// </summary>
    5.21 +        public PrivacyState PrivacyState { get; private set; } = new PrivacyState();
    5.22 +
    5.23 +        /// <summary>
    5.24          /// Gets the rating of this message.
    5.25          /// </summary>
    5.26 -        public pEpRating Rating
    5.27 -        {
    5.28 -            get { return this._Rating; }
    5.29 -        }
    5.30 +        public pEpRating Rating { get; private set; } = pEpRating.pEpRatingUndefined;
    5.31  
    5.32          /// <summary>
    5.33          /// Sets the rating of this message and updates the UI.
    5.34 @@ -160,8 +157,27 @@
    5.35          /// <param name="rating">The message rating.</param>
    5.36          public void SetRating(pEpRating rating)
    5.37          {
    5.38 -            this._Rating = rating;
    5.39 -            RibbonCustomizations.Invalidate();
    5.40 +            this.Rating = rating;
    5.41 +            this.UpdatePrivacyStateAndUI();
    5.42 +        }
    5.43 +
    5.44 +        /// <summary>
    5.45 +        /// Updates the privacy state and the UI (ribbon and form region).
    5.46 +        /// </summary>
    5.47 +        public void UpdatePrivacyStateAndUI()
    5.48 +        {
    5.49 +            try
    5.50 +            {
    5.51 +                this.PrivacyState = new PrivacyState(this.Rating,
    5.52 +                                                     this.ForceProtection,
    5.53 +                                                     this.ForceUnencrypted);
    5.54 +                RibbonCustomizations.Invalidate();
    5.55 +                ((this.Controls[0].Controls[0] as System.Windows.Forms.Integration.ElementHost).Child as UserControlPrivacyStatus)?.Update(this.PrivacyState);
    5.56 +            }
    5.57 +            catch (Exception ex)
    5.58 +            {
    5.59 +                Log.Error("UpdateUI: Error occured. " + ex.ToString());
    5.60 +            }
    5.61          }
    5.62  
    5.63          /**************************************************************
    5.64 @@ -715,7 +731,7 @@
    5.65              PEPCache.CacheItem cacheItem = null;
    5.66  
    5.67              // Do not show the form region
    5.68 -            this.OutlookFormRegion.Visible = false;
    5.69 +            this.OutlookFormRegion.Visible = true;
    5.70  
    5.71              // Set mail item
    5.72              omi = this.OutlookItem as Outlook.MailItem;
    5.73 @@ -1572,7 +1588,7 @@
    5.74                          // Refresh the UI
    5.75                          this.ResolveAllRecipients();
    5.76                          this.RequestRatingAndUIUpdate();
    5.77 -                        RibbonCustomizations.Invalidate();
    5.78 +                        this.UpdatePrivacyStateAndUI();
    5.79  
    5.80                          break;
    5.81                      }
     6.1 --- a/UI/PrivacyState.cs	Wed Oct 17 08:04:35 2018 +0200
     6.2 +++ b/UI/PrivacyState.cs	Thu Oct 18 12:27:44 2018 +0200
     6.3 @@ -1,6 +1,7 @@
     6.4  using pEpCOMServerAdapterLib;
     6.5 -using System.Collections.Generic;
     6.6 +using System;
     6.7  using System.Windows.Media;
     6.8 +using System.Windows.Media.Imaging;
     6.9  
    6.10  namespace pEp
    6.11  {
    6.12 @@ -10,16 +11,15 @@
    6.13      /// </summary>
    6.14      internal class PrivacyState : Interfaces.ICopy<PrivacyState>
    6.15      {
    6.16 -        private Brush     _Background;
    6.17 -        private Brush     _BackgroundClick;
    6.18 -        private Brush     _BackgroundMouseOver;
    6.19 -        private pEpColor  _Color;
    6.20 -        private string    _Explanation;
    6.21 -        private Brush     _Foreground;
    6.22 -        private pEpRating _Rating;
    6.23 -        private string    _ShortText;
    6.24 -        private string    _SuggestionIncoming;
    6.25 -        private string    _SuggestionOutgoing;
    6.26 +        // Load image resources for WPF
    6.27 +        private static readonly BitmapImage imageLogoBlack                                      = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageLogoBlack.png", UriKind.RelativeOrAbsolute));
    6.28 +        private static readonly BitmapImage imageLogoWhite                                      = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageLogoWhite.png", UriKind.RelativeOrAbsolute));
    6.29 +        private static readonly BitmapImage imagePrivacyStatusGreenInvert                       = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusGreenInvert.png", UriKind.RelativeOrAbsolute));
    6.30 +        private static readonly BitmapImage imagePrivacyStatusGreenProtectionDisabledInvert     = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusGreenProtectionDisabledInvert.png", UriKind.RelativeOrAbsolute));
    6.31 +        private static readonly BitmapImage imagePrivacyStatusNoColorInvert                     = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusNoColorInvert.png", UriKind.RelativeOrAbsolute));
    6.32 +        private static readonly BitmapImage imagePrivacyStatusRedInvert                         = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusRedInvert.png", UriKind.RelativeOrAbsolute));
    6.33 +        private static readonly BitmapImage imagePrivacyStatusYellowInvert                      = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusYellowInvert.png", UriKind.RelativeOrAbsolute));
    6.34 +        private static readonly BitmapImage imagePrivacyStatusYellowProtectionDisabledInvert    = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusYellowProtectionDisabledInvert.png", UriKind.RelativeOrAbsolute));
    6.35  
    6.36          /**************************************************************
    6.37           * 
    6.38 @@ -29,181 +29,130 @@
    6.39  
    6.40          /// <summary>
    6.41          /// Default constructor.
    6.42 -        /// This constructor is not recommended to use.
    6.43          /// </summary>
    6.44 -        public PrivacyState()
    6.45 +        public PrivacyState() : this(pEpRating.pEpRatingUndefined)
    6.46          {
    6.47 -            this._Rating = pEpRating.pEpRatingUndefined;
    6.48 -
    6.49 -            this._Background = (Brush)Globals.ResourceDict["BrushGray"];
    6.50 -            this._BackgroundClick = (Brush)Globals.ResourceDict["BrushGrayClick"];
    6.51 -            this._BackgroundMouseOver = (Brush)Globals.ResourceDict["BrushGrayHover"];
    6.52 -            this._Color = this._Rating.ToColor();
    6.53 -            this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedExplanation;
    6.54 -            this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
    6.55 -            this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedText;
    6.56 -            this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedSuggestionIncoming;
    6.57 -            this._SuggestionOutgoing = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedSuggestionOutgoing;
    6.58          }
    6.59  
    6.60          /// <summary>
    6.61 -        /// Default constructor with arguments.
    6.62 -        /// This constructor always should be used.
    6.63 +        /// Primary constructor to create a new Privacy State.
    6.64          /// </summary>
    6.65 -        /// <param name="rating">The privacy status rating.</param>
    6.66 -        public PrivacyState(pEpRating rating)
    6.67 +        /// <param name="rating">The rating of the message.</param>
    6.68 +        /// <param name="forceProtection">If the message should be forcefully encrypted.</param>
    6.69 +        /// <param name="forceUnencrypted">If the message should be forcefully unencrypted.</param>
    6.70 +        public PrivacyState(pEpRating rating,
    6.71 +                            bool forceProtection = false,
    6.72 +                            bool forceUnencrypted = false)
    6.73          {
    6.74 -            Brush backBrush;
    6.75 -            Brush backBrushClick;
    6.76 -            Brush backBrushMouseOver;
    6.77 +            // Set properties passed as arguments
    6.78 +            this.ForceProtection = forceProtection;
    6.79 +            this.ForceUnencrypted = forceUnencrypted;
    6.80 +            this.Rating = rating;
    6.81  
    6.82 -            this._Rating = rating;
    6.83 -            this._Color = this._Rating.ToColor();
    6.84 +            // Calculate color from rating
    6.85 +            pEpColor color = PrivacyState.RatingToColor(rating);
    6.86  
    6.87 -            // Get background colors
    6.88 -            PrivacyState.RatingToBrushes(this._Rating,
    6.89 -                                         out backBrush,
    6.90 -                                         out backBrushClick,
    6.91 -                                         out backBrushMouseOver);
    6.92 +            // Check if force protection
    6.93 +            if ((color == pEpColor.pEpColorNoColor) &&
    6.94 +                (this.ForceProtection))
    6.95 +            {
    6.96 +                color = pEpColor.pEpColorYellow;
    6.97 +            }
    6.98  
    6.99 -            // Updates any properties dependent on the privacy status.
   6.100 -            switch (this._Rating)
   6.101 +            // Set colors and icons
   6.102 +            this.SetColorsAndIcons(color, this.ForceUnencrypted);
   6.103 +
   6.104 +            // Set labels and tooltip
   6.105 +            switch (this.Rating)
   6.106              {
   6.107                  case pEpRating.pEpRatingUnderAttack:
   6.108                      {
   6.109 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUnderAttackText;
   6.110 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUnderAttackExplanation;
   6.111 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUnderAttackSuggestion;
   6.112 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.113 -                        this._Background = backBrush;
   6.114 -                        this._BackgroundClick = backBrushClick;
   6.115 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.116 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.117 -                        break;
   6.118 +                        this.Label = Properties.Resources.PrivacyStatus_RatingUnderAttackText;
   6.119 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnderAttackExplanation;
   6.120                      }
   6.121 +                    break;
   6.122                  case pEpRating.pEpRatingMistrust:
   6.123                      {
   6.124 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingMistrustText;
   6.125 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingMistrustExplanation;
   6.126 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingMistrustSuggestion;
   6.127 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.128 -                        this._Background = backBrush;
   6.129 -                        this._BackgroundClick = backBrushClick;
   6.130 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.131 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.132 -                        break;
   6.133 +                        this.Label = Properties.Resources.PrivacyStatus_RatingMistrustText;
   6.134 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingMistrustExplanation;
   6.135                      }
   6.136 -                case pEpRating.pEpRatingUndefined:
   6.137 -                    {
   6.138 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedText;
   6.139 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedExplanation;
   6.140 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedSuggestionIncoming;
   6.141 -                        this._SuggestionOutgoing = pEp.Properties.Resources.PrivacyStatus_RatingUndefinedSuggestionOutgoing;
   6.142 -                        this._Background = backBrush;
   6.143 -                        this._BackgroundClick = backBrushClick;
   6.144 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.145 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.146 -                        break;
   6.147 -                    }
   6.148 +                    break;
   6.149                  case pEpRating.pEpRatingCannotDecrypt:
   6.150                  case pEpRating.pEpRatingHaveNoKey:
   6.151                      {
   6.152 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingHaveNoKeyText;
   6.153 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingHaveNoKeyExplanation;
   6.154 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingHaveNoKeySuggestionIncoming;
   6.155 -                        this._SuggestionOutgoing = pEp.Properties.Resources.PrivacyStatus_RatingHaveNoKeySuggestionOutgoing;
   6.156 -                        this._Background = backBrush;
   6.157 -                        this._BackgroundClick = backBrushClick;
   6.158 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.159 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.160 -                        break;
   6.161 +                        this.Label = Properties.Resources.PrivacyStatus_RatingHaveNoKeyText;
   6.162 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingHaveNoKeyExplanation;
   6.163                      }
   6.164 +                    break;
   6.165                  case pEpRating.pEpRatingUnencrypted:
   6.166                      {
   6.167 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   6.168 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedExplanation;
   6.169 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedSuggestion;
   6.170 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.171 -                        this._Background = backBrush;
   6.172 -                        this._BackgroundClick = backBrushClick;
   6.173 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.174 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.175 -                        break;
   6.176 +                        if (this.ForceProtection)
   6.177 +                        {
   6.178 +                            this.Label = Properties.Resources.PrivacyStatus_RatingReliableText;
   6.179 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingReliableExplanation;
   6.180 +                        }
   6.181 +                        else
   6.182 +                        {
   6.183 +                            this.Label = Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   6.184 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnencryptedExplanation;
   6.185 +                        }
   6.186                      }
   6.187 +                    break;
   6.188                  case pEpRating.pEpRatingUnencryptedForSome:
   6.189                      {
   6.190 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeText;
   6.191 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeExplanation;
   6.192 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeSuggestion;
   6.193 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.194 -                        this._Background = backBrush;
   6.195 -                        this._BackgroundClick = backBrushClick;
   6.196 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.197 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.198 -                        break;
   6.199 +                        this.Label = Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeText;
   6.200 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeExplanation;
   6.201                      }
   6.202 +                    break;
   6.203                  case pEpRating.pEpRatingUnreliable:
   6.204                      {
   6.205 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingUnreliableText;
   6.206 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingUnreliableExplanation;
   6.207 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingUnreliableSuggestion;
   6.208 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.209 -                        this._Background = backBrush;
   6.210 -                        this._BackgroundClick = backBrushClick;
   6.211 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.212 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.213 -                        break;
   6.214 +                        this.Label = Properties.Resources.PrivacyStatus_RatingUnreliableText;
   6.215 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnreliableExplanation;
   6.216                      }
   6.217 +                    break;
   6.218                  case pEpRating.pEpRatingReliable:
   6.219                      {
   6.220 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingReliableText;
   6.221 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingReliableExplanation;
   6.222 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingReliableSuggestion;
   6.223 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.224 -                        this._Background = backBrush;
   6.225 -                        this._BackgroundClick = backBrushClick;
   6.226 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.227 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.228 -                        break;
   6.229 +                        if (this.ForceUnencrypted)
   6.230 +                        {
   6.231 +                            this.Label = Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   6.232 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnencryptedExplanation;
   6.233 +                        }
   6.234 +                        else
   6.235 +                        {
   6.236 +                            this.Label = Properties.Resources.PrivacyStatus_RatingReliableText;
   6.237 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingReliableExplanation;
   6.238 +                        }
   6.239                      }
   6.240 +                    break;
   6.241                  case pEpRating.pEpRatingTrusted:
   6.242                  case pEpRating.pEpRatingTrustedAndAnonymized:
   6.243                  case pEpRating.pEpRatingFullyAnonymous:
   6.244                      {
   6.245 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingTrustedText;
   6.246 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingTrustedExplanation;
   6.247 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingTrustedSuggestion;
   6.248 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.249 -                        this._Background = backBrush;
   6.250 -                        this._BackgroundClick = backBrushClick;
   6.251 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.252 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.253 -                        break;
   6.254 +                        if (this.ForceUnencrypted)
   6.255 +                        {
   6.256 +                            this.Label = Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   6.257 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingUnencryptedExplanation;
   6.258 +                        }
   6.259 +                        else
   6.260 +                        {
   6.261 +                            this.Label = Properties.Resources.PrivacyStatus_RatingTrustedText;
   6.262 +                            this.Tooltip = Properties.Resources.PrivacyStatus_RatingTrustedExplanation;
   6.263 +                        }
   6.264                      }
   6.265 +                    break;
   6.266                  case pEpRating.pEpRatingB0rken:
   6.267                      {
   6.268 -                        this._ShortText = pEp.Properties.Resources.PrivacyStatus_RatingBrokenText;
   6.269 -                        this._Explanation = pEp.Properties.Resources.PrivacyStatus_RatingBrokenExplanation;
   6.270 -                        this._SuggestionIncoming = pEp.Properties.Resources.PrivacyStatus_RatingBrokenSuggestion;
   6.271 -                        this._SuggestionOutgoing = this._SuggestionIncoming;
   6.272 -                        this._Background = backBrush;
   6.273 -                        this._BackgroundClick = backBrushClick;
   6.274 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.275 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.276 -                        break;
   6.277 +                        this.Label = Properties.Resources.PrivacyStatus_RatingBrokenText;
   6.278 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingBrokenExplanation;
   6.279                      }
   6.280 -                default: // Should not get here
   6.281 +                    break;
   6.282 +                case pEpRating.pEpRatingUndefined:
   6.283 +                default:
   6.284                      {
   6.285 -                        this._ShortText = "";
   6.286 -                        this._Explanation = "";
   6.287 -                        this._SuggestionIncoming = "";
   6.288 -                        this._SuggestionOutgoing = "";
   6.289 -                        this._Background = backBrush;
   6.290 -                        this._BackgroundClick = backBrushClick;
   6.291 -                        this._BackgroundMouseOver = backBrushMouseOver;
   6.292 -                        this._Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.293 -                        break;
   6.294 +                        this.Label = Properties.Resources.PrivacyStatus_RatingUndefinedText;
   6.295 +                        this.Tooltip = Properties.Resources.PrivacyStatus_RatingUndefinedExplanation;
   6.296                      }
   6.297 +                    break;
   6.298              }
   6.299          }
   6.300  
   6.301 @@ -214,92 +163,54 @@
   6.302           *************************************************************/
   6.303  
   6.304          /// <summary>
   6.305 -        /// Gets the background brush corresponding to the set rating.
   6.306 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.307 +        /// Gets the background brush corresponding to the rating.
   6.308          /// </summary>
   6.309 -        public Brush Background
   6.310 -        {
   6.311 -            get { return (this._Background); }
   6.312 -        }
   6.313 +        public Brush Background { get; private set; }
   6.314  
   6.315          /// <summary>
   6.316 -        /// Gets the 'click' background brush corresponding to the set rating.
   6.317 -        /// This is a specific color for when a cursor is clicked.
   6.318 +        /// Gets or sets whether to send the message forcefully protected.
   6.319          /// </summary>
   6.320 -        public Brush BackgroundClick
   6.321 -        {
   6.322 -            get { return (this._BackgroundClick); }
   6.323 -        }
   6.324 +        public bool ForceProtection { get; private set; } = false;
   6.325  
   6.326          /// <summary>
   6.327 -        /// Gets the 'mouse over' background brush corresponding to the set rating.
   6.328 -        /// This is a specific color for when a cursor is over.
   6.329 +        /// Gets or sets whether to send this message forcefully unencrypted.
   6.330          /// </summary>
   6.331 -        public Brush BackgroundMouseOver
   6.332 -        {
   6.333 -            get { return (this._BackgroundMouseOver); }
   6.334 -        }
   6.335 +        public bool ForceUnencrypted { get; private set; } = false;
   6.336  
   6.337          /// <summary>
   6.338 -        /// Gets the pEp color corresponding to the pEp rating.
   6.339 +        /// Gets the foreround brush corresponding to the rating.
   6.340          /// </summary>
   6.341 -        public pEpColor Color
   6.342 -        {
   6.343 -            get { return (this._Color); }
   6.344 -        }
   6.345 +        public Brush Foreground { get; private set; }
   6.346  
   6.347          /// <summary>
   6.348 -        /// Gets the explanation for the privacy status.
   6.349 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.350 +        /// Gets the image corresponding to the rating.
   6.351          /// </summary>
   6.352 -        public string Explanation
   6.353 -        {
   6.354 -            get { return (this._Explanation); }
   6.355 -        }
   6.356 +        public System.Drawing.Bitmap Image { get; private set; }
   6.357  
   6.358          /// <summary>
   6.359 -        /// Gets the foreground brush corresponding to set rating..
   6.360 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.361 +        /// Gets the inverted image corresponding to the rating.
   6.362          /// </summary>
   6.363 -        public Brush Foreground
   6.364 -        {
   6.365 -            get { return (this._Foreground); }
   6.366 -        }
   6.367 +        public ImageSource ImageInvert { get; private set; }
   6.368 +
   6.369 +        /// <summary>
   6.370 +        /// Gets the caption corresponding to the rating.
   6.371 +        /// </summary>
   6.372 +        public string Label { get; private set; }
   6.373 +
   6.374 +        /// <summary>
   6.375 +        /// Gets the logo corresponding to the rating.
   6.376 +        /// </summary>
   6.377 +        public ImageSource Logo { get; private set; }
   6.378  
   6.379          /// <summary>
   6.380          /// Gets the pEp rating of the state.
   6.381          /// </summary>
   6.382 -        public pEpRating Rating
   6.383 -        {
   6.384 -            get { return (this._Rating); }
   6.385 -        }
   6.386 +        public pEpRating Rating { get; private set; }
   6.387  
   6.388          /// <summary>
   6.389 -        /// Gets the short-text of the privacy status.
   6.390 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.391 +        /// Gets the tool tip corresponding to the rating.
   6.392          /// </summary>
   6.393 -        public string ShortText
   6.394 -        {
   6.395 -            get { return (this._ShortText); }
   6.396 -        }
   6.397 -
   6.398 -        /// <summary>
   6.399 -        /// Gets the suggestion to improve the privacy status for incoming messages.
   6.400 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.401 -        /// </summary>
   6.402 -        public string SuggestionIncoming
   6.403 -        {
   6.404 -            get { return (this._SuggestionIncoming); }
   6.405 -        }
   6.406 -
   6.407 -        /// <summary>
   6.408 -        /// Gets the suggestion to improve the privacy status for outgoing messages.
   6.409 -        /// This is dependent on PrivacyStatus and therefore automatically set.
   6.410 -        /// </summary>
   6.411 -        public string SuggestionOutgoing
   6.412 -        {
   6.413 -            get { return (this._SuggestionOutgoing); }
   6.414 -        }
   6.415 +        public string Tooltip { get; private set; }
   6.416  
   6.417          /**************************************************************
   6.418           * 
   6.419 @@ -313,7 +224,78 @@
   6.420          /// <returns>The deep copy of the object.</returns>
   6.421          public PrivacyState Copy()
   6.422          {
   6.423 -            return (new PrivacyState(this._Rating));
   6.424 +            return (new PrivacyState(this.Rating));
   6.425 +        }
   6.426 +
   6.427 +        /// <summary>
   6.428 +        /// Sets colors and icons for a given Privacy State.
   6.429 +        /// </summary>
   6.430 +        /// <param name="color">The color of the state.</param>
   6.431 +        /// <param name="forceUnencrypted">Whether the message is supposed to get sent forcefully unencrypted.</param>
   6.432 +        private void SetColorsAndIcons(pEpColor color, bool forceUnencrypted = false)
   6.433 +        {
   6.434 +            switch (color)
   6.435 +            {
   6.436 +                case pEpColor.pEpColorYellow:
   6.437 +                    {
   6.438 +                        if (forceUnencrypted)
   6.439 +                        {
   6.440 +                            this.Background = (Brush)Globals.ResourceDict["BrushGray"];
   6.441 +                            this.Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.442 +                            this.Image = Properties.Resources.ImagePrivacyStatusYellowProtectionDisabled;
   6.443 +                            this.ImageInvert = PrivacyState.imagePrivacyStatusYellowProtectionDisabledInvert;
   6.444 +                            this.Logo = PrivacyState.imageLogoWhite;
   6.445 +                        }
   6.446 +                        else
   6.447 +                        {
   6.448 +                            this.Background = (Brush)Globals.ResourceDict["BrushYellow"];
   6.449 +                            this.Foreground = (Brush)Globals.ResourceDict["BrushTextBlack"];
   6.450 +                            this.Image = Properties.Resources.ImagePrivacyStatusYellow;
   6.451 +                            this.ImageInvert = PrivacyState.imagePrivacyStatusYellowInvert;
   6.452 +                            this.Logo = PrivacyState.imageLogoBlack;
   6.453 +                        }
   6.454 +                    }
   6.455 +                    break;
   6.456 +                case pEpColor.pEpColorGreen:
   6.457 +                    {
   6.458 +                        if (forceUnencrypted)
   6.459 +                        {
   6.460 +                            this.Background = (Brush)Globals.ResourceDict["BrushGray"];
   6.461 +                            this.Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.462 +                            this.Image = Properties.Resources.ImagePrivacyStatusGreenProtectionDisabled;
   6.463 +                            this.ImageInvert = PrivacyState.imagePrivacyStatusGreenProtectionDisabledInvert;
   6.464 +                            this.Logo = PrivacyState.imageLogoWhite;
   6.465 +                        }
   6.466 +                        else
   6.467 +                        {
   6.468 +                            this.Background = (Brush)Globals.ResourceDict["BrushGreen"];
   6.469 +                            this.Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.470 +                            this.Image = Properties.Resources.ImagePrivacyStatusGreen;
   6.471 +                            this.ImageInvert = PrivacyState.imagePrivacyStatusGreenInvert;
   6.472 +                            this.Logo = PrivacyState.imageLogoWhite;
   6.473 +                        }
   6.474 +                    }
   6.475 +                    break;
   6.476 +                case pEpColor.pEpColorRed:
   6.477 +                    {
   6.478 +                        this.Background = (Brush)Globals.ResourceDict["BrushRed"];
   6.479 +                        this.Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.480 +                        this.Image = Properties.Resources.ImagePrivacyStatusRed;
   6.481 +                        this.ImageInvert = PrivacyState.imagePrivacyStatusRedInvert;
   6.482 +                        this.Logo = PrivacyState.imageLogoWhite;
   6.483 +                    }
   6.484 +                    break;
   6.485 +                case pEpColor.pEpColorNoColor:
   6.486 +                default:
   6.487 +                    {
   6.488 +                        this.Background = (Brush)Globals.ResourceDict["BrushGray"];
   6.489 +                        this.Foreground = (Brush)Globals.ResourceDict["BrushTextWhite"];
   6.490 +                        this.Image = Properties.Resources.ImagePrivacyStatusNoColor;
   6.491 +                        this.ImageInvert = PrivacyState.imagePrivacyStatusNoColorInvert;
   6.492 +                        this.Logo = PrivacyState.imageLogoWhite;
   6.493 +                    }
   6.494 +                    break;
   6.495 +            }
   6.496          }
   6.497  
   6.498          /**************************************************************
   6.499 @@ -323,106 +305,41 @@
   6.500           *************************************************************/
   6.501  
   6.502          /// <summary>
   6.503 -        /// Converts the given privacy color to a brush for display in the UI.
   6.504 +        /// 
   6.505          /// </summary>
   6.506 -        /// <param name="privacyColor">The privacy color to convert.</param>
   6.507 -        /// <returns>The brush associated with the given privacy color.</returns>
   6.508 -        public static Brush ColorToBrush(pEpColor privacyColor)
   6.509 +        /// <param name="rating"></param>
   6.510 +        /// <returns></returns>
   6.511 +        private static pEpColor RatingToColor(pEpRating rating)
   6.512          {
   6.513 -            switch (privacyColor)
   6.514 +            switch (rating)
   6.515              {
   6.516 -                case pEpColor.pEpColorNoColor:
   6.517 -                    return (Brush)Globals.ResourceDict["BrushGray"];
   6.518 -                case pEpColor.pEpColorRed:
   6.519 -                    return (Brush)Globals.ResourceDict["BrushRed"];
   6.520 -                case pEpColor.pEpColorYellow:
   6.521 -                    return (Brush)Globals.ResourceDict["BrushYellow"];
   6.522 -                case pEpColor.pEpColorGreen:
   6.523 -                    return (Brush)Globals.ResourceDict["BrushGreen"];
   6.524 +                case pEpRating.pEpRatingReliable:
   6.525 +                    {
   6.526 +                        return pEpColor.pEpColorYellow;
   6.527 +                    }
   6.528 +                case pEpRating.pEpRatingTrusted:
   6.529 +                case pEpRating.pEpRatingTrustedAndAnonymized:
   6.530 +                case pEpRating.pEpRatingFullyAnonymous:
   6.531 +                    {
   6.532 +                        return pEpColor.pEpColorGreen;
   6.533 +                    }
   6.534 +                case pEpRating.pEpRatingMistrust:
   6.535 +                case pEpRating.pEpRatingB0rken:
   6.536 +                case pEpRating.pEpRatingUnderAttack:
   6.537 +                    {
   6.538 +                        return pEpColor.pEpColorRed;
   6.539 +                    }
   6.540 +                case pEpRating.pEpRatingUndefined:
   6.541 +                case pEpRating.pEpRatingCannotDecrypt:
   6.542 +                case pEpRating.pEpRatingHaveNoKey:
   6.543 +                case pEpRating.pEpRatingUnencrypted:
   6.544 +                case pEpRating.pEpRatingUnencryptedForSome:
   6.545 +                case pEpRating.pEpRatingUnreliable:
   6.546                  default:
   6.547 -                    return (Brush)Globals.ResourceDict["BrushGray"];
   6.548 +                    {
   6.549 +                        return pEpColor.pEpColorNoColor;
   6.550 +                    }
   6.551              }
   6.552          }
   6.553 -
   6.554 -        /// <summary>
   6.555 -        /// Converts the given privacy color to a brush for display in the UI.
   6.556 -        /// </summary>
   6.557 -        /// <param name="privacyColor">The privacy color to convert.</param>
   6.558 -        /// <param name="color">The standard brush associated with the given privacy color.</param>
   6.559 -        /// <param name="brushClick">The 'clicked' brush associated with the given privacy color when clicked.</param>
   6.560 -        /// <param name="brushMouseOver">The 'mouse over' brush associated with the given privacy color when the mouse is over.</param>
   6.561 -        public static void ColorToBrushes(pEpColor privacyColor,
   6.562 -                                          out Brush brush,
   6.563 -                                          out Brush brushClick,
   6.564 -                                          out Brush brushMouseOver)
   6.565 -        {
   6.566 -
   6.567 -            switch (privacyColor)
   6.568 -            {
   6.569 -                case pEpColor.pEpColorNoColor:
   6.570 -                    brush = (Brush)Globals.ResourceDict["BrushGray"];
   6.571 -                    brushClick = (Brush)Globals.ResourceDict["BrushGrayClick"];
   6.572 -                    brushMouseOver = (Brush)Globals.ResourceDict["BrushGrayHover"];
   6.573 -                    return;
   6.574 -                case pEpColor.pEpColorRed:
   6.575 -                    brush = (Brush)Globals.ResourceDict["BrushRed"];
   6.576 -                    brushClick = (Brush)Globals.ResourceDict["BrushRedClick"];
   6.577 -                    brushMouseOver = (Brush)Globals.ResourceDict["BrushRedHover"];
   6.578 -                    return;
   6.579 -                case pEpColor.pEpColorYellow:
   6.580 -                    brush = (Brush)Globals.ResourceDict["BrushYellow"];
   6.581 -                    brushClick = (Brush)Globals.ResourceDict["BrushYellowClick"];
   6.582 -                    brushMouseOver = (Brush)Globals.ResourceDict["BrushYellowHover"];
   6.583 -                    return;
   6.584 -                case pEpColor.pEpColorGreen:
   6.585 -                    brush = (Brush)Globals.ResourceDict["BrushGreen"];
   6.586 -                    brushClick = (Brush)Globals.ResourceDict["BrushGreenClick"];
   6.587 -                    brushMouseOver = (Brush)Globals.ResourceDict["BrushGreenHover"];
   6.588 -                    return;
   6.589 -                default:
   6.590 -                    brush = (Brush)Globals.ResourceDict["BrushGray"];
   6.591 -                    brushClick = (Brush)Globals.ResourceDict["BrushGrayClick"];
   6.592 -                    brushMouseOver = (Brush)Globals.ResourceDict["BrushGrayHover"];
   6.593 -                    return;
   6.594 -            }
   6.595 -        }
   6.596 -
   6.597 -        /// <summary>
   6.598 -        /// Converts the given pEp rating to a brush for display in the UI.
   6.599 -        /// </summary>
   6.600 -        /// <param name="rating">The pEp rating to convert.</param>
   6.601 -        /// <returns>The brush associated with the given rating.</returns>
   6.602 -        public static Brush RatingToBrush(pEpRating rating)
   6.603 -        {
   6.604 -            return ColorToBrush(rating.ToColor());
   6.605 -        }
   6.606 -
   6.607 -        /// <summary>
   6.608 -        /// Converts the given pEp rating to brushes for display in the UI.
   6.609 -        /// </summary>
   6.610 -        /// <param name="rating">The pEp rating to convert.</param>
   6.611 -        /// <param name="color">The standard brush associated with the given privacy color.</param>
   6.612 -        /// <param name="brushClick">The 'clicked' brush associated with the given privacy color when clicked.</param>
   6.613 -        /// <param name="brushMouseOver">The 'mouse over' brush associated with the given privacy color when the mouse is over.</param>
   6.614 -        public static void RatingToBrushes(pEpRating rating,
   6.615 -                                           out Brush brush,
   6.616 -                                           out Brush brushClick,
   6.617 -                                           out Brush brushMouseOver)
   6.618 -        {
   6.619 -            Brush backBrush;
   6.620 -            Brush backBrushClick;
   6.621 -            Brush backBrushMouseOver;
   6.622 -
   6.623 -            ColorToBrushes(rating.ToColor(),
   6.624 -                           out backBrush,
   6.625 -                           out backBrushClick,
   6.626 -                           out backBrushMouseOver);
   6.627 -
   6.628 -            brush = backBrush;
   6.629 -            brushClick = backBrushClick;
   6.630 -            brushMouseOver = backBrushMouseOver;
   6.631 -
   6.632 -            return;
   6.633 -        }
   6.634      }
   6.635  }
     7.1 --- a/UI/PrivacyView.xaml	Wed Oct 17 08:04:35 2018 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,104 +0,0 @@
     7.4 -<UserControl x:Class="pEp.UI.PrivacyView"
     7.5 -             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     7.6 -             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     7.7 -             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     7.8 -             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     7.9 -             xmlns:local="clr-namespace:pEp.UI"
    7.10 -             mc:Ignorable="d"
    7.11 -             MinHeight="28"
    7.12 -             MinWidth="140"
    7.13 -             d:DesignHeight="28"
    7.14 -             d:DesignWidth="140">
    7.15 -    <UserControl.Resources>
    7.16 -        <ResourceDictionary>
    7.17 -            <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    7.18 -            <ResourceDictionary.MergedDictionaries>
    7.19 -                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Dictionary.xaml" />
    7.20 -            </ResourceDictionary.MergedDictionaries>
    7.21 -        </ResourceDictionary>
    7.22 -    </UserControl.Resources>
    7.23 -    <Grid>
    7.24 -        <Border Name="BorderLayoutRoot"
    7.25 -                Background="{Binding Path=DisplayState.Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.26 -                HorizontalAlignment="Stretch"
    7.27 -                VerticalAlignment="Stretch"
    7.28 -                BorderBrush="Black"
    7.29 -                BorderThickness="1"
    7.30 -                Padding="{StaticResource ButtonPaddingStandard}">
    7.31 -            <Grid>
    7.32 -                <Grid.ColumnDefinitions>
    7.33 -                    <ColumnDefinition Width="auto" />
    7.34 -                    <ColumnDefinition Width="*" />
    7.35 -                </Grid.ColumnDefinitions>
    7.36 -                <Image Grid.Column="0"
    7.37 -                       Stretch="Uniform"
    7.38 -                       VerticalAlignment="Stretch"
    7.39 -                       Margin="0,0,5,0"
    7.40 -                       Visibility="{Binding Path=DisplayState.IsInIndicatorMode, Converter={StaticResource BoolToVisibility}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}, FallbackValue=Collapsed}">
    7.41 -                    <Image.Style>
    7.42 -                        <Style TargetType="Image">
    7.43 -                            <Style.Triggers>
    7.44 -                                <DataTrigger Binding="{Binding Path='DisplayState.Color', RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.45 -                                             Value="pEpColorGreen">
    7.46 -                                    <Setter Property="Source"
    7.47 -                                            Value="pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusGreenInvert.png" />
    7.48 -                                </DataTrigger>
    7.49 -                                <DataTrigger Binding="{Binding Path='DisplayState.Color', RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.50 -                                             Value="pEpColorNoColor">
    7.51 -                                    <Setter Property="Source"
    7.52 -                                            Value="pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusNoColorInvert.png" />
    7.53 -                                </DataTrigger>
    7.54 -                                <DataTrigger Binding="{Binding Path='DisplayState.Color', RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.55 -                                             Value="pEpColorRed">
    7.56 -                                    <Setter Property="Source"
    7.57 -                                            Value="pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusRedInvert.png" />
    7.58 -                                </DataTrigger>
    7.59 -                                <DataTrigger Binding="{Binding Path='DisplayState.Color', RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.60 -                                             Value="pEpColorYellow">
    7.61 -                                    <Setter Property="Source"
    7.62 -                                            Value="pack://application:,,,/pEp;component/Resources/ImagePrivacyStatusYellowInvert.png" />
    7.63 -                                </DataTrigger>
    7.64 -                            </Style.Triggers>
    7.65 -                        </Style>
    7.66 -                    </Image.Style>
    7.67 -                </Image>
    7.68 -                <TextBlock Grid.Column="1"
    7.69 -                           Foreground="{Binding Path=DisplayState.Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.70 -                           Text="{Binding Path=DisplayState.Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}"
    7.71 -                           TextAlignment="Center"
    7.72 -                           HorizontalAlignment="Center"
    7.73 -                           VerticalAlignment="Center"
    7.74 -                           FontFamily="Arial"
    7.75 -                           FontSize="13" />
    7.76 -            </Grid>
    7.77 -        </Border>
    7.78 -        <Grid Name="GridHitTarget"
    7.79 -              Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:PrivacyView}}}">
    7.80 -            <!--
    7.81 -                Note: A tooltip is not part of the visual tree we are using here.
    7.82 -                This means any RelativeSource in binding will not work correctly.
    7.83 -                As a work around, the Tag in the 'PlacementTarget' is used to store the reference to the PrivacyView.
    7.84 -                This is then relayed to the ToolTip itself where the tooltip can then use bindings to the PrivacyView state.
    7.85 -                A downside is this is setting the DataContext. But that shouldn't be an issue as this never needs to be used 
    7.86 -                outside this control.
    7.87 -            -->
    7.88 -            <Grid.ToolTip>
    7.89 -                <ToolTip DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
    7.90 -                         Visibility="{Binding Path=DisplayState.ToolTipIsVisible, Converter={StaticResource BoolToVisibility}, FallbackValue=Collapsed}">
    7.91 -                    <TextBlock Text="{Binding Path=DisplayState.ToolTip}" />
    7.92 -                </ToolTip>
    7.93 -            </Grid.ToolTip>
    7.94 -            <Grid.Background>
    7.95 -                <SolidColorBrush>
    7.96 -                    <SolidColorBrush.Color>
    7.97 -                        <!-- Not fully transparent to catch mouse events -->
    7.98 -                        <Color A="1"
    7.99 -                               R="255"
   7.100 -                               G="255"
   7.101 -                               B="255" />
   7.102 -                    </SolidColorBrush.Color>
   7.103 -                </SolidColorBrush>
   7.104 -            </Grid.Background>
   7.105 -        </Grid>
   7.106 -    </Grid>
   7.107 -</UserControl>
     8.1 --- a/UI/PrivacyView.xaml.cs	Wed Oct 17 08:04:35 2018 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,516 +0,0 @@
     8.4 -using pEpCOMServerAdapterLib;
     8.5 -using System.ComponentModel;
     8.6 -using System.Windows;
     8.7 -using System.Windows.Controls;
     8.8 -using System.Windows.Media;
     8.9 -
    8.10 -namespace pEp.UI
    8.11 -{
    8.12 -    /// <summary>
    8.13 -    /// Interaction logic for PrivacyView.xaml
    8.14 -    /// </summary>
    8.15 -    public partial class PrivacyView : UserControl
    8.16 -    {
    8.17 -        public delegate void ClickedDelegate(object sender, RoutedEventArgs e);
    8.18 -
    8.19 -        /// <summary>
    8.20 -        /// Event for when the control is clicked when in button mode.
    8.21 -        /// </summary>
    8.22 -        public event ClickedDelegate Click;
    8.23 -
    8.24 -        public static readonly DependencyProperty RatingProperty = DependencyProperty.Register("Rating",
    8.25 -                                                                                               typeof(pEpRating),
    8.26 -                                                                                               typeof(PrivacyView),
    8.27 -                                                                                               new PropertyMetadata(propertyChangedCallback: DPRatingChangedCallback));
    8.28 -        public static readonly DependencyProperty ModeProperty   = DependencyProperty.Register("Mode",
    8.29 -                                                                                               typeof(State.EnumDisplayMode),
    8.30 -                                                                                               typeof(PrivacyView),
    8.31 -                                                                                               new PropertyMetadata(propertyChangedCallback: DPModeChangedCallback));
    8.32 -
    8.33 -        private bool  clickStarted;
    8.34 -        private State displayState;
    8.35 -        private bool  eventsAreConnected;
    8.36 -
    8.37 -        /**************************************************************
    8.38 -         * 
    8.39 -         * Constructors
    8.40 -         * 
    8.41 -         *************************************************************/
    8.42 -
    8.43 -        /// <summary>
    8.44 -        /// Default constructor.
    8.45 -        /// </summary>
    8.46 -        public PrivacyView()
    8.47 -        {
    8.48 -            this.InitializeComponent();
    8.49 -
    8.50 -            this.clickStarted = false;
    8.51 -            this.displayState = new State();
    8.52 -            this.eventsAreConnected = false;
    8.53 -
    8.54 -            // Sync dependency property values with the display state
    8.55 -            this.SetCurrentValue(RatingProperty, this.displayState.Rating);
    8.56 -            this.SetCurrentValue(ModeProperty, this.displayState.Mode);
    8.57 -
    8.58 -            this.ConnectEvents(true);
    8.59 -        }
    8.60 -
    8.61 -        /**************************************************************
    8.62 -         * 
    8.63 -         * Property Accessors
    8.64 -         * 
    8.65 -         *************************************************************/
    8.66 -
    8.67 -        /// <summary>
    8.68 -        /// Gets or sets the pEp rating.
    8.69 -        /// This is bound directly to the current display state Rating property which is then bound to the UI.
    8.70 -        /// </summary>
    8.71 -        public pEpRating Rating
    8.72 -        {
    8.73 -            get { return (pEpRating)this.GetValue(RatingProperty); }
    8.74 -            set { this.SetCurrentValue(RatingProperty, value); }
    8.75 -        }
    8.76 -
    8.77 -        /// <summary>
    8.78 -        /// Gets or sets the displayed state.
    8.79 -        /// </summary>
    8.80 -        public State DisplayState
    8.81 -        {
    8.82 -            get { return (this.displayState); }
    8.83 -            set { this.displayState = value; }
    8.84 -        }
    8.85 -
    8.86 -        /// <summary>
    8.87 -        /// Gets or sets the display mode.
    8.88 -        /// This is bound directly to the current display state Mode property which is  
    8.89 -        /// then bound to the UI.
    8.90 -        /// </summary>
    8.91 -        public State.EnumDisplayMode Mode
    8.92 -        {
    8.93 -            get { return (State.EnumDisplayMode)this.GetValue(ModeProperty); }
    8.94 -            set { this.SetCurrentValue(ModeProperty, value); }
    8.95 -        }
    8.96 -
    8.97 -        /**************************************************************
    8.98 -         * 
    8.99 -         * Methods
   8.100 -         * 
   8.101 -         *************************************************************/
   8.102 -
   8.103 -        /// <summary>
   8.104 -        /// Connects or disconnects all control events from the UI.
   8.105 -        /// </summary>
   8.106 -        /// <param name="connect">True to connect events, false to disconnect.</param>
   8.107 -        private void ConnectEvents(bool connect)
   8.108 -        {
   8.109 -            // Connect events only if not already connected
   8.110 -            if ((connect == true) &&
   8.111 -                (this.eventsAreConnected == false))
   8.112 -            {
   8.113 -                this.GridHitTarget.MouseEnter += GridHitTarget_MouseEnter;
   8.114 -                this.GridHitTarget.MouseLeave += GridHitTarget_MouseLeave;
   8.115 -                this.GridHitTarget.MouseDown += GridHitTarget_MouseDown;
   8.116 -                this.GridHitTarget.MouseUp += GridHitTarget_MouseUp;
   8.117 -                this.GridHitTarget.LostFocus += GridHitTarget_LostFocus;
   8.118 -
   8.119 -                this.eventsAreConnected = true;
   8.120 -            }
   8.121 -            // Always attempt to disconnect
   8.122 -            else if (connect == false)
   8.123 -            {
   8.124 -                this.GridHitTarget.MouseEnter -= GridHitTarget_MouseEnter;
   8.125 -                this.GridHitTarget.MouseLeave -= GridHitTarget_MouseLeave;
   8.126 -                this.GridHitTarget.MouseDown -= GridHitTarget_MouseDown;
   8.127 -                this.GridHitTarget.MouseUp -= GridHitTarget_MouseUp;
   8.128 -                this.GridHitTarget.LostFocus -= GridHitTarget_LostFocus;
   8.129 -
   8.130 -                this.eventsAreConnected = false;
   8.131 -            }
   8.132 -
   8.133 -            return;
   8.134 -        }
   8.135 -
   8.136 -        /**************************************************************
   8.137 -         * 
   8.138 -         * Callbacks
   8.139 -         * 
   8.140 -         *************************************************************/
   8.141 -
   8.142 -        /// <summary>
   8.143 -        /// Callback for when the Rating dependency property changes.
   8.144 -        /// </summary>
   8.145 -        public static void DPRatingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
   8.146 -        {
   8.147 -            /* Forcefully update the view model/state
   8.148 -             * This will then trigger a UI update
   8.149 -             * Note: It should be possible to remove this callback and replace with a data binding.
   8.150 -             * However, the internal binding linking the DP to the state breaks when another binding
   8.151 -             * is added externally from a parent control.
   8.152 -             */
   8.153 -            ((PrivacyView)d).DisplayState.Rating = (pEpRating)e.NewValue;
   8.154 -            return;
   8.155 -        }
   8.156 -
   8.157 -        /// <summary>
   8.158 -        /// Callback for when the Mode dependency property changes.
   8.159 -        /// </summary>
   8.160 -        public static void DPModeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
   8.161 -        {
   8.162 -            /* Forcefully update the view model/state
   8.163 -             * This will then trigger a UI update
   8.164 -             * Note: It should be possible to remove this callback and replace with a data binding.
   8.165 -             * However, the internal binding linking the DP to the state breaks when another binding
   8.166 -             * is added externally from a parent control.
   8.167 -             */
   8.168 -            ((PrivacyView)d).DisplayState.Mode = (State.EnumDisplayMode)e.NewValue;
   8.169 -            return;
   8.170 -        }
   8.171 -
   8.172 -        /**************************************************************
   8.173 -         * 
   8.174 -         * Event Handling
   8.175 -         * 
   8.176 -         *************************************************************/
   8.177 -
   8.178 -        /// <summary>
   8.179 -        /// Event handler for when the mouse enters the hit target.
   8.180 -        /// </summary>
   8.181 -        private void GridHitTarget_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
   8.182 -        {
   8.183 -            this.displayState.MouseStatus = State.EnumMouseStatus.Over;
   8.184 -            return;
   8.185 -        }
   8.186 -
   8.187 -        /// <summary>
   8.188 -        /// Event handler for when the mouse leaves the hit target.
   8.189 -        /// </summary>
   8.190 -        private void GridHitTarget_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
   8.191 -        {
   8.192 -            this.displayState.MouseStatus = State.EnumMouseStatus.None;
   8.193 -            return;
   8.194 -        }
   8.195 -
   8.196 -        /// <summary>
   8.197 -        /// Event handler for when the mouse is pressed within the hit target.
   8.198 -        /// </summary>
   8.199 -        private void GridHitTarget_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
   8.200 -        {
   8.201 -            this.clickStarted = true;
   8.202 -            this.displayState.MouseStatus = State.EnumMouseStatus.Click;
   8.203 -            return;
   8.204 -        }
   8.205 -
   8.206 -        /// <summary>
   8.207 -        /// Event handler for when the mouse is released within the hit target.
   8.208 -        /// </summary>
   8.209 -        private void GridHitTarget_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
   8.210 -        {
   8.211 -            this.displayState.MouseStatus = State.EnumMouseStatus.None;
   8.212 -
   8.213 -            if ((this.clickStarted) &&
   8.214 -                (this.displayState.Mode == State.EnumDisplayMode.Button))
   8.215 -            {
   8.216 -                this.Click?.Invoke(this, new RoutedEventArgs());
   8.217 -            }
   8.218 -
   8.219 -            return;
   8.220 -        }
   8.221 -
   8.222 -        /// <summary>
   8.223 -        /// Event handler for when the hit target looses focus.
   8.224 -        /// </summary>
   8.225 -        private void GridHitTarget_LostFocus(object sender, RoutedEventArgs e)
   8.226 -        {
   8.227 -            this.clickStarted = false;
   8.228 -            this.displayState.MouseStatus = State.EnumMouseStatus.None;
   8.229 -            return;
   8.230 -        }
   8.231 -
   8.232 -        /**************************************************************
   8.233 -         * 
   8.234 -         * Sub-classes
   8.235 -         * 
   8.236 -         *************************************************************/
   8.237 -
   8.238 -        /// <summary>
   8.239 -        /// Class used to store the state of the manage privacy status form.
   8.240 -        /// </summary>
   8.241 -        public class State : INotifyPropertyChanged,
   8.242 -                             Interfaces.IReset
   8.243 -        {
   8.244 -            /// <summary>
   8.245 -            /// Event raised when a property is changed on a component.
   8.246 -            /// </summary>
   8.247 -            public event PropertyChangedEventHandler PropertyChanged;
   8.248 -
   8.249 -            /// <summary>
   8.250 -            /// Enumeration to define the how the privacy rating should be displayed.
   8.251 -            /// </summary>
   8.252 -            public enum EnumDisplayMode
   8.253 -            {
   8.254 -                /// <summary>
   8.255 -                /// Displays as a button that can be clicked.
   8.256 -                /// </summary>
   8.257 -                Button,
   8.258 -
   8.259 -                /// <summary>
   8.260 -                /// Displays similar to a button but it cannot be clicked.
   8.261 -                /// </summary>
   8.262 -                Indicator,
   8.263 -            }
   8.264 -
   8.265 -            /// <summary>
   8.266 -            /// Enumeration to define the mouse status on the hit target.
   8.267 -            /// </summary>
   8.268 -            public enum EnumMouseStatus
   8.269 -            {
   8.270 -                /// <summary>
   8.271 -                /// The mouse has clicked (or started to click) the hit target.
   8.272 -                /// </summary>
   8.273 -                Click,
   8.274 -
   8.275 -                /// <summary>
   8.276 -                /// The mouse is not over the hit target.
   8.277 -                /// </summary>
   8.278 -                None,
   8.279 -
   8.280 -                /// <summary>
   8.281 -                /// The mouse is over the hit target.
   8.282 -                /// </summary>
   8.283 -                Over,
   8.284 -            }
   8.285 -
   8.286 -            private Brush           _Background;
   8.287 -            private pEpColor        _Color;
   8.288 -            private pEpRating       _Rating;
   8.289 -            private Brush           _Foreground;
   8.290 -            private EnumDisplayMode _Mode;
   8.291 -            private EnumMouseStatus _MouseStatus;
   8.292 -            private string          _Text;
   8.293 -            private string          _ToolTip;
   8.294 -            private bool            _ToolTipIsVisible;
   8.295 -
   8.296 -            /**************************************************************
   8.297 -             * 
   8.298 -             * Constructors
   8.299 -             * 
   8.300 -             *************************************************************/
   8.301 -
   8.302 -            /// <summary>
   8.303 -            /// Default constructor.
   8.304 -            /// </summary>
   8.305 -            public State()
   8.306 -            {
   8.307 -                this.Reset();
   8.308 -            }
   8.309 -
   8.310 -            /**************************************************************
   8.311 -             * 
   8.312 -             * Property Accessors
   8.313 -             * 
   8.314 -             *************************************************************/
   8.315 -
   8.316 -            /// <summary>
   8.317 -            /// Gets the background brush of the control.
   8.318 -            /// This is a dependent property set through Rating, Mode and MouseStatus.
   8.319 -            /// </summary>
   8.320 -            public Brush Background
   8.321 -            {
   8.322 -                get { return (this._Background); }
   8.323 -            }
   8.324 -
   8.325 -            /// <summary>
   8.326 -            /// Gets the pEp color of the state. This is calculated from the rating.
   8.327 -            /// </summary>
   8.328 -            public pEpColor Color
   8.329 -            {
   8.330 -                get { return (this._Color); }
   8.331 -            }
   8.332 -
   8.333 -            /// <summary>
   8.334 -            /// Gets or sets the pEp rating of the state.
   8.335 -            /// </summary>
   8.336 -            public pEpRating Rating
   8.337 -            {
   8.338 -                get { return (this._Rating); }
   8.339 -                set
   8.340 -                {
   8.341 -                    this._Rating = value;
   8.342 -                    this.RaisePropertyChangedEvent(nameof(this.Rating));
   8.343 -
   8.344 -                    this.CalcDependentProperties();
   8.345 -                }
   8.346 -            }
   8.347 -
   8.348 -            /// <summary>
   8.349 -            /// Gets the foreground brush of the control.
   8.350 -            /// This is a dependent property set through Rating.
   8.351 -            /// </summary>
   8.352 -            public Brush Foreground
   8.353 -            {
   8.354 -                get { return (this._Foreground); }
   8.355 -            }
   8.356 -
   8.357 -            /// <summary>
   8.358 -            /// Gets whether this state is in indicator mode or not.
   8.359 -            /// </summary>
   8.360 -            public bool IsInIndicatorMode
   8.361 -            {
   8.362 -                get { return (this.Mode == EnumDisplayMode.Indicator); }
   8.363 -            }
   8.364 -
   8.365 -            /// <summary>
   8.366 -            /// Gets or sets the display mode of the privacy rating.
   8.367 -            /// </summary>
   8.368 -            public EnumDisplayMode Mode
   8.369 -            {
   8.370 -                get { return (this._Mode); }
   8.371 -                set
   8.372 -                {
   8.373 -                    this._Mode = value;
   8.374 -                    this.RaisePropertyChangedEvent(nameof(this.Mode));
   8.375 -
   8.376 -                    this.CalcDependentProperties();
   8.377 -                }
   8.378 -            }
   8.379 -
   8.380 -            /// <summary>
   8.381 -            /// Gets or sets the status of the mouse on the hit target.
   8.382 -            /// </summary>
   8.383 -            public EnumMouseStatus MouseStatus
   8.384 -            {
   8.385 -                get { return (this._MouseStatus); }
   8.386 -                set
   8.387 -                {
   8.388 -                    this._MouseStatus = value;
   8.389 -                    this.RaisePropertyChangedEvent(nameof(this.MouseStatus));
   8.390 -
   8.391 -                    this.CalcDependentProperties();
   8.392 -                }
   8.393 -            }
   8.394 -
   8.395 -            /// <summary>
   8.396 -            /// Gets the displayed text of the control.
   8.397 -            /// This is a dependent property set through Rating.
   8.398 -            /// </summary>
   8.399 -            public string Text
   8.400 -            {
   8.401 -                get { return (this._Text); }
   8.402 -            }
   8.403 -
   8.404 -            /// <summary>
   8.405 -            /// Gets the ToolTip text of the control.
   8.406 -            /// This is a dependent property set through Mode.
   8.407 -            /// </summary>
   8.408 -            public string ToolTip
   8.409 -            {
   8.410 -                get { return (this._ToolTip); }
   8.411 -            }
   8.412 -
   8.413 -            /// <summary>
   8.414 -            /// Gets whether the ToolTip of the control is visible.
   8.415 -            /// This is a dependent property set through Mode.
   8.416 -            /// </summary>
   8.417 -            public bool ToolTipIsVisible
   8.418 -            {
   8.419 -                get { return (this._ToolTipIsVisible); }
   8.420 -            }
   8.421 -
   8.422 -            /**************************************************************
   8.423 -             * 
   8.424 -             * Methods
   8.425 -             * 
   8.426 -             *************************************************************/
   8.427 -
   8.428 -            /// <summary>
   8.429 -            /// Raises the property changed event, if possible, with the given arguments.
   8.430 -            /// </summary>
   8.431 -            /// <param name="propertyName">The name of the property that changed.</param>
   8.432 -            private void RaisePropertyChangedEvent(string propertyName)
   8.433 -            {
   8.434 -                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   8.435 -                return;
   8.436 -            }
   8.437 -
   8.438 -            /// <summary>
   8.439 -            /// Resets the object to it's default state/values.
   8.440 -            /// This will raise property changed events.
   8.441 -            /// </summary>
   8.442 -            public void Reset()
   8.443 -            {
   8.444 -                PrivacyState state = new PrivacyState(pEpRating.pEpRatingUndefined);
   8.445 -
   8.446 -                // Set independent properties
   8.447 -                this._Rating = state.Rating;
   8.448 -                this._Mode = EnumDisplayMode.Indicator;
   8.449 -                this._MouseStatus = EnumMouseStatus.None;
   8.450 -
   8.451 -                this.RaisePropertyChangedEvent(nameof(this.Rating));
   8.452 -                this.RaisePropertyChangedEvent(nameof(this.Mode));
   8.453 -                this.RaisePropertyChangedEvent(nameof(this.MouseStatus));
   8.454 -
   8.455 -                // Set dependent properties -- raises own events
   8.456 -                this.CalcDependentProperties();
   8.457 -
   8.458 -                return;
   8.459 -            }
   8.460 -
   8.461 -            /// <summary>
   8.462 -            /// Recalculates the dependent properties from the current independent property values. 
   8.463 -            /// This will raise property changed events.
   8.464 -            /// </summary>
   8.465 -            private void CalcDependentProperties()
   8.466 -            {
   8.467 -                PrivacyState state = new PrivacyState(this._Rating);
   8.468 -
   8.469 -                //Color
   8.470 -                this._Color = this.Rating.ToColor();
   8.471 -                this.RaisePropertyChangedEvent(nameof(this.Color));
   8.472 -
   8.473 -                // Background
   8.474 -                if (this._Mode == EnumDisplayMode.Button)
   8.475 -                {
   8.476 -                    switch (this._MouseStatus)
   8.477 -                    {
   8.478 -                        case EnumMouseStatus.Click:
   8.479 -                            this._Background = state.BackgroundClick;
   8.480 -                            break;
   8.481 -                        case EnumMouseStatus.None:
   8.482 -                            this._Background = state.Background;
   8.483 -                            break;
   8.484 -                        case EnumMouseStatus.Over:
   8.485 -                            this._Background = state.BackgroundMouseOver;
   8.486 -                            break;
   8.487 -                    }
   8.488 -                }
   8.489 -                else
   8.490 -                {
   8.491 -                    this._Background = state.Background;
   8.492 -                }
   8.493 -                this.RaisePropertyChangedEvent(nameof(this.Background));
   8.494 -
   8.495 -                this._Foreground = state.Foreground;
   8.496 -                this.RaisePropertyChangedEvent(nameof(this.Foreground));
   8.497 -
   8.498 -                this._Text = state.ShortText;
   8.499 -                this.RaisePropertyChangedEvent(nameof(this.Text));
   8.500 -
   8.501 -                // ToolTip
   8.502 -                if (this._Mode == EnumDisplayMode.Button)
   8.503 -                {
   8.504 -                    this._ToolTip = Properties.Resources.PrivacyView_ToolTip;
   8.505 -                    this._ToolTipIsVisible = true;
   8.506 -                }
   8.507 -                else
   8.508 -                {
   8.509 -                    this._ToolTip = null;
   8.510 -                    this._ToolTipIsVisible = false;
   8.511 -                }
   8.512 -                this.RaisePropertyChangedEvent(nameof(this.ToolTip));
   8.513 -                this.RaisePropertyChangedEvent(nameof(this.ToolTipIsVisible));
   8.514 -
   8.515 -                return;
   8.516 -            }
   8.517 -        }
   8.518 -    }
   8.519 -}
     9.1 --- a/UI/RibbonCustomizations.cs	Wed Oct 17 08:04:35 2018 +0200
     9.2 +++ b/UI/RibbonCustomizations.cs	Thu Oct 18 12:27:44 2018 +0200
     9.3 @@ -583,7 +583,7 @@
     9.4                                      omi.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, value);
     9.5  
     9.6                                      // Update UI
     9.7 -                                    RibbonCustomizations.Invalidate();
     9.8 +                                    this.UpdateUI(control);
     9.9                                  }
    9.10  
    9.11                                  break;
    9.12 @@ -674,6 +674,15 @@
    9.13              }
    9.14          }
    9.15  
    9.16 +        /// <summary>
    9.17 +        /// Updates the UI (ribbon and form region).
    9.18 +        /// </summary>
    9.19 +        /// <param name="control">The control to get its form region.</param>
    9.20 +        private void UpdateUI(Office.IRibbonControl control)
    9.21 +        {
    9.22 +            this.GetFormRegionPrivacyStatus(control)?.UpdatePrivacyStateAndUI();
    9.23 +        }
    9.24 +
    9.25          /**************************************************************
    9.26           * 
    9.27           * Callbacks
    9.28 @@ -781,65 +790,7 @@
    9.29          /// </summary>
    9.30          public System.Drawing.Bitmap ButtonPrivacyStatus_GetImage(Office.IRibbonControl control)
    9.31          {
    9.32 -            pEpRating rating = this.GetRating(control);
    9.33 -
    9.34 -            switch (rating)
    9.35 -            {
    9.36 -                // Red rating
    9.37 -                case pEpRating.pEpRatingMistrust:
    9.38 -                case pEpRating.pEpRatingB0rken:
    9.39 -                case pEpRating.pEpRatingUnderAttack:
    9.40 -                    return Properties.Resources.ImageRatingRed;
    9.41 -
    9.42 -                // Yellow rating
    9.43 -                case pEpRating.pEpRatingReliable:
    9.44 -                    {
    9.45 -                        if (this.GetForceUnencrypted(control))
    9.46 -                        {
    9.47 -                            return Properties.Resources.ImagePrivacyStatusYellowProtectionDisabled;
    9.48 -                        }
    9.49 -                        else
    9.50 -                        {
    9.51 -                            return Properties.Resources.ImageRatingYellow;
    9.52 -                        }
    9.53 -                    }
    9.54 -
    9.55 -                // Green rating
    9.56 -                case pEpRating.pEpRatingTrusted:
    9.57 -                case pEpRating.pEpRatingTrustedAndAnonymized:
    9.58 -                case pEpRating.pEpRatingFullyAnonymous:
    9.59 -                    {
    9.60 -                        if (this.GetForceUnencrypted(control))
    9.61 -                        {
    9.62 -                            return Properties.Resources.ImagePrivacyStatusGreenProtectionDisabled;
    9.63 -                        }
    9.64 -                        else
    9.65 -                        {
    9.66 -                            return Properties.Resources.ImageRatingGreen;
    9.67 -                        }
    9.68 -                    }
    9.69 -
    9.70 -                // No color rating
    9.71 -                case pEpRating.pEpRatingUnencrypted:
    9.72 -                case pEpRating.pEpRatingUnencryptedForSome:
    9.73 -                    {
    9.74 -                        if ((this.GetForceProtection(control)) &&
    9.75 -                            (this.GetDisableForceProtection(control) == false))
    9.76 -                        {
    9.77 -                            return Properties.Resources.ImageRatingYellow;
    9.78 -                        }
    9.79 -                        else
    9.80 -                        {
    9.81 -                            return Properties.Resources.ImagePrivacyStatusNoColor;
    9.82 -                        }
    9.83 -                    }
    9.84 -                case pEpRating.pEpRatingUndefined:
    9.85 -                case pEpRating.pEpRatingCannotDecrypt:
    9.86 -                case pEpRating.pEpRatingHaveNoKey:
    9.87 -                case pEpRating.pEpRatingUnreliable:
    9.88 -                default:
    9.89 -                    return Properties.Resources.ImagePrivacyStatusNoColor;
    9.90 -            }
    9.91 +            return this.GetFormRegionPrivacyStatus(control)?.PrivacyState.Image;
    9.92          }
    9.93  
    9.94          /// <summary>
    9.95 @@ -847,63 +798,14 @@
    9.96          /// </summary>
    9.97          public string ButtonPrivacyStatus_GetLabel(Office.IRibbonControl control)
    9.98          {
    9.99 -            pEpRating rating = this.GetRating(control);
   9.100 +            string label = this.GetFormRegionPrivacyStatus(control)?.PrivacyState.Label;
   9.101  
   9.102 -            switch (rating)
   9.103 +            // Workaround to show ampersands correctly
   9.104 +            if (label.Contains(" & "))
   9.105              {
   9.106 -                case pEpRating.pEpRatingMistrust:
   9.107 -                    return Properties.Resources.PrivacyStatus_RatingMistrustText;
   9.108 -                case pEpRating.pEpRatingB0rken:
   9.109 -                    return Properties.Resources.PrivacyStatus_RatingBrokenText;
   9.110 -                case pEpRating.pEpRatingUnderAttack:
   9.111 -                    return Properties.Resources.PrivacyStatus_RatingUnderAttackText;
   9.112 -                case pEpRating.pEpRatingReliable:
   9.113 -                    {
   9.114 -                        if (this.GetForceUnencrypted(control))
   9.115 -                        {
   9.116 -                            return Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   9.117 -                        }
   9.118 -                        else
   9.119 -                        {
   9.120 -                            return Properties.Resources.PrivacyStatus_RatingReliableText;
   9.121 -                        }
   9.122 -                    }
   9.123 -                case pEpRating.pEpRatingTrusted:
   9.124 -                case pEpRating.pEpRatingTrustedAndAnonymized:
   9.125 -                case pEpRating.pEpRatingFullyAnonymous:
   9.126 -                    {
   9.127 -                        if (this.GetForceUnencrypted(control))
   9.128 -                        {
   9.129 -                            return Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   9.130 -                        }
   9.131 -                        else
   9.132 -                        {
   9.133 -                            return Properties.Resources.PrivacyStatus_RatingTrustedText;
   9.134 -                        }
   9.135 -                    }
   9.136 -                case pEpRating.pEpRatingCannotDecrypt:
   9.137 -                case pEpRating.pEpRatingHaveNoKey:
   9.138 -                    return Properties.Resources.PrivacyStatus_RatingHaveNoKeyText;
   9.139 -                case pEpRating.pEpRatingUnencrypted:
   9.140 -                    {
   9.141 -                        if ((this.GetForceProtection(control)) &&
   9.142 -                            (this.GetDisableForceProtection(control) == false))
   9.143 -                        {
   9.144 -                            return Properties.Resources.PrivacyStatus_RatingReliableText;
   9.145 -                        }
   9.146 -                        else
   9.147 -                        {
   9.148 -                            return Properties.Resources.PrivacyStatus_RatingUnencryptedText;
   9.149 -                        }
   9.150 -                    }
   9.151 -                case pEpRating.pEpRatingUnencryptedForSome:
   9.152 -                    return Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeText;
   9.153 -                case pEpRating.pEpRatingUnreliable:
   9.154 -                    return Properties.Resources.PrivacyStatus_RatingUnreliableText;
   9.155 -                case pEpRating.pEpRatingUndefined:
   9.156 -                default:
   9.157 -                    return Properties.Resources.PrivacyStatus_RatingUndefinedText;
   9.158 +                label = label.Replace(" & ", " && ");
   9.159              }
   9.160 +            return label;
   9.161          }
   9.162  
   9.163          /// <summary>
   9.164 @@ -911,7 +813,7 @@
   9.165          /// </summary>
   9.166          public string ButtonPrivacyStatus_GetScreentip(Office.IRibbonControl control)
   9.167          {
   9.168 -            return Properties.Resources.PrivacyStatus_FormText;            
   9.169 +            return Properties.Resources.PrivacyStatus_FormText;
   9.170          }
   9.171  
   9.172          /// <summary>
   9.173 @@ -946,7 +848,7 @@
   9.174                          {
   9.175                              omi = this.GetMailItem(control);
   9.176                              visible = ((omi?.GetIsDraft() == true) ||
   9.177 -                                       (this.GetIsDecryptAlwaysEnabled(control)));                     
   9.178 +                                       (this.GetIsDecryptAlwaysEnabled(control)));
   9.179                          }
   9.180                      }
   9.181                  }
   9.182 @@ -991,7 +893,7 @@
   9.183                  this.SetNeverUnsecure(control, false);
   9.184              }
   9.185  
   9.186 -            RibbonCustomizations.Invalidate();
   9.187 +            this.UpdateUI(control);
   9.188          }
   9.189  
   9.190          /// <summary>
   9.191 @@ -1002,13 +904,13 @@
   9.192              /* The button is disabled if
   9.193               *  - Rating is lower than reliable
   9.194               *  - Force Protection or Never Unsecure are enabled and not overridden
   9.195 -             */ 
   9.196 +             */
   9.197              if (((this.GetRating(control) < pEpRating.pEpRatingReliable) ||
   9.198                   (this.GetNeverUnsecure(control))) ||
   9.199                   ((this.GetForceProtection(control)) && (this.GetDisableForceProtection(control) == false)))
   9.200              {
   9.201                  return false;
   9.202 -            }            
   9.203 +            }
   9.204              else
   9.205              {
   9.206                  return true;
   9.207 @@ -1126,7 +1028,7 @@
   9.208                  this.SetNeverUnsecure(control, isPressed);
   9.209              }
   9.210  
   9.211 -            RibbonCustomizations.Invalidate();
   9.212 +            this.UpdateUI(control);
   9.213          }
   9.214  
   9.215          /// <summary>
   9.216 @@ -1149,7 +1051,7 @@
   9.217  
   9.218              if (this.GetIsPEPEnabled(control))
   9.219              {
   9.220 -                enabled = ((this.GetRating(control) == pEpRating.pEpRatingUnencrypted) && 
   9.221 +                enabled = ((this.GetRating(control) == pEpRating.pEpRatingUnencrypted) &&
   9.222                             (this.GetForceUnencrypted(control) == false));
   9.223              }
   9.224              else
   9.225 @@ -1174,7 +1076,7 @@
   9.226          /// </summary>
   9.227          public bool ToggleButtonForceProtection_GetPressed(Office.IRibbonControl control)
   9.228          {
   9.229 -            return ((this.GetForceProtection(control)) && 
   9.230 +            return ((this.GetForceProtection(control)) &&
   9.231                      (this.GetDisableForceProtection(control) == false));
   9.232          }
   9.233  
   9.234 @@ -1205,7 +1107,7 @@
   9.235          public void ToggleButtonNeverUnsecure_Click(Office.IRibbonControl control, bool isPressed)
   9.236          {
   9.237              this.SetNeverUnsecure(control, isPressed);
   9.238 -            RibbonCustomizations.Invalidate();
   9.239 +            this.UpdateUI(control);
   9.240          }
   9.241  
   9.242          /// <summary>
   9.243 @@ -1214,9 +1116,9 @@
   9.244          public bool ToggleButtonNeverUnsecure_GetEnabled(Office.IRibbonControl control)
   9.245          {
   9.246              // Enabled if not forcefully unencrypted, rating >= Reliable (or force protection), no S/MIME enabled and no BCC recipients
   9.247 -             return (((this.GetRating(control) >= pEpRating.pEpRatingReliable) || (this.GetForceProtection(control)) && (this.ToggleButtonForceProtection_GetEnabled(control))) &&
   9.248 -                     (this.GetForceUnencrypted(control) == false) &&
   9.249 -                     (this.GetIsSMIMEEnabled(control) == false));
   9.250 +            return (((this.GetRating(control) >= pEpRating.pEpRatingReliable) || (this.GetForceProtection(control)) && (this.ToggleButtonForceProtection_GetEnabled(control))) &&
   9.251 +                    (this.GetForceUnencrypted(control) == false) &&
   9.252 +                    (this.GetIsSMIMEEnabled(control) == false));
   9.253          }
   9.254  
   9.255          /// <summary>
   9.256 @@ -1342,7 +1244,7 @@
   9.257          public void ToggleButtonForceUnencryptedContact_Click(Office.IRibbonControl control, bool isPressed)
   9.258          {
   9.259              this.SetProperty(control, MailItemExtensions.PEPProperty.ForceUnencrypted, isPressed);
   9.260 -            RibbonCustomizations.Invalidate();
   9.261 +            this.UpdateUI(control);
   9.262          }
   9.263  
   9.264          /// <summary>
   9.265 @@ -1491,7 +1393,7 @@
   9.266                  if (explorer != null)
   9.267                  {
   9.268                      visible = (explorer.ActiveInlineResponse == null);
   9.269 -                }                
   9.270 +                }
   9.271              }
   9.272              catch (Exception ex)
   9.273              {
   9.274 @@ -1642,7 +1544,7 @@
   9.275              switch (ribbonID)
   9.276              {
   9.277                  case "Microsoft.Outlook.Explorer":
   9.278 -                    if (Globals.OutlookVersion == Globals.Version.Outlook2010 )
   9.279 +                    if (Globals.OutlookVersion == Globals.Version.Outlook2010)
   9.280                      {
   9.281                          return GetResourceText("pEp.UI.RibbonCustomizationsExplorer2010.xml");
   9.282                      }
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/UI/UserControlPrivacyStatus.xaml	Thu Oct 18 12:27:44 2018 +0200
    10.3 @@ -0,0 +1,36 @@
    10.4 +<UserControl x:Class="pEp.UI.UserControlPrivacyStatus"
    10.5 +             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    10.6 +             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    10.7 +             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    10.8 +             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    10.9 +             mc:Ignorable="d" 
   10.10 +             d:DesignHeight="36" d:DesignWidth="500">
   10.11 +    <Grid>
   10.12 +        <Grid.ColumnDefinitions>
   10.13 +            <ColumnDefinition Width="auto"/>
   10.14 +            <ColumnDefinition Width="*"/>
   10.15 +            <ColumnDefinition Width="auto"/>
   10.16 +        </Grid.ColumnDefinitions>
   10.17 +
   10.18 +        <!--The Privacy Status icon-->
   10.19 +        <Image Grid.Column="0" 
   10.20 +               Width="30"
   10.21 +               Height="30"
   10.22 +               Margin="10,3"
   10.23 +               Source="{Binding Path=Icon}"/>
   10.24 +        
   10.25 +        <!--The Privacy Status text-->
   10.26 +        <Label Grid.Column="1"
   10.27 +               VerticalAlignment="Center"
   10.28 +               Margin="5"
   10.29 +               Content="{Binding Path=Text}"
   10.30 +               Foreground="{Binding Path=ForegroundColor}"/>
   10.31 +        
   10.32 +        <!--The pEp logo-->
   10.33 +        <Image Grid.Column="2"
   10.34 +               Width="36"
   10.35 +               Height="36"
   10.36 +               Margin="10,0"
   10.37 +               Source="{Binding Path=Logo}" />
   10.38 +    </Grid>
   10.39 +</UserControl>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/UI/UserControlPrivacyStatus.xaml.cs	Thu Oct 18 12:27:44 2018 +0200
    11.3 @@ -0,0 +1,104 @@
    11.4 +using System.ComponentModel;
    11.5 +using System.Windows.Controls;
    11.6 +using System.Windows.Media;
    11.7 +
    11.8 +namespace pEp.UI
    11.9 +{
   11.10 +    /// <summary>
   11.11 +    /// Interaction logic for UserControlPrivacyStatus.xaml
   11.12 +    /// </summary>
   11.13 +    public partial class UserControlPrivacyStatus : UserControl,
   11.14 +                                                    INotifyPropertyChanged
   11.15 +    {
   11.16 +        private Brush       _ForegroundColor;
   11.17 +        private ImageSource _Icon;
   11.18 +        private ImageSource _Logo;
   11.19 +        private string      _Text;
   11.20 +
   11.21 +        public event PropertyChangedEventHandler PropertyChanged;
   11.22 +
   11.23 +        /// <summary>
   11.24 +        /// Constructor.
   11.25 +        /// </summary>
   11.26 +        public UserControlPrivacyStatus()
   11.27 +        {
   11.28 +            InitializeComponent();
   11.29 +            this.DataContext = this;
   11.30 +            this.Update(new PrivacyState());
   11.31 +        }
   11.32 +
   11.33 +        /// <summary>
   11.34 +        /// The foreground (font) color.
   11.35 +        /// </summary>
   11.36 +        public Brush ForegroundColor
   11.37 +        {
   11.38 +            get { return this._ForegroundColor; }
   11.39 +            set
   11.40 +            {
   11.41 +                this._ForegroundColor = value;
   11.42 +                this.RaisePropertyChangedEvent(nameof(this.ForegroundColor));
   11.43 +            }
   11.44 +        }
   11.45 +
   11.46 +        /// <summary>
   11.47 +        /// The privacy status icon.
   11.48 +        /// </summary>
   11.49 +        public ImageSource Icon
   11.50 +        {
   11.51 +            get { return this._Icon; }
   11.52 +            set
   11.53 +            {
   11.54 +                this._Icon = value;
   11.55 +                this.RaisePropertyChangedEvent(nameof(this.Icon));
   11.56 +            }
   11.57 +        }
   11.58 +
   11.59 +        /// <summary>
   11.60 +        /// The pEp logo.
   11.61 +        /// </summary>
   11.62 +        public ImageSource Logo
   11.63 +        {
   11.64 +            get { return this._Logo; }
   11.65 +            set
   11.66 +            {
   11.67 +                this._Logo = value;
   11.68 +                this.RaisePropertyChangedEvent(nameof(this.Logo));
   11.69 +            }
   11.70 +        }
   11.71 +
   11.72 +        /// <summary>
   11.73 +        /// The Privacy Status text.
   11.74 +        /// </summary>
   11.75 +        public string Text
   11.76 +        {
   11.77 +            get { return this._Text; }
   11.78 +            set
   11.79 +            {
   11.80 +                this._Text = value;
   11.81 +                this.RaisePropertyChangedEvent(nameof(this.Text));
   11.82 +            }
   11.83 +        }
   11.84 +
   11.85 +        /// <summary>
   11.86 +        /// Raises the property changed event, if possible, with the given arguments.
   11.87 +        /// </summary>
   11.88 +        /// <param name="propertyName">The name of the property that changed.</param>
   11.89 +        private void RaisePropertyChangedEvent(string propertyName)
   11.90 +        {
   11.91 +            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   11.92 +        }
   11.93 +
   11.94 +        /// <summary>
   11.95 +        /// Updates this control with the values from the given Privacy State.
   11.96 +        /// </summary>
   11.97 +        /// <param name="privacyState">The Privacy State to get its values from.</param>
   11.98 +        internal void Update(PrivacyState privacyState)
   11.99 +        {
  11.100 +            this.Background = privacyState.Background;
  11.101 +            this.ForegroundColor = privacyState.Foreground;
  11.102 +            this.Icon = privacyState.ImageInvert;
  11.103 +            this.Text = privacyState.Label;
  11.104 +            this.Logo = privacyState.Logo;
  11.105 +        }
  11.106 +    }
  11.107 +}
    12.1 --- a/pEpForOutlook.csproj	Wed Oct 17 08:04:35 2018 +0200
    12.2 +++ b/pEpForOutlook.csproj	Thu Oct 18 12:27:44 2018 +0200
    12.3 @@ -466,12 +466,12 @@
    12.4        <SubType>Code</SubType>
    12.5      </Compile>
    12.6      <Compile Include="UI\PrivacyState.cs" />
    12.7 -    <Compile Include="UI\PrivacyView.xaml.cs">
    12.8 -      <DependentUpon>PrivacyView.xaml</DependentUpon>
    12.9 -    </Compile>
   12.10      <Compile Include="UI\SelectionBox.xaml.cs">
   12.11        <DependentUpon>SelectionBox.xaml</DependentUpon>
   12.12      </Compile>
   12.13 +    <Compile Include="UI\UserControlPrivacyStatus.xaml.cs">
   12.14 +      <DependentUpon>UserControlPrivacyStatus.xaml</DependentUpon>
   12.15 +    </Compile>
   12.16      <Compile Include="UI\ValueConverters.cs" />
   12.17      <Compile Include="Wrappers\WatchedExplorer.cs" />
   12.18      <EmbeddedResource Include="Properties\Resources.hi.resx">
   12.19 @@ -569,10 +569,7 @@
   12.20      <Resource Include="Resources\ImageLogoBuyMedium.png" />
   12.21      <Resource Include="Resources\ImageLogoIcon.png" />
   12.22      <Resource Include="Resources\ImagePreviewContact.png" />
   12.23 -    <Resource Include="Resources\ImagePrivacyStatusGreenInvert.png" />
   12.24 -    <Resource Include="Resources\ImagePrivacyStatusNoColorInvert.png" />
   12.25      <Resource Include="Resources\ImagePrivacyStatusRedInvert.png" />
   12.26 -    <Resource Include="Resources\ImagePrivacyStatusYellowInvert.png" />
   12.27      <Resource Include="Resources\ImageRatingGreen.png" />
   12.28      <Resource Include="Resources\ImageRatingRed.png" />
   12.29      <Resource Include="Resources\ImageRatingYellow.png" />
   12.30 @@ -581,6 +578,9 @@
   12.31      <Resource Include="Resources\ImageLogoWhite.png" />
   12.32      <Resource Include="Resources\ImagePrivacyStatusGreenProtectionDisabledInvert.png" />
   12.33      <Resource Include="Resources\ImagePrivacyStatusYellowProtectionDisabledInvert.png" />
   12.34 +    <Resource Include="Resources\ImagePrivacyStatusGreenInvert.png" />
   12.35 +    <Resource Include="Resources\ImagePrivacyStatusNoColorInvert.png" />
   12.36 +    <Resource Include="Resources\ImagePrivacyStatusYellowInvert.png" />
   12.37      <Content Include="Resources\ImageReaderSplash.png" />
   12.38      <Content Include="Resources\ImageUpgradePEP.png" />
   12.39      <Resource Include="Resources\ImageNeverUnsecureOff.png" />
   12.40 @@ -616,6 +616,10 @@
   12.41      <Resource Include="Resources\ImagePrivacyStatusYellow.png" />
   12.42    </ItemGroup>
   12.43    <ItemGroup>
   12.44 +    <Page Include="UI\UserControlPrivacyStatus.xaml">
   12.45 +      <SubType>Designer</SubType>
   12.46 +      <Generator>MSBuild:Compile</Generator>
   12.47 +    </Page>
   12.48      <Resource Include="Resources\Dictionary.xaml">
   12.49        <Generator>MSBuild:Compile</Generator>
   12.50        <SubType>Designer</SubType>
   12.51 @@ -644,10 +648,6 @@
   12.52        <SubType>Designer</SubType>
   12.53        <Generator>MSBuild:Compile</Generator>
   12.54      </Page>
   12.55 -    <Page Include="UI\PrivacyView.xaml">
   12.56 -      <SubType>Designer</SubType>
   12.57 -      <Generator>MSBuild:Compile</Generator>
   12.58 -    </Page>
   12.59      <Page Include="UI\SelectionBox.xaml">
   12.60        <SubType>Designer</SubType>
   12.61        <Generator>MSBuild:Compile</Generator>