Implement DraftMailItem and reorganizing Redesign_Ribbon
authorThomas
Fri, 14 Jul 2017 14:26:43 +0200
branchRedesign_Ribbon
changeset 17421b4c06ca643e
parent 1741 aad40b3e7ede
child 1746 f8ebc4c85206
Implement DraftMailItem and reorganizing
AdapterExtensions.cs
CryptableMailItem.cs
DraftMailItem.cs
Extensions/MailItemExtensions.cs
MsgContainer.cs
MsgProcessor.cs
ThisAddIn.cs
UI/ExplorerRibbon.Designer.cs
UI/ExplorerRibbon.cs
UI/ExplorerRibbon.resx
UI/HandshakeDialog.xaml.cs
UI/InspectorRibbonCompose.Designer.cs
UI/InspectorRibbonCompose.cs
UI/InspectorRibbonRead.Designer.cs
UI/InspectorRibbonRead.cs
UI/InspectorRibbonRead.resx
UI/Ribbon/ExplorerRibbon.Designer.cs
UI/Ribbon/ExplorerRibbon.cs
UI/Ribbon/InspectorRibbonCompose.Designer.cs
UI/Ribbon/InspectorRibbonCompose.cs
UI/Ribbon/InspectorRibbonRead.Designer.cs
UI/Ribbon/InspectorRibbonRead.cs
UI/Ribbon/InspectorRibbonRead.resx
UI/Ribbon/RibbonExtensions.cs
UI/RibbonExtensions.cs
WatchedExplorer.cs
pEpForOutlook.csproj
     1.1 --- a/AdapterExtensions.cs	Thu Jul 13 13:26:16 2017 +0200
     1.2 +++ b/AdapterExtensions.cs	Fri Jul 14 14:26:43 2017 +0200
     1.3 @@ -58,9 +58,10 @@
     1.4          /// <param name="message">The message to reevaluate.</param>
     1.5          /// <param name="originalRating">The original rating of the message.</param>
     1.6          /// <returns>The reevaluated rating.</returns>
     1.7 -        public static pEpRating ReevaluateMessageRating(PEPMessage message, pEpRating originalRating, string[] keyList = null)
     1.8 +        public static pEpRating ReevaluateMessageRating(PEPMessage message, pEpRating? originalRating = null, string[] keyList = null)
     1.9          {
    1.10 -            pEpRating reevaluatedRating = originalRating;
    1.11 +            pEpRating reevaluatedRating = pEpRating.pEpRatingUndefined;
    1.12 +            pEpRating processingRating;
    1.13  
    1.14              if ((message != null) &&
    1.15                  (message.KeyList != null))
    1.16 @@ -68,17 +69,29 @@
    1.17                  try
    1.18                  {
    1.19                      TextMessage src = message.ToCOMType();
    1.20 +
    1.21 +                    // If no keylist was explicitly passed, use the one stored with the message
    1.22                      if (keyList == null)
    1.23                      {
    1.24                          keyList = message.KeyList.Split(',');
    1.25                      }
    1.26  
    1.27 -                    reevaluatedRating = ThisAddIn.PEPEngine.ReEvaluateMessageRating(src, keyList, originalRating);
    1.28 +                    // If no rating was explicitly passed, use the one stored with the message
    1.29 +                    if (originalRating == null)
    1.30 +                    {
    1.31 +                        processingRating = message.Rating;
    1.32 +                    }
    1.33 +                    else
    1.34 +                    {
    1.35 +                        processingRating = originalRating ?? pEpRating.pEpRatingUndefined;
    1.36 +                    }
    1.37 +
    1.38 +                    reevaluatedRating = ThisAddIn.PEPEngine.ReEvaluateMessageRating(src, keyList, processingRating);
    1.39                  }
    1.40 -                catch (Exception e)
    1.41 +                catch (Exception ex)
    1.42                  {
    1.43 -                    reevaluatedRating = originalRating;
    1.44 -                    Log.Error("ReevaluateMessageRating: Error reevaluating rating. " + e.Message);
    1.45 +                    reevaluatedRating = pEpRating.pEpRatingUndefined;
    1.46 +                    Log.Error("ReevaluateMessageRating: Error reevaluating rating. " + ex.ToString());
    1.47                  }
    1.48              }
    1.49  
     2.1 --- a/CryptableMailItem.cs	Thu Jul 13 13:26:16 2017 +0200
     2.2 +++ b/CryptableMailItem.cs	Fri Jul 14 14:26:43 2017 +0200
     2.3 @@ -24,7 +24,7 @@
     2.4          public delegate void StdMailEventHandler(ref bool cancel);
     2.5          public delegate void RespondMailEventHandler(object item, ref bool cancel);
     2.6          public delegate void GenericHandler(object sender, EventArgs e);
     2.7 -        public delegate void ProcessingCompletedHandler(object sender, MsgProcessor.ProcessingCompletedEventArgs e);
     2.8 +        public delegate void ProcessingCompletedHandler(object sender, MsgProcessor.ProcessingCompletedEventArgsOLD e);
     2.9          public delegate void GetMirrorCompletedHandler(object sender, GetMirrorCompletedEventArgs e);
    2.10  
    2.11          /// <summary>
    2.12 @@ -1157,7 +1157,7 @@
    2.13                      {
    2.14                          if (PEPMessage.Create(this.internalMailItem, out mirror) == Globals.ReturnStatus.Success)
    2.15                          {
    2.16 -                            result = AdapterExtensions.ReevaluateMessageRating(mirror, mirror.Rating);
    2.17 +                            result = AdapterExtensions.ReevaluateMessageRating(mirror);
    2.18                          }
    2.19                      }
    2.20                      catch (Exception e)
    2.21 @@ -1204,7 +1204,7 @@
    2.22                          // Get UI rating from mirror
    2.23                          try
    2.24                          {
    2.25 -                            result = AdapterExtensions.ReevaluateMessageRating(mirror, mirror.Rating);
    2.26 +                            result = AdapterExtensions.ReevaluateMessageRating(mirror);
    2.27                          }
    2.28                          catch (Exception e)
    2.29                          {
    2.30 @@ -1468,12 +1468,12 @@
    2.31          /// </summary>
    2.32          private void Processor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    2.33          {
    2.34 -            MsgProcessor.ProcessingCompletedEventArgs args;
    2.35 +            MsgProcessor.ProcessingCompletedEventArgsOLD args;
    2.36  
    2.37              // Raise complete event (only if dispose after decryption is not true since .this reference is returned)
    2.38              if (this.disposeAfterProcessing == false)
    2.39              {
    2.40 -                args = new MsgProcessor.ProcessingCompletedEventArgs();
    2.41 +                args = new MsgProcessor.ProcessingCompletedEventArgsOLD();
    2.42  
    2.43                  // Check for errors during processing but invoke anyhow to complete process (needed to look up mirror).
    2.44                  if (e.Error == null)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/DraftMailItem.cs	Fri Jul 14 14:26:43 2017 +0200
     3.3 @@ -0,0 +1,119 @@
     3.4 +using System;
     3.5 +using System.ComponentModel;
     3.6 +using Outlook = Microsoft.Office.Interop.Outlook;
     3.7 +
     3.8 +namespace pEp
     3.9 +{
    3.10 +    /// <summary>
    3.11 +    /// Stores an Outlook draft mail item with connected events.
    3.12 +    /// </summary>
    3.13 +    public class DraftMailItem : IDisposable
    3.14 +    {
    3.15 +        /// <summary>
    3.16 +        /// Occurs when the component is disposed by a call to the Dispose method.
    3.17 +        /// </summary>
    3.18 +        public event EventHandler Disposed;
    3.19 +
    3.20 +        /// <summary>
    3.21 +        /// Event for when the internal mail item property change event occurs.
    3.22 +        /// </summary>
    3.23 +        public event PropertyChangedEventHandler PropertyChanged;
    3.24 +
    3.25 +        private Outlook.MailItem             internalMailItem                   = null;
    3.26 +
    3.27 +        /**************************************************************
    3.28 +         * 
    3.29 +         * Constructors/Destructors
    3.30 +         * 
    3.31 +         *************************************************************/
    3.32 +
    3.33 +        /// <summary>
    3.34 +        /// Primary constructor.
    3.35 +        /// </summary>
    3.36 +        /// <param name="omi">The mail item to wrap.</param>
    3.37 +        public DraftMailItem(Outlook.MailItem mailItem)
    3.38 +        {
    3.39 +            this.internalMailItem = mailItem;
    3.40 +
    3.41 +            if (this.internalMailItem != null)
    3.42 +            {
    3.43 +                this.ConnectMailItemComposeEvents();
    3.44 +            }
    3.45 +        }
    3.46 +
    3.47 +        /// <summary>
    3.48 +        /// Destructor.
    3.49 +        /// </summary>
    3.50 +        ~DraftMailItem()
    3.51 +        {
    3.52 +            this.Dispose();
    3.53 +        }
    3.54 +
    3.55 +        #region Methods
    3.56 +        /**************************************************************
    3.57 +         * 
    3.58 +         * Methods
    3.59 +         * 
    3.60 +         *************************************************************/
    3.61 +
    3.62 +        /// <summary>
    3.63 +        /// Connects all events of the internal mail item.
    3.64 +        /// </summary>
    3.65 +        private void ConnectMailItemComposeEvents()
    3.66 +        {
    3.67 +            if (this.internalMailItem != null)
    3.68 +            {
    3.69 +                this.internalMailItem.Write += MailItem_Write;
    3.70 +                this.internalMailItem.PropertyChange += MailItem_PropertyChange;
    3.71 +            }
    3.72 +        }
    3.73 +
    3.74 +        /// <summary>
    3.75 +        /// Disconnects all events from the internal mail item.
    3.76 +        /// </summary>
    3.77 +        private void DisconnectMailItemComposeEvents()
    3.78 +        {
    3.79 +            if (this.internalMailItem != null)
    3.80 +            {
    3.81 +                this.internalMailItem.Write -= MailItem_Write;
    3.82 +                this.internalMailItem.PropertyChange += MailItem_PropertyChange;
    3.83 +            }
    3.84 +        }
    3.85 +
    3.86 +        /// <summary>
    3.87 +        /// Releases all resources and disconnects internal events.
    3.88 +        /// </summary>
    3.89 +        public void Dispose()
    3.90 +        {
    3.91 +            if (this.internalMailItem != null)
    3.92 +            {
    3.93 +                this.DisconnectMailItemComposeEvents();
    3.94 +                this.internalMailItem = null;
    3.95 +            }
    3.96 +
    3.97 +            // Raise the disposed event
    3.98 +            if (this.Disposed != null)
    3.99 +                this.Disposed.Invoke(this, new EventArgs());
   3.100 +
   3.101 +            return;
   3.102 +        }
   3.103 +        #endregion
   3.104 +
   3.105 +        #region Event Handling
   3.106 +        /**************************************************************
   3.107 +         * 
   3.108 +         * Event Handling
   3.109 +         * 
   3.110 +         *************************************************************/
   3.111 +        private void MailItem_PropertyChange(string name)
   3.112 +        {
   3.113 +            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
   3.114 +        }
   3.115 +
   3.116 +        private void MailItem_Write(ref bool cancel)
   3.117 +        {
   3.118 +        }
   3.119 +
   3.120 +        #endregion
   3.121 +    }
   3.122 +}
     4.1 --- a/Extensions/MailItemExtensions.cs	Thu Jul 13 13:26:16 2017 +0200
     4.2 +++ b/Extensions/MailItemExtensions.cs	Fri Jul 14 14:26:43 2017 +0200
     4.3 @@ -1020,11 +1020,15 @@
     4.4          }
     4.5  
     4.6          /// <summary>
     4.7 -        /// Starts processing the mail item.
     4.8 +        /// Starts processing a mail item. This method should be used for items that are
     4.9 +        /// processed in automatic events like NewMailEx or Items.ItemAdd where there is
    4.10 +        /// a probability that this mail item is new and this processing is its first one.
    4.11 +        /// Do not use it for events with user interaction like Click or Open where the item
    4.12 +        /// most likely has already been processed.
    4.13          /// </summary>
    4.14 -        /// <param name="omi">The Outlook mail item to process with.</param>
    4.15 +        /// <param name="omi">The Outlook mail item to process.</param>
    4.16          /// <param name="folder">The folder type the mail item is in.</param>
    4.17 -        public static void Process(this Outlook.MailItem omi, Outlook.OlDefaultFolders? folder = null)
    4.18 +        public static void ProcessAddedItem(this Outlook.MailItem omi, Outlook.OlDefaultFolders? folder = null)
    4.19          {
    4.20              bool process = false;
    4.21              bool saveOmi = false;
    4.22 @@ -1063,6 +1067,17 @@
    4.23                          }
    4.24                      }
    4.25                  }
    4.26 +                // Do not process mirrors
    4.27 +                else if (omi.GetIsMirror())
    4.28 +                {
    4.29 +                    Log.Verbose("ProcessAddedItem: Mirror detected, skipping processing");
    4.30 +                }
    4.31 +                // Do not processes deleted messages on IMAP
    4.32 +                else if (omi.GetIsInIMAPStore() &&
    4.33 +                    (MapiHelper.GetProperty(omi, MapiProperty.PidLidImapMarkedForDeletion, "0").ToString() == "1"))
    4.34 +                {
    4.35 +                    Log.Verbose("ProcessAddedItem: Deleted IMAP message detected, skipping processing");
    4.36 +                }
    4.37                  /* Else, process the mail item and decrypt it. This is needed especially for Sent folders as sent mails are normally
    4.38                   * not read and therefore remain encrypted and not searchable in this folder.
    4.39                   * 
    4.40 @@ -1090,7 +1105,7 @@
    4.41                          }
    4.42                          catch (Exception e)
    4.43                          {
    4.44 -                            Log.Error("Items_ItemAdd: Could not set custom message class, " + e.ToString());
    4.45 +                            Log.Error("ProcessAddedItem: Could not set custom message class, " + e.ToString());
    4.46                          }
    4.47                      }
    4.48                  }
    4.49 @@ -1104,7 +1119,7 @@
    4.50                      }
    4.51                      catch (Exception ex)
    4.52                      {
    4.53 -                        Log.Error("Items_ItemAdd: Error saving mail item. " + ex.ToString());
    4.54 +                        Log.Error("ProcessAddedItem: Error saving mail item. " + ex.ToString());
    4.55                      }
    4.56                  }
    4.57  
    4.58 @@ -1122,7 +1137,7 @@
    4.59                          }
    4.60                          else
    4.61                          {
    4.62 -                            Log.Error("Items_ItemAdd: Error during creation of MsgContainer. Item skipped.");
    4.63 +                            Log.Error("ProcessAddedItem: Error during creation of MsgContainer. Item skipped.");
    4.64                          }
    4.65                      }
    4.66                      else
     5.1 --- a/MsgContainer.cs	Thu Jul 13 13:26:16 2017 +0200
     5.2 +++ b/MsgContainer.cs	Fri Jul 14 14:26:43 2017 +0200
     5.3 @@ -2,6 +2,7 @@
     5.4  using System;
     5.5  using System.Collections.Generic;
     5.6  using System.ComponentModel;
     5.7 +using System.Diagnostics;
     5.8  using System.Runtime.InteropServices;
     5.9  using Outlook = Microsoft.Office.Interop.Outlook;
    5.10  
    5.11 @@ -266,7 +267,7 @@
    5.12          /// <param name="omi">The mail item to create the container from.</param>
    5.13          /// <param name="msgContainer">The created container</param>
    5.14          /// <returns>The status of the creation operation.</returns>
    5.15 -        public static Globals.ReturnStatus Create(Outlook.MailItem omi, out MsgContainer msgContainer)
    5.16 +        public static Globals.ReturnStatus Create(Outlook.MailItem omi, out MsgContainer msgContainer, bool lookupMirror = false)
    5.17          {
    5.18              Globals.ReturnStatus status = Globals.ReturnStatus.Failure;
    5.19              PEPMessage message = null;
    5.20 @@ -276,28 +277,38 @@
    5.21              {
    5.22                  try
    5.23                  {
    5.24 +                    Log.Verbose("MsgContainer.Create. Starting...");
    5.25                      msgContainer.IsInSecureStore = omi.GetIsInSecureStore();
    5.26 +                    Log.Verbose("MsgContainer.Create. GetIsInSecureStore.");
    5.27                      msgContainer.MessageCreationStatus = PEPMessage.Create(omi, out message);
    5.28 +                    Log.Verbose("MsgContainer.Create. Created message.");
    5.29                      if (msgContainer.MessageCreationStatus == Globals.ReturnStatus.Success)
    5.30                      {
    5.31                          msgContainer.Message = message;
    5.32                      }
    5.33                      msgContainer.EntryId = omi.EntryID;
    5.34                      msgContainer.IsDraft = omi.GetIsDraft();
    5.35 +                    Log.Verbose("MsgContainer.Create. GetIsDraft.");
    5.36                      msgContainer.IsInSentFolder = omi.GetIsInSentFolder();
    5.37 +                    Log.Verbose("MsgContainer.Create. GetIsInSentFolder.");
    5.38                      msgContainer.IsMirror = omi.GetIsMirror();
    5.39 +                    Log.Verbose("MsgContainer.Create. GetIsMirror.");
    5.40                      msgContainer.IsNeverUnsecure = omi.GetNeverUnsecure();
    5.41 +                    Log.Verbose("MsgContainer.Create. GetNeverUnsecure.");
    5.42  
    5.43 -                    if ((msgContainer.IsInSecureStore || msgContainer.IsNeverUnsecure) &&
    5.44 +                    if (lookupMirror &&
    5.45 +                        (msgContainer.IsInSecureStore || msgContainer.IsNeverUnsecure) &&
    5.46                          (msgContainer.Message?.IsSecure ?? false))
    5.47                      {
    5.48                          Outlook.MailItem mirror = null;
    5.49                          PEPMessage mirrorMessage = null;
    5.50                          mirror = MsgProcessor.GetMirror(omi);
    5.51 +                        Log.Verbose("MsgContainer.Create. Found mirror.");
    5.52  
    5.53                          if (mirror != null)
    5.54                          {
    5.55                              msgContainer.MirrorCreationStatus = PEPMessage.Create(mirror, out mirrorMessage);
    5.56 +                            Log.Verbose("MsgContainer.Create. Created mirror.");
    5.57                              if (msgContainer.MirrorCreationStatus == Globals.ReturnStatus.Success)
    5.58                              {
    5.59                                  msgContainer.Mirror = mirrorMessage;
    5.60 @@ -305,19 +316,17 @@
    5.61                          }
    5.62                      }
    5.63  
    5.64 -                    if (msgContainer.Mirror != null)
    5.65 -                    {
    5.66 -                        msgContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Mirror, msgContainer.Mirror.Rating);
    5.67 -                    }
    5.68 -                    else if (msgContainer.Message != null)
    5.69 +                    if (msgContainer.Message != null)
    5.70                      {
    5.71                          if (msgContainer.Message.Direction == pEpMsgDirection.pEpDirIncoming)
    5.72                          {
    5.73 -                            msgContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Message, msgContainer.Message.Rating);
    5.74 +                            msgContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Message);
    5.75 +                            Log.Verbose("MsgContainer.Create. Reevaluated rating.");
    5.76                          }
    5.77                          else
    5.78                          {
    5.79                              msgContainer.Rating = msgContainer.Message.GetOutgoingRating();
    5.80 +                            Log.Verbose("MsgContainer.Create. Outgoing rating.");
    5.81                          }
    5.82                      }
    5.83  
     6.1 --- a/MsgProcessor.cs	Thu Jul 13 13:26:16 2017 +0200
     6.2 +++ b/MsgProcessor.cs	Fri Jul 14 14:26:43 2017 +0200
     6.3 @@ -15,15 +15,15 @@
     6.4      /// </summary>
     6.5      internal class MsgProcessor : IDisposable
     6.6      {
     6.7 +        public delegate void ProcessingCompletedHandlerOLD(object sender, ProcessingCompletedEventArgsOLD e);
     6.8          public delegate void ProcessingCompletedHandler(object sender, ProcessingCompletedEventArgs e);
     6.9 -        public delegate void ProcessingCompletedHandler2(object sender, ProcessingCompletedEventArgs2 e);
    6.10  
    6.11          /// <summary>
    6.12          /// Event when processing is completed.
    6.13          /// WARNING: The calling thread is a background worker.
    6.14          /// </summary>
    6.15 +        public event ProcessingCompletedHandlerOLD ProcessingCompletedOLD;
    6.16          public event ProcessingCompletedHandler ProcessingCompleted;
    6.17 -        public event ProcessingCompletedHandler2 ProcessingCompleted2;
    6.18  
    6.19          public const string UNKNOWN_SENDER                            = "unknown";
    6.20          public const string USER_PROPERTY_KEY_FORCE_UNENCRYPTED       = "sendUnencrypted";
    6.21 @@ -85,7 +85,7 @@
    6.22              pEpDecryptFlags decryptionFlags;
    6.23              MsgContainer msgCont;
    6.24              Globals.ReturnStatus sts;
    6.25 -            ProcessingCompletedEventArgs args = null;
    6.26 +            ProcessingCompletedEventArgsOLD args = null;
    6.27  
    6.28              if (e.Argument is MsgContainer)
    6.29              {
    6.30 @@ -101,7 +101,7 @@
    6.31                                            out processedRating,
    6.32                                            out decryptionFlags);
    6.33  
    6.34 -                args = new ProcessingCompletedEventArgs();
    6.35 +                args = new ProcessingCompletedEventArgsOLD();
    6.36                  args.IsMirror = (mirror != null);
    6.37                  args.ProcessedDecryptionFlags = decryptionFlags;
    6.38                  args.ProcessedMessage = processedMessage;
    6.39 @@ -119,7 +119,7 @@
    6.40          private void BackgroundProcessor_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    6.41          {
    6.42              Log.Verbose("MsgProcessor.BackgroundProcessor: Completed");
    6.43 -            this.ProcessingCompleted?.Invoke(this, (e.Result as ProcessingCompletedEventArgs));
    6.44 +            this.ProcessingCompletedOLD?.Invoke(this, (e.Result as ProcessingCompletedEventArgsOLD));
    6.45              return;
    6.46          }
    6.47  
    6.48 @@ -188,7 +188,7 @@
    6.49                          {
    6.50                              if (updateUI)
    6.51                              {
    6.52 -                                this.ProcessingCompleted2?.Invoke(this, new ProcessingCompletedEventArgs2(result));
    6.53 +                                this.ProcessingCompleted?.Invoke(this, new ProcessingCompletedEventArgs(result));
    6.54                              }
    6.55                              else
    6.56                              {
    6.57 @@ -202,7 +202,6 @@
    6.58                              Globals.ThisAddIn.DecrementDecryptionCounter();
    6.59                          }
    6.60  
    6.61 -
    6.62                      }, TaskScheduler.FromCurrentSynchronizationContext());
    6.63                  }
    6.64                  catch (Exception e)
    6.65 @@ -228,7 +227,7 @@
    6.66                  if ((msgContainer.IsInSecureStore) &&
    6.67                      (msgContainer.Mirror != null))
    6.68                  {
    6.69 -                    processedMessageContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Mirror, msgContainer.Mirror.Rating);
    6.70 +                    processedMessageContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Mirror);
    6.71                  }
    6.72                  else
    6.73                  {
    6.74 @@ -261,7 +260,7 @@
    6.75                          {
    6.76                              try
    6.77                              {
    6.78 -                                processedMessageContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Message, msgContainer.Message.Rating);
    6.79 +                                processedMessageContainer.Rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Message);
    6.80                              }
    6.81                              catch (Exception ex)
    6.82                              {
    6.83 @@ -273,6 +272,7 @@
    6.84                          {
    6.85                              processedMessageContainer.Mirror = mirrorMessage;
    6.86                              processedMessageContainer.MirrorCreated = true;
    6.87 +                            processedMessageContainer.MirrorCreationStatus = Globals.ReturnStatus.Success;
    6.88                          }
    6.89  
    6.90                          if (sts != Globals.ReturnStatus.Success)
    6.91 @@ -300,27 +300,27 @@
    6.92                  {
    6.93                      if (msgContainer.Error == null)
    6.94                      {
    6.95 -                        if ((msgContainer.IsInSecureStore || msgContainer.IsNeverUnsecure) &&
    6.96 -                            (msgContainer.Mirror != null))
    6.97 +                        if (msgContainer.IsInSecureStore || msgContainer.IsNeverUnsecure)
    6.98                          {
    6.99 -                            MsgProcessor.SetMirror(msgContainer);
   6.100 -
   6.101 -                            if (msgContainer.MirrorCreated)
   6.102 +                            if (msgContainer.Mirror != null)
   6.103                              {
   6.104 -                                omi = this.CreateMirrorOMI(msgContainer.EntryId);
   6.105 -                            }
   6.106 -
   6.107 -                            if (omi != null)
   6.108 -                            {
   6.109 -                                msgContainer.Mirror.ApplyTo(omi, true, false);
   6.110 -                                omi.Save();
   6.111 +                                MsgProcessor.SetMirror(msgContainer);
   6.112                              }
   6.113                          }
   6.114                          else if (msgContainer.Message != null)
   6.115                          {
   6.116                              omi = Globals.ThisAddIn.Application.Session.GetItemFromID(msgContainer?.EntryId);
   6.117 -                            msgContainer.Message.ApplyTo(omi, true, false);
   6.118 -                            omi.Save();
   6.119 +
   6.120 +                            if (omi != null)
   6.121 +                            {
   6.122 +                                msgContainer.Message.ApplyTo(omi, true, false);
   6.123 +                                omi.Save();
   6.124 +                            }
   6.125 +                            else
   6.126 +                            {
   6.127 +                                Log.Error("MsgProcessor.CompleteProcessing: Failure getting omi from entryId. "
   6.128 +                                          + ((string.IsNullOrEmpty(msgContainer.EntryId)) ? "EntryId null or empty." : ""));
   6.129 +                            }
   6.130                          }
   6.131  
   6.132                          // Update UI rating if necessary
   6.133 @@ -333,9 +333,7 @@
   6.134                                  if (uiParent is Outlook.Explorer)
   6.135                                  {
   6.136                                      ribbonCollection = Globals.Ribbons[uiParent as Outlook.Explorer];
   6.137 -
   6.138 -                                    ribbonCollection.ExplorerRibbon.pEpButton.UpdateButton(msgContainer.Rating);
   6.139 -                                    ribbonCollection.ExplorerRibbon.pEpGroupExplorer.UpdateVisibility(msgContainer.Rating);
   6.140 +                                    ribbonCollection?.ExplorerRibbon?.pEpGroupExplorer?.UpdatePEPGroup(msgContainer.Rating);
   6.141                                  }
   6.142                              }
   6.143                              catch (Exception ex)
   6.144 @@ -343,6 +341,46 @@
   6.145                                  Log.Error("MsgProcessor.CompleteProcessing: Error updating pEp ribbon. " + ex.ToString());
   6.146                              }
   6.147                          }
   6.148 +
   6.149 +                        if (msgContainer.MirrorCreated)
   6.150 +                        {
   6.151 +                            // Double check if mirror is not already there
   6.152 +                            if (omi != null)
   6.153 +                            {
   6.154 +                                var sw = new System.Diagnostics.Stopwatch();
   6.155 +                                sw.Restart();
   6.156 +                                Outlook.MailItem mirrorItem = MsgProcessor.GetMirror(omi);
   6.157 +                                sw.Stop();
   6.158 +                                Log.Verbose(string.Format("MsgProcessor.CompleteProcessing: Looking up mirror took {0} ms. Was found: {1}.", sw.ElapsedMilliseconds, (mirrorItem != null).ToString()));
   6.159 +
   6.160 +                                if (mirrorItem == null)
   6.161 +                                {
   6.162 +                                    mirrorItem = this.CreateMirrorOMI(msgContainer.EntryId);
   6.163 +
   6.164 +                                    if (mirrorItem != null)
   6.165 +                                    {
   6.166 +                                        try
   6.167 +                                        {
   6.168 +                                            msgContainer.Mirror.ApplyTo(mirrorItem, true, false);
   6.169 +                                            mirrorItem.Save();
   6.170 +                                        }
   6.171 +                                        catch (Exception ex)
   6.172 +                                        {
   6.173 +                                            Log.Error("MsgProcessor.CompleteProcessing: Error applying and saving mirror mail item. " + ex.ToString());
   6.174 +                                        }
   6.175 +                                    }
   6.176 +                                }
   6.177 +
   6.178 +                                mirrorItem = null;
   6.179 +                            }
   6.180 +                            else
   6.181 +                            {
   6.182 +                                Log.Error("MsgProcessor.CompleteProcessing: Failure getting omi from entryId for mirror search. "
   6.183 +                                          + ((string.IsNullOrEmpty(msgContainer.EntryId)) ? "EntryId null or empty." : ""));
   6.184 +                            }
   6.185 +
   6.186 +
   6.187 +                        }
   6.188                      }
   6.189                      else
   6.190                      {
   6.191 @@ -1538,17 +1576,18 @@
   6.192              WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveExplorer()];
   6.193              PEPMessage mirror = msgContainer.Mirror;
   6.194  
   6.195 -            if ((mirror == null) &&
   6.196 -                (msgContainer.MirrorCreationStatus == Globals.ReturnStatus.Failure))
   6.197 +            if (mirror == null)
   6.198              {
   6.199 -                MsgProcessor.SetNote(Properties.Resources.Message_OpenError);
   6.200 -                Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, failure during decryption.");
   6.201 -            }
   6.202 -            else if ((mirror == null) &&
   6.203 -                     (msgContainer.MirrorCreationStatus == Globals.ReturnStatus.FailureNoConnection))
   6.204 -            {
   6.205 -                MsgProcessor.SetNote(Properties.Resources.Message_DecryptionNoConnection);
   6.206 -                Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, connection failure during decryption.");
   6.207 +                if (msgContainer.MirrorCreationStatus == Globals.ReturnStatus.FailureNoConnection)
   6.208 +                {
   6.209 +                    MsgProcessor.SetNote(Properties.Resources.Message_DecryptionNoConnection);
   6.210 +                    Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, connection failure during decryption.");
   6.211 +                }
   6.212 +                else
   6.213 +                {
   6.214 +                    MsgProcessor.SetNote(Properties.Resources.Message_OpenError);
   6.215 +                    Log.Verbose("MailItem_GetMirrorComplete: Cannot display mirror, failure during decryption.");
   6.216 +                }
   6.217              }
   6.218              else
   6.219              {
   6.220 @@ -1873,7 +1912,10 @@
   6.221              return (MsgProcessor.GetMirror(original.EntryID, userName));
   6.222          }
   6.223  
   6.224 -
   6.225 +        /// <summary>
   6.226 +        /// Clears the unencrypted preview and displays the given note (if any).
   6.227 +        /// </summary>
   6.228 +        /// <param name="note">The note to diplsay.</param>
   6.229          public static void SetNote(string note = null)
   6.230          {
   6.231              WindowFormRegionCollection formRegions = Globals.FormRegions[Globals.ThisAddIn.Application.ActiveWindow()];
   6.232 @@ -1905,11 +1947,14 @@
   6.233           * 
   6.234           *************************************************************/
   6.235  
   6.236 -        internal class ProcessingCompletedEventArgs2 : EventArgs
   6.237 +        /// <summary>
   6.238 +        /// Class used to store the result in the ProcessingCompleted event.
   6.239 +        /// </summary>
   6.240 +        internal class ProcessingCompletedEventArgs : EventArgs
   6.241          {
   6.242              public MsgContainer Result { get; set; }
   6.243  
   6.244 -            public ProcessingCompletedEventArgs2(MsgContainer result)
   6.245 +            public ProcessingCompletedEventArgs(MsgContainer result)
   6.246              {
   6.247                  this.Result = result;
   6.248              }
   6.249 @@ -1918,7 +1963,7 @@
   6.250          /// <summary>
   6.251          /// Class used to store the arguments in the ProcessingCompleted event.
   6.252          /// </summary>
   6.253 -        internal class ProcessingCompletedEventArgs : EventArgs
   6.254 +        internal class ProcessingCompletedEventArgsOLD : EventArgs
   6.255          {
   6.256              /// <summary>
   6.257              /// Whether the ProcessedMessage corresponds to a mirror (true) or the original message (false).
   6.258 @@ -1949,7 +1994,7 @@
   6.259              /// <summary>
   6.260              /// Default constructor.
   6.261              /// </summary>
   6.262 -            public ProcessingCompletedEventArgs()
   6.263 +            public ProcessingCompletedEventArgsOLD()
   6.264              {
   6.265                  this.IsMirror = false;
   6.266                  this.ProcessedDecryptionFlags = pEpDecryptFlags.pEpDecryptFlagsNone;
   6.267 @@ -1962,7 +2007,7 @@
   6.268              /// Constructs a new ProcessingCompletedEventArgs with the given arguments.
   6.269              /// </summary>
   6.270              /// <param name="rating">The rating after the processing completes.</param>
   6.271 -            public ProcessingCompletedEventArgs(pEpRating rating)
   6.272 +            public ProcessingCompletedEventArgsOLD(pEpRating rating)
   6.273              {
   6.274                  this.IsMirror = false;
   6.275                  this.ProcessedDecryptionFlags = pEpDecryptFlags.pEpDecryptFlagsNone;
     7.1 --- a/ThisAddIn.cs	Thu Jul 13 13:26:16 2017 +0200
     7.2 +++ b/ThisAddIn.cs	Fri Jul 14 14:26:43 2017 +0200
     7.3 @@ -3549,7 +3549,7 @@
     7.4  
     7.5                      if (omi != null)
     7.6                      {
     7.7 -                        omi.Process();
     7.8 +                        omi.ProcessAddedItem();
     7.9                      }
    7.10                  }
    7.11              }
    7.12 @@ -4416,7 +4416,7 @@
    7.13  
    7.14                      if (omi != null)
    7.15                      {
    7.16 -                        omi.Process(this.defaultFolder);
    7.17 +                        omi.ProcessAddedItem(this.defaultFolder);
    7.18                      }
    7.19                  }
    7.20                  catch (Exception ex)
     8.1 --- a/UI/ExplorerRibbon.Designer.cs	Thu Jul 13 13:26:16 2017 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,96 +0,0 @@
     8.4 -namespace pEp
     8.5 -{
     8.6 -    partial class ExplorerRibbon : Microsoft.Office.Tools.Ribbon.RibbonBase
     8.7 -    {
     8.8 -        /// <summary>
     8.9 -        /// Required designer variable.
    8.10 -        /// </summary>
    8.11 -        private System.ComponentModel.IContainer components = null;
    8.12 -
    8.13 -        public ExplorerRibbon()
    8.14 -            : base(Globals.Factory.GetRibbonFactory())
    8.15 -        {
    8.16 -            InitializeComponent();
    8.17 -        }
    8.18 -
    8.19 -        /// <summary>
    8.20 -        /// Clean up any resources being used.
    8.21 -        /// </summary>
    8.22 -        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    8.23 -        protected override void Dispose(bool disposing)
    8.24 -        {
    8.25 -            if (disposing && (components != null))
    8.26 -            {
    8.27 -                components.Dispose();
    8.28 -            }
    8.29 -            base.Dispose(disposing);
    8.30 -        }
    8.31 -
    8.32 -        #region Component Designer generated code
    8.33 -
    8.34 -        /// <summary>
    8.35 -        /// Required method for Designer support - do not modify
    8.36 -        /// the contents of this method with the code editor.
    8.37 -        /// </summary>
    8.38 -        private void InitializeComponent()
    8.39 -        {
    8.40 -            this.tab1 = this.Factory.CreateRibbonTab();
    8.41 -            this.pEpGroupExplorer = this.Factory.CreateRibbonGroup();
    8.42 -            this.pEpButton = this.Factory.CreateRibbonButton();
    8.43 -            this.tab1.SuspendLayout();
    8.44 -            this.pEpGroupExplorer.SuspendLayout();
    8.45 -            this.SuspendLayout();
    8.46 -            // 
    8.47 -            // tab1
    8.48 -            // 
    8.49 -            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
    8.50 -            this.tab1.ControlId.OfficeId = "TabMail";
    8.51 -            this.tab1.Groups.Add(this.pEpGroupExplorer);
    8.52 -            this.tab1.Label = "TabMail";
    8.53 -            this.tab1.Name = "tab1";
    8.54 -            // 
    8.55 -            // pEpGroupExplorer
    8.56 -            // 
    8.57 -            this.pEpGroupExplorer.Items.Add(this.pEpButton);
    8.58 -            this.pEpGroupExplorer.Label = "pEp";
    8.59 -            this.pEpGroupExplorer.Name = "pEpGroupExplorer";
    8.60 -            this.pEpGroupExplorer.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupSendReceive");
    8.61 -            // 
    8.62 -            // pEpButton
    8.63 -            // 
    8.64 -            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
    8.65 -            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
    8.66 -            this.pEpButton.Label = "pEp";
    8.67 -            this.pEpButton.Name = "pEpButton";
    8.68 -            this.pEpButton.ShowImage = true;
    8.69 -            this.pEpButton.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.pEpButton_Click);
    8.70 -            // 
    8.71 -            // ExplorerRibbon
    8.72 -            // 
    8.73 -            this.Name = "ExplorerRibbon";
    8.74 -            this.RibbonType = "Microsoft.Outlook.Explorer";
    8.75 -            this.Tabs.Add(this.tab1);
    8.76 -            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.ExplorerRibbon_Load);
    8.77 -            this.tab1.ResumeLayout(false);
    8.78 -            this.tab1.PerformLayout();
    8.79 -            this.pEpGroupExplorer.ResumeLayout(false);
    8.80 -            this.pEpGroupExplorer.PerformLayout();
    8.81 -            this.ResumeLayout(false);
    8.82 -
    8.83 -        }
    8.84 -
    8.85 -        #endregion
    8.86 -
    8.87 -        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
    8.88 -        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupExplorer;
    8.89 -        internal Microsoft.Office.Tools.Ribbon.RibbonButton pEpButton;
    8.90 -    }
    8.91 -
    8.92 -    partial class ThisRibbonCollection
    8.93 -    {
    8.94 -        internal ExplorerRibbon ExplorerRibbon
    8.95 -        {
    8.96 -            get { return this.GetRibbon<ExplorerRibbon>(); }
    8.97 -        }
    8.98 -    }
    8.99 -}
     9.1 --- a/UI/ExplorerRibbon.cs	Thu Jul 13 13:26:16 2017 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,95 +0,0 @@
     9.4 -using Microsoft.Office.Tools.Ribbon;
     9.5 -using pEp.UI;
     9.6 -using pEpCOMServerAdapterLib;
     9.7 -using System;
     9.8 -using Outlook = Microsoft.Office.Interop.Outlook;
     9.9 -
    9.10 -namespace pEp
    9.11 -{
    9.12 -    public partial class ExplorerRibbon
    9.13 -    {
    9.14 -        HandshakeDialog handshakeDialog = null;
    9.15 -
    9.16 -        private void ExplorerRibbon_Load(object sender, RibbonUIEventArgs e)
    9.17 -        {
    9.18 -
    9.19 -        }
    9.20 -
    9.21 -        private void pEpButton_Click(object sender, RibbonControlEventArgs e)
    9.22 -        {
    9.23 -            Outlook.Explorer explorer = null;
    9.24 -            Outlook.MailItem omi = null;
    9.25 -            MsgContainer msgContainer = null;
    9.26 -            PEPIdentity ownIdent = null;
    9.27 -
    9.28 -            try
    9.29 -            {
    9.30 -                explorer = this.Context as Outlook.Explorer;
    9.31 -
    9.32 -                if (explorer.Selection?.Count > 0)
    9.33 -                {
    9.34 -                    omi = explorer.Selection[1] as Outlook.MailItem;
    9.35 -
    9.36 -                    if (omi != null)
    9.37 -                    {
    9.38 -                        // Create MsgContainer
    9.39 -                        if (MsgContainer.Create(omi, out msgContainer) != Globals.ReturnStatus.Success)
    9.40 -                        {
    9.41 -                            throw new Exception("Error creating MsgContainer.");
    9.42 -                        }
    9.43 -
    9.44 -                        // Get own identity
    9.45 -                        if (PEPIdentity.GetOwnIdentity(omi, out ownIdent) != Globals.ReturnStatus.Success)
    9.46 -                        {
    9.47 -                            throw new Exception("Error getting own identity.");
    9.48 -                        }
    9.49 -
    9.50 -                        omi = null;
    9.51 -
    9.52 -                        handshakeDialog = new HandshakeDialog(ownIdent,
    9.53 -                                                              msgContainer.Mirror ?? msgContainer.Message);
    9.54 -                        handshakeDialog.OnUpdateStatus += HandshakeDialog_Updated;
    9.55 -                        handshakeDialog.Closed += HandshakeDialog_Closed;
    9.56 -                        handshakeDialog.ShowDialog();
    9.57 -                    }
    9.58 -                }
    9.59 -
    9.60 -            }
    9.61 -            catch (Exception ex)
    9.62 -            {
    9.63 -                Globals.StopAndSendCrashReport(ex);
    9.64 -            }
    9.65 -            finally
    9.66 -            {
    9.67 -                explorer = null;
    9.68 -                omi = null;
    9.69 -            }
    9.70 -        }
    9.71 -
    9.72 -        /// <summary>
    9.73 -        /// Event handler for when a handshake dialog was closed.
    9.74 -        /// </summary>
    9.75 -        private void HandshakeDialog_Closed(object sender, EventArgs e)
    9.76 -        {
    9.77 -            if (this.handshakeDialog != null)
    9.78 -            {
    9.79 -                this.handshakeDialog.OnUpdateStatus -= HandshakeDialog_Updated;
    9.80 -                this.handshakeDialog.Closed -= HandshakeDialog_Closed;
    9.81 -                this.handshakeDialog = null;
    9.82 -            }
    9.83 -        }
    9.84 -
    9.85 -        /// <summary>
    9.86 -        /// Event handler for when a handshake dialog was updated.
    9.87 -        /// </summary>
    9.88 -        private void HandshakeDialog_Updated(object sender, EventArgs e)
    9.89 -        {
    9.90 -            var handshakeDialog = sender as HandshakeDialog;
    9.91 -            if (handshakeDialog != null)
    9.92 -            {
    9.93 -                pEpRating rating = AdapterExtensions.ReevaluateMessageRating(handshakeDialog.Message, handshakeDialog.Message.Rating);
    9.94 -                this.pEpButton.UpdateButton(rating);
    9.95 -            }
    9.96 -        }
    9.97 -    }
    9.98 -}
    10.1 --- a/UI/ExplorerRibbon.resx	Thu Jul 13 13:26:16 2017 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,120 +0,0 @@
    10.4 -<?xml version="1.0" encoding="utf-8"?>
    10.5 -<root>
    10.6 -  <!-- 
    10.7 -    Microsoft ResX Schema 
    10.8 -    
    10.9 -    Version 2.0
   10.10 -    
   10.11 -    The primary goals of this format is to allow a simple XML format 
   10.12 -    that is mostly human readable. The generation and parsing of the 
   10.13 -    various data types are done through the TypeConverter classes 
   10.14 -    associated with the data types.
   10.15 -    
   10.16 -    Example:
   10.17 -    
   10.18 -    ... ado.net/XML headers & schema ...
   10.19 -    <resheader name="resmimetype">text/microsoft-resx</resheader>
   10.20 -    <resheader name="version">2.0</resheader>
   10.21 -    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   10.22 -    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   10.23 -    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
   10.24 -    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   10.25 -    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   10.26 -        <value>[base64 mime encoded serialized .NET Framework object]</value>
   10.27 -    </data>
   10.28 -    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   10.29 -        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
   10.30 -        <comment>This is a comment</comment>
   10.31 -    </data>
   10.32 -                
   10.33 -    There are any number of "resheader" rows that contain simple 
   10.34 -    name/value pairs.
   10.35 -    
   10.36 -    Each data row contains a name, and value. The row also contains a 
   10.37 -    type or mimetype. Type corresponds to a .NET class that support 
   10.38 -    text/value conversion through the TypeConverter architecture. 
   10.39 -    Classes that don't support this are serialized and stored with the 
   10.40 -    mimetype set.
   10.41 -    
   10.42 -    The mimetype is used for serialized objects, and tells the 
   10.43 -    ResXResourceReader how to depersist the object. This is currently not 
   10.44 -    extensible. For a given mimetype the value must be set accordingly:
   10.45 -    
   10.46 -    Note - application/x-microsoft.net.object.binary.base64 is the format 
   10.47 -    that the ResXResourceWriter will generate, however the reader can 
   10.48 -    read any of the formats listed below.
   10.49 -    
   10.50 -    mimetype: application/x-microsoft.net.object.binary.base64
   10.51 -    value   : The object must be serialized with 
   10.52 -            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
   10.53 -            : and then encoded with base64 encoding.
   10.54 -    
   10.55 -    mimetype: application/x-microsoft.net.object.soap.base64
   10.56 -    value   : The object must be serialized with 
   10.57 -            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   10.58 -            : and then encoded with base64 encoding.
   10.59 -
   10.60 -    mimetype: application/x-microsoft.net.object.bytearray.base64
   10.61 -    value   : The object must be serialized into a byte array 
   10.62 -            : using a System.ComponentModel.TypeConverter
   10.63 -            : and then encoded with base64 encoding.
   10.64 -    -->
   10.65 -  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   10.66 -    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
   10.67 -    <xsd:element name="root" msdata:IsDataSet="true">
   10.68 -      <xsd:complexType>
   10.69 -        <xsd:choice maxOccurs="unbounded">
   10.70 -          <xsd:element name="metadata">
   10.71 -            <xsd:complexType>
   10.72 -              <xsd:sequence>
   10.73 -                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   10.74 -              </xsd:sequence>
   10.75 -              <xsd:attribute name="name" use="required" type="xsd:string" />
   10.76 -              <xsd:attribute name="type" type="xsd:string" />
   10.77 -              <xsd:attribute name="mimetype" type="xsd:string" />
   10.78 -              <xsd:attribute ref="xml:space" />
   10.79 -            </xsd:complexType>
   10.80 -          </xsd:element>
   10.81 -          <xsd:element name="assembly">
   10.82 -            <xsd:complexType>
   10.83 -              <xsd:attribute name="alias" type="xsd:string" />
   10.84 -              <xsd:attribute name="name" type="xsd:string" />
   10.85 -            </xsd:complexType>
   10.86 -          </xsd:element>
   10.87 -          <xsd:element name="data">
   10.88 -            <xsd:complexType>
   10.89 -              <xsd:sequence>
   10.90 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   10.91 -                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   10.92 -              </xsd:sequence>
   10.93 -              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
   10.94 -              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   10.95 -              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   10.96 -              <xsd:attribute ref="xml:space" />
   10.97 -            </xsd:complexType>
   10.98 -          </xsd:element>
   10.99 -          <xsd:element name="resheader">
  10.100 -            <xsd:complexType>
  10.101 -              <xsd:sequence>
  10.102 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
  10.103 -              </xsd:sequence>
  10.104 -              <xsd:attribute name="name" type="xsd:string" use="required" />
  10.105 -            </xsd:complexType>
  10.106 -          </xsd:element>
  10.107 -        </xsd:choice>
  10.108 -      </xsd:complexType>
  10.109 -    </xsd:element>
  10.110 -  </xsd:schema>
  10.111 -  <resheader name="resmimetype">
  10.112 -    <value>text/microsoft-resx</value>
  10.113 -  </resheader>
  10.114 -  <resheader name="version">
  10.115 -    <value>2.0</value>
  10.116 -  </resheader>
  10.117 -  <resheader name="reader">
  10.118 -    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  10.119 -  </resheader>
  10.120 -  <resheader name="writer">
  10.121 -    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  10.122 -  </resheader>
  10.123 -</root>
  10.124 \ No newline at end of file
    11.1 --- a/UI/HandshakeDialog.xaml.cs	Thu Jul 13 13:26:16 2017 +0200
    11.2 +++ b/UI/HandshakeDialog.xaml.cs	Fri Jul 14 14:26:43 2017 +0200
    11.3 @@ -111,7 +111,7 @@
    11.4          /// <param name="isIncoming">Whether the mail item is incoming or not.</param>
    11.5          public HandshakeDialog(PEPIdentity myself,
    11.6                                 PEPMessage message)
    11.7 -        { 
    11.8 +        {
    11.9              this.InitializeDialog();
   11.10  
   11.11              this.Myself = myself;
   11.12 @@ -524,22 +524,7 @@
   11.13              this.BuildDialog();
   11.14  
   11.15              // Raise updated event
   11.16 -            OnUpdateStatus(this, new EventArgs());
   11.17 -        }
   11.18 -
   11.19 -        /// <summary>
   11.20 -        /// Builds a new key sync state.
   11.21 -        /// </summary>
   11.22 -        /// <param name="ownIdentity">The own identity.</param>
   11.23 -        /// <param name="partnerIdentity">The partner identity.</param>
   11.24 -        /// <param name="mode">The handshake mode.</param>
   11.25 -        public void BuildSyncState(PEPIdentity ownIdentity,
   11.26 -                                   PEPIdentity partnerIdentity,
   11.27 -                                   HandshakeMode mode)
   11.28 -        {
   11.29 -            this.Items = new ObservableCollection<HandshakeItem>();
   11.30 -
   11.31 -
   11.32 +            this.OnUpdateStatus.Invoke(this, new EventArgs());
   11.33          }
   11.34  
   11.35          /// <summary>
    12.1 --- a/UI/InspectorRibbonCompose.Designer.cs	Thu Jul 13 13:26:16 2017 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,97 +0,0 @@
    12.4 -namespace pEp
    12.5 -{
    12.6 -    partial class InspectorRibbonCompose : Microsoft.Office.Tools.Ribbon.RibbonBase
    12.7 -    {
    12.8 -        /// <summary>
    12.9 -        /// Required designer variable.
   12.10 -        /// </summary>
   12.11 -        private System.ComponentModel.IContainer components = null;
   12.12 -
   12.13 -        public InspectorRibbonCompose()
   12.14 -            : base(Globals.Factory.GetRibbonFactory())
   12.15 -        {
   12.16 -            InitializeComponent();
   12.17 -        }
   12.18 -
   12.19 -        /// <summary>
   12.20 -        /// Clean up any resources being used.
   12.21 -        /// </summary>
   12.22 -        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   12.23 -        protected override void Dispose(bool disposing)
   12.24 -        {
   12.25 -            if (disposing && (components != null))
   12.26 -            {
   12.27 -                this.DisconnectMailItemComposeEvents(omi);
   12.28 -                this.omi = null;
   12.29 -
   12.30 -                components.Dispose();
   12.31 -            }
   12.32 -            base.Dispose(disposing);
   12.33 -        }
   12.34 -
   12.35 -        #region Component Designer generated code
   12.36 -
   12.37 -        /// <summary>
   12.38 -        /// Required method for Designer support - do not modify
   12.39 -        /// the contents of this method with the code editor.
   12.40 -        /// </summary>
   12.41 -        private void InitializeComponent()
   12.42 -        {
   12.43 -            this.tab1 = this.Factory.CreateRibbonTab();
   12.44 -            this.pEpGroupInspector = this.Factory.CreateRibbonGroup();
   12.45 -            this.pEpButton = this.Factory.CreateRibbonSplitButton();
   12.46 -            this.tab1.SuspendLayout();
   12.47 -            this.pEpGroupInspector.SuspendLayout();
   12.48 -            this.SuspendLayout();
   12.49 -            // 
   12.50 -            // tab1
   12.51 -            // 
   12.52 -            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
   12.53 -            this.tab1.ControlId.OfficeId = "TabNewMailMessage";
   12.54 -            this.tab1.Groups.Add(this.pEpGroupInspector);
   12.55 -            this.tab1.Label = "TabNewMailMessage";
   12.56 -            this.tab1.Name = "tab1";
   12.57 -            // 
   12.58 -            // pEpGroupInspector
   12.59 -            // 
   12.60 -            this.pEpGroupInspector.Items.Add(this.pEpButton);
   12.61 -            this.pEpGroupInspector.Label = "pEp";
   12.62 -            this.pEpGroupInspector.Name = "pEpGroupInspector";
   12.63 -            this.pEpGroupInspector.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupZoom");
   12.64 -            // 
   12.65 -            // pEpButton
   12.66 -            // 
   12.67 -            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
   12.68 -            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
   12.69 -            this.pEpButton.Label = "pEp";
   12.70 -            this.pEpButton.Name = "pEpButton";
   12.71 -            // 
   12.72 -            // InspectorRibbon
   12.73 -            // 
   12.74 -            this.Name = "InspectorRibbon";
   12.75 -            this.RibbonType = "Microsoft.Outlook.Mail.Compose";
   12.76 -            this.Tabs.Add(this.tab1);
   12.77 -            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.InspectorRibbonCompose_Load);
   12.78 -            this.tab1.ResumeLayout(false);
   12.79 -            this.tab1.PerformLayout();
   12.80 -            this.pEpGroupInspector.ResumeLayout(false);
   12.81 -            this.pEpGroupInspector.PerformLayout();
   12.82 -            this.ResumeLayout(false);
   12.83 -
   12.84 -        }
   12.85 -
   12.86 -        #endregion
   12.87 -
   12.88 -        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
   12.89 -        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupInspector;
   12.90 -        internal Microsoft.Office.Tools.Ribbon.RibbonSplitButton pEpButton;
   12.91 -    }
   12.92 -
   12.93 -    partial class ThisRibbonCollection
   12.94 -    {
   12.95 -        internal InspectorRibbonCompose InspectorRibbonCompose
   12.96 -        {
   12.97 -            get { return this.GetRibbon<InspectorRibbonCompose>(); }
   12.98 -        }
   12.99 -    }
  12.100 -}
    13.1 --- a/UI/InspectorRibbonCompose.cs	Thu Jul 13 13:26:16 2017 +0200
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,131 +0,0 @@
    13.4 -using Microsoft.Office.Tools.Ribbon;
    13.5 -using pEpCOMServerAdapterLib;
    13.6 -using System;
    13.7 -using System.Threading.Tasks;
    13.8 -using Outlook = Microsoft.Office.Interop.Outlook;
    13.9 -
   13.10 -namespace pEp
   13.11 -{
   13.12 -    public partial class InspectorRibbonCompose
   13.13 -    {
   13.14 -        Outlook.MailItem omi = null;
   13.15 -        bool isEnabled = true;
   13.16 -
   13.17 -        private void InspectorRibbonCompose_Load(object sender, RibbonUIEventArgs e)
   13.18 -        {
   13.19 -            Outlook.Inspector inspector = null;
   13.20 -
   13.21 -            inspector = this.Context as Outlook.Inspector;
   13.22 -
   13.23 -            if ((inspector != null) &&
   13.24 -                (inspector.CurrentItem is Outlook.MailItem))
   13.25 -            {
   13.26 -                omi = inspector.CurrentItem as Outlook.MailItem;
   13.27 -
   13.28 -                if (omi != null &&
   13.29 -                    omi.GetIsPEPEnabled())
   13.30 -                {
   13.31 -                    this.ConnectMailItemComposeEvents(omi);
   13.32 -
   13.33 -                    var rating = omi.GetOutgoingRating();
   13.34 -                    this.pEpButton.UpdateButton(rating);
   13.35 -                }
   13.36 -                else
   13.37 -                {
   13.38 -                    omi = null;
   13.39 -                    this.isEnabled = false;
   13.40 -                    this.pEpGroupInspector.Visible = false;
   13.41 -                }
   13.42 -            }
   13.43 -
   13.44 -            inspector = null;
   13.45 -        }
   13.46 -
   13.47 -        private void ConnectMailItemComposeEvents(Outlook.MailItem omi)
   13.48 -        {
   13.49 -            if (omi != null)
   13.50 -            {
   13.51 -                omi.Write += MailItem_Write;
   13.52 -                omi.PropertyChange += MailItem_PropertyChange;
   13.53 -            }
   13.54 -        }
   13.55 -
   13.56 -        private void DisconnectMailItemComposeEvents(Outlook.MailItem omi)
   13.57 -        {
   13.58 -            if (omi != null)
   13.59 -            {
   13.60 -                omi.Write -= MailItem_Write;
   13.61 -                omi.PropertyChange += MailItem_PropertyChange;
   13.62 -            }
   13.63 -        }
   13.64 -
   13.65 -        private void MailItem_PropertyChange(string name)
   13.66 -        {
   13.67 -            switch (name.ToUpperInvariant())
   13.68 -            {
   13.69 -                case "BCC":
   13.70 -                    {
   13.71 -                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   13.72 -                        break;
   13.73 -                    }
   13.74 -                case "CC":
   13.75 -                    {
   13.76 -                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   13.77 -                        break;
   13.78 -                    }
   13.79 -                case "SENTONBEHALFOFNAME":
   13.80 -                    {
   13.81 -                        // Always fired with "SENDUSINGACCOUNT" so is ignored
   13.82 -                        break;
   13.83 -                    }
   13.84 -                case "SENDUSINGACCOUNT":
   13.85 -                    {
   13.86 -                        try
   13.87 -                        {
   13.88 -                            // Update pEp enabled status
   13.89 -                            this.isEnabled = omi.GetIsPEPEnabled();
   13.90 -                            this.pEpGroupInspector.Visible = this.isEnabled;
   13.91 -
   13.92 -                            // Refresh the UI
   13.93 -                            omi.Recipients.ResolveAll();
   13.94 -                            MsgContainer msgContainer;
   13.95 -                            if (MsgContainer.Create(omi, out msgContainer) == Globals.ReturnStatus.Success)
   13.96 -                            {
   13.97 -                                this.pEpButton.UpdateButton(msgContainer.Rating);
   13.98 -                            }
   13.99 -                        }
  13.100 -                        catch (Exception ex)
  13.101 -                        {
  13.102 -                            Log.Error("MailItem_PropertyChange: Error. " + ex.ToString());
  13.103 -                        }
  13.104 -
  13.105 -                        break;
  13.106 -                    }
  13.107 -                case "TO":
  13.108 -                    {
  13.109 -                        if (this.isEnabled)
  13.110 -                        {
  13.111 -                            PEPMessage message = null;
  13.112 -                            if (PEPMessage.Create(omi, out message) == Globals.ReturnStatus.Success)
  13.113 -                            {
  13.114 -                                Task.Factory.StartNew(() =>
  13.115 -                                {
  13.116 -                                    var msgProcessor = new MsgProcessor();
  13.117 -                                    return msgProcessor.GetOutgoingRating(message);
  13.118 -
  13.119 -                                }).ContinueWith(task =>
  13.120 -                                {
  13.121 -                                    this.pEpButton.UpdateButton(task.Result);
  13.122 -                                });
  13.123 -                            }
  13.124 -                        }
  13.125 -                        break;
  13.126 -                    }
  13.127 -            }
  13.128 -        }
  13.129 -
  13.130 -        private void MailItem_Write(ref bool cancel)
  13.131 -        {
  13.132 -        }
  13.133 -    }
  13.134 -}
    14.1 --- a/UI/InspectorRibbonRead.Designer.cs	Thu Jul 13 13:26:16 2017 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,94 +0,0 @@
    14.4 -namespace pEp
    14.5 -{
    14.6 -    partial class InspectorRibbonRead : Microsoft.Office.Tools.Ribbon.RibbonBase
    14.7 -    {
    14.8 -        /// <summary>
    14.9 -        /// Required designer variable.
   14.10 -        /// </summary>
   14.11 -        private System.ComponentModel.IContainer components = null;
   14.12 -
   14.13 -        public InspectorRibbonRead()
   14.14 -            : base(Globals.Factory.GetRibbonFactory())
   14.15 -        {
   14.16 -            InitializeComponent();
   14.17 -        }
   14.18 -
   14.19 -        /// <summary>
   14.20 -        /// Clean up any resources being used.
   14.21 -        /// </summary>
   14.22 -        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   14.23 -        protected override void Dispose(bool disposing)
   14.24 -        {
   14.25 -            if (disposing && (components != null))
   14.26 -            {
   14.27 -                components.Dispose();
   14.28 -            }
   14.29 -            base.Dispose(disposing);
   14.30 -        }
   14.31 -
   14.32 -        #region Component Designer generated code
   14.33 -
   14.34 -        /// <summary>
   14.35 -        /// Required method for Designer support - do not modify
   14.36 -        /// the contents of this method with the code editor.
   14.37 -        /// </summary>
   14.38 -        private void InitializeComponent()
   14.39 -        {
   14.40 -            this.tab1 = this.Factory.CreateRibbonTab();
   14.41 -            this.pEpGroupInspector = this.Factory.CreateRibbonGroup();
   14.42 -            this.pEpButton = this.Factory.CreateRibbonSplitButton();
   14.43 -            this.tab1.SuspendLayout();
   14.44 -            this.pEpGroupInspector.SuspendLayout();
   14.45 -            this.SuspendLayout();
   14.46 -            // 
   14.47 -            // tab1
   14.48 -            // 
   14.49 -            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
   14.50 -            this.tab1.ControlId.OfficeId = "TabReadMessage";
   14.51 -            this.tab1.Groups.Add(this.pEpGroupInspector);
   14.52 -            this.tab1.Label = "TabReadMessage";
   14.53 -            this.tab1.Name = "tab1";
   14.54 -            // 
   14.55 -            // pEpGroupInspector
   14.56 -            // 
   14.57 -            this.pEpGroupInspector.Items.Add(this.pEpButton);
   14.58 -            this.pEpGroupInspector.Label = "pEp";
   14.59 -            this.pEpGroupInspector.Name = "pEpGroupInspector";
   14.60 -            this.pEpGroupInspector.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupZoom");
   14.61 -            // 
   14.62 -            // pEpButton
   14.63 -            // 
   14.64 -            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
   14.65 -            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
   14.66 -            this.pEpButton.Label = "pEp";
   14.67 -            this.pEpButton.Name = "pEpButton";
   14.68 -            // 
   14.69 -            // InspectorRibbon
   14.70 -            // 
   14.71 -            this.Name = "InspectorRibbon";
   14.72 -            this.RibbonType = "Microsoft.Outlook.Mail.Read";
   14.73 -            this.Tabs.Add(this.tab1);
   14.74 -            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.InspectorRibbon_Load);
   14.75 -            this.tab1.ResumeLayout(false);
   14.76 -            this.tab1.PerformLayout();
   14.77 -            this.pEpGroupInspector.ResumeLayout(false);
   14.78 -            this.pEpGroupInspector.PerformLayout();
   14.79 -            this.ResumeLayout(false);
   14.80 -
   14.81 -        }
   14.82 -
   14.83 -        #endregion
   14.84 -
   14.85 -        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
   14.86 -        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupInspector;
   14.87 -        internal Microsoft.Office.Tools.Ribbon.RibbonSplitButton pEpButton;
   14.88 -    }
   14.89 -
   14.90 -    partial class ThisRibbonCollection
   14.91 -    {
   14.92 -        internal InspectorRibbonRead InspectorRibbonRead
   14.93 -        {
   14.94 -            get { return this.GetRibbon<InspectorRibbonRead>(); }
   14.95 -        }
   14.96 -    }
   14.97 -}
    15.1 --- a/UI/InspectorRibbonRead.cs	Thu Jul 13 13:26:16 2017 +0200
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,43 +0,0 @@
    15.4 -using Microsoft.Office.Tools.Ribbon;
    15.5 -using pEpCOMServerAdapterLib;
    15.6 -using Outlook = Microsoft.Office.Interop.Outlook;
    15.7 -
    15.8 -
    15.9 -namespace pEp
   15.10 -{
   15.11 -    public partial class InspectorRibbonRead
   15.12 -    {
   15.13 -        private void InspectorRibbon_Load(object sender, RibbonUIEventArgs e)
   15.14 -        {
   15.15 -            Outlook.Inspector inspector = null;
   15.16 -            Outlook.MailItem omi = null;
   15.17 -            MsgContainer msgContainer = null;
   15.18 -            pEpRating rating = pEpRating.pEpRatingUndefined;
   15.19 -
   15.20 -            this.pEpGroupInspector.Visible = false;
   15.21 -
   15.22 -            inspector = this.Context as Outlook.Inspector;
   15.23 -
   15.24 -            if (inspector != null)
   15.25 -            {
   15.26 -                omi = inspector.CurrentItem as Outlook.MailItem;
   15.27 -
   15.28 -                if (omi != null)
   15.29 -                {
   15.30 -                    if (MsgContainer.Create(omi, out msgContainer) == Globals.ReturnStatus.Success)
   15.31 -                    {
   15.32 -                        rating = AdapterExtensions.ReevaluateMessageRating(msgContainer.Message, msgContainer.Message.Rating);
   15.33 -                        this.pEpButton.UpdateButton(rating);
   15.34 -                        this.pEpGroupInspector.UpdateVisibility(rating);
   15.35 -                    }
   15.36 -                    else
   15.37 -                    {
   15.38 -                        Log.Error("InspectorRibbon_Load: Error creating MsgContainer.");
   15.39 -                    }
   15.40 -
   15.41 -                    omi = null;
   15.42 -                }
   15.43 -            }
   15.44 -        }
   15.45 -    }
   15.46 -}
    16.1 --- a/UI/InspectorRibbonRead.resx	Thu Jul 13 13:26:16 2017 +0200
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,120 +0,0 @@
    16.4 -<?xml version="1.0" encoding="utf-8"?>
    16.5 -<root>
    16.6 -  <!-- 
    16.7 -    Microsoft ResX Schema 
    16.8 -    
    16.9 -    Version 2.0
   16.10 -    
   16.11 -    The primary goals of this format is to allow a simple XML format 
   16.12 -    that is mostly human readable. The generation and parsing of the 
   16.13 -    various data types are done through the TypeConverter classes 
   16.14 -    associated with the data types.
   16.15 -    
   16.16 -    Example:
   16.17 -    
   16.18 -    ... ado.net/XML headers & schema ...
   16.19 -    <resheader name="resmimetype">text/microsoft-resx</resheader>
   16.20 -    <resheader name="version">2.0</resheader>
   16.21 -    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   16.22 -    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   16.23 -    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
   16.24 -    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   16.25 -    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   16.26 -        <value>[base64 mime encoded serialized .NET Framework object]</value>
   16.27 -    </data>
   16.28 -    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   16.29 -        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
   16.30 -        <comment>This is a comment</comment>
   16.31 -    </data>
   16.32 -                
   16.33 -    There are any number of "resheader" rows that contain simple 
   16.34 -    name/value pairs.
   16.35 -    
   16.36 -    Each data row contains a name, and value. The row also contains a 
   16.37 -    type or mimetype. Type corresponds to a .NET class that support 
   16.38 -    text/value conversion through the TypeConverter architecture. 
   16.39 -    Classes that don't support this are serialized and stored with the 
   16.40 -    mimetype set.
   16.41 -    
   16.42 -    The mimetype is used for serialized objects, and tells the 
   16.43 -    ResXResourceReader how to depersist the object. This is currently not 
   16.44 -    extensible. For a given mimetype the value must be set accordingly:
   16.45 -    
   16.46 -    Note - application/x-microsoft.net.object.binary.base64 is the format 
   16.47 -    that the ResXResourceWriter will generate, however the reader can 
   16.48 -    read any of the formats listed below.
   16.49 -    
   16.50 -    mimetype: application/x-microsoft.net.object.binary.base64
   16.51 -    value   : The object must be serialized with 
   16.52 -            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
   16.53 -            : and then encoded with base64 encoding.
   16.54 -    
   16.55 -    mimetype: application/x-microsoft.net.object.soap.base64
   16.56 -    value   : The object must be serialized with 
   16.57 -            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   16.58 -            : and then encoded with base64 encoding.
   16.59 -
   16.60 -    mimetype: application/x-microsoft.net.object.bytearray.base64
   16.61 -    value   : The object must be serialized into a byte array 
   16.62 -            : using a System.ComponentModel.TypeConverter
   16.63 -            : and then encoded with base64 encoding.
   16.64 -    -->
   16.65 -  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   16.66 -    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
   16.67 -    <xsd:element name="root" msdata:IsDataSet="true">
   16.68 -      <xsd:complexType>
   16.69 -        <xsd:choice maxOccurs="unbounded">
   16.70 -          <xsd:element name="metadata">
   16.71 -            <xsd:complexType>
   16.72 -              <xsd:sequence>
   16.73 -                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   16.74 -              </xsd:sequence>
   16.75 -              <xsd:attribute name="name" use="required" type="xsd:string" />
   16.76 -              <xsd:attribute name="type" type="xsd:string" />
   16.77 -              <xsd:attribute name="mimetype" type="xsd:string" />
   16.78 -              <xsd:attribute ref="xml:space" />
   16.79 -            </xsd:complexType>
   16.80 -          </xsd:element>
   16.81 -          <xsd:element name="assembly">
   16.82 -            <xsd:complexType>
   16.83 -              <xsd:attribute name="alias" type="xsd:string" />
   16.84 -              <xsd:attribute name="name" type="xsd:string" />
   16.85 -            </xsd:complexType>
   16.86 -          </xsd:element>
   16.87 -          <xsd:element name="data">
   16.88 -            <xsd:complexType>
   16.89 -              <xsd:sequence>
   16.90 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   16.91 -                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   16.92 -              </xsd:sequence>
   16.93 -              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
   16.94 -              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   16.95 -              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   16.96 -              <xsd:attribute ref="xml:space" />
   16.97 -            </xsd:complexType>
   16.98 -          </xsd:element>
   16.99 -          <xsd:element name="resheader">
  16.100 -            <xsd:complexType>
  16.101 -              <xsd:sequence>
  16.102 -                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
  16.103 -              </xsd:sequence>
  16.104 -              <xsd:attribute name="name" type="xsd:string" use="required" />
  16.105 -            </xsd:complexType>
  16.106 -          </xsd:element>
  16.107 -        </xsd:choice>
  16.108 -      </xsd:complexType>
  16.109 -    </xsd:element>
  16.110 -  </xsd:schema>
  16.111 -  <resheader name="resmimetype">
  16.112 -    <value>text/microsoft-resx</value>
  16.113 -  </resheader>
  16.114 -  <resheader name="version">
  16.115 -    <value>2.0</value>
  16.116 -  </resheader>
  16.117 -  <resheader name="reader">
  16.118 -    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  16.119 -  </resheader>
  16.120 -  <resheader name="writer">
  16.121 -    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  16.122 -  </resheader>
  16.123 -</root>
  16.124 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/UI/Ribbon/ExplorerRibbon.Designer.cs	Fri Jul 14 14:26:43 2017 +0200
    17.3 @@ -0,0 +1,96 @@
    17.4 +namespace pEp
    17.5 +{
    17.6 +    partial class ExplorerRibbon : Microsoft.Office.Tools.Ribbon.RibbonBase
    17.7 +    {
    17.8 +        /// <summary>
    17.9 +        /// Required designer variable.
   17.10 +        /// </summary>
   17.11 +        private System.ComponentModel.IContainer components = null;
   17.12 +
   17.13 +        public ExplorerRibbon()
   17.14 +            : base(Globals.Factory.GetRibbonFactory())
   17.15 +        {
   17.16 +            InitializeComponent();
   17.17 +        }
   17.18 +
   17.19 +        /// <summary>
   17.20 +        /// Clean up any resources being used.
   17.21 +        /// </summary>
   17.22 +        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   17.23 +        protected override void Dispose(bool disposing)
   17.24 +        {
   17.25 +            if (disposing && (components != null))
   17.26 +            {
   17.27 +                components.Dispose();
   17.28 +            }
   17.29 +            base.Dispose(disposing);
   17.30 +        }
   17.31 +
   17.32 +        #region Component Designer generated code
   17.33 +
   17.34 +        /// <summary>
   17.35 +        /// Required method for Designer support - do not modify
   17.36 +        /// the contents of this method with the code editor.
   17.37 +        /// </summary>
   17.38 +        private void InitializeComponent()
   17.39 +        {
   17.40 +            this.tab1 = this.Factory.CreateRibbonTab();
   17.41 +            this.pEpGroupExplorer = this.Factory.CreateRibbonGroup();
   17.42 +            this.pEpButton = this.Factory.CreateRibbonButton();
   17.43 +            this.tab1.SuspendLayout();
   17.44 +            this.pEpGroupExplorer.SuspendLayout();
   17.45 +            this.SuspendLayout();
   17.46 +            // 
   17.47 +            // tab1
   17.48 +            // 
   17.49 +            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
   17.50 +            this.tab1.ControlId.OfficeId = "TabMail";
   17.51 +            this.tab1.Groups.Add(this.pEpGroupExplorer);
   17.52 +            this.tab1.Label = "TabMail";
   17.53 +            this.tab1.Name = "tab1";
   17.54 +            // 
   17.55 +            // pEpGroupExplorer
   17.56 +            // 
   17.57 +            this.pEpGroupExplorer.Items.Add(this.pEpButton);
   17.58 +            this.pEpGroupExplorer.Label = "pEp";
   17.59 +            this.pEpGroupExplorer.Name = "pEpGroupExplorer";
   17.60 +            this.pEpGroupExplorer.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupSendReceive");
   17.61 +            // 
   17.62 +            // pEpButton
   17.63 +            // 
   17.64 +            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
   17.65 +            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
   17.66 +            this.pEpButton.Label = "pEp";
   17.67 +            this.pEpButton.Name = "pEpButton";
   17.68 +            this.pEpButton.ShowImage = true;
   17.69 +            this.pEpButton.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.pEpButton_Click);
   17.70 +            // 
   17.71 +            // ExplorerRibbon
   17.72 +            // 
   17.73 +            this.Name = "ExplorerRibbon";
   17.74 +            this.RibbonType = "Microsoft.Outlook.Explorer";
   17.75 +            this.Tabs.Add(this.tab1);
   17.76 +            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.ExplorerRibbon_Load);
   17.77 +            this.tab1.ResumeLayout(false);
   17.78 +            this.tab1.PerformLayout();
   17.79 +            this.pEpGroupExplorer.ResumeLayout(false);
   17.80 +            this.pEpGroupExplorer.PerformLayout();
   17.81 +            this.ResumeLayout(false);
   17.82 +
   17.83 +        }
   17.84 +
   17.85 +        #endregion
   17.86 +
   17.87 +        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
   17.88 +        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupExplorer;
   17.89 +        internal Microsoft.Office.Tools.Ribbon.RibbonButton pEpButton;
   17.90 +    }
   17.91 +
   17.92 +    partial class ThisRibbonCollection
   17.93 +    {
   17.94 +        internal ExplorerRibbon ExplorerRibbon
   17.95 +        {
   17.96 +            get { return this.GetRibbon<ExplorerRibbon>(); }
   17.97 +        }
   17.98 +    }
   17.99 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/UI/Ribbon/ExplorerRibbon.cs	Fri Jul 14 14:26:43 2017 +0200
    18.3 @@ -0,0 +1,95 @@
    18.4 +using Microsoft.Office.Tools.Ribbon;
    18.5 +using pEp.UI;
    18.6 +using pEpCOMServerAdapterLib;
    18.7 +using System;
    18.8 +using Outlook = Microsoft.Office.Interop.Outlook;
    18.9 +
   18.10 +namespace pEp
   18.11 +{
   18.12 +    public partial class ExplorerRibbon
   18.13 +    {
   18.14 +        HandshakeDialog handshakeDialog = null;
   18.15 +
   18.16 +        private void ExplorerRibbon_Load(object sender, RibbonUIEventArgs e)
   18.17 +        {
   18.18 +
   18.19 +        }
   18.20 +
   18.21 +        private void pEpButton_Click(object sender, RibbonControlEventArgs e)
   18.22 +        {
   18.23 +            Outlook.Explorer explorer = null;
   18.24 +            Outlook.MailItem omi = null;
   18.25 +            MsgContainer msgContainer = null;
   18.26 +            PEPIdentity ownIdent = null;
   18.27 +
   18.28 +            try
   18.29 +            {
   18.30 +                explorer = this.Context as Outlook.Explorer;
   18.31 +
   18.32 +                if (explorer.Selection?.Count > 0)
   18.33 +                {
   18.34 +                    omi = explorer.Selection[1] as Outlook.MailItem;
   18.35 +
   18.36 +                    if (omi != null)
   18.37 +                    {
   18.38 +                        // Create MsgContainer
   18.39 +                        if (MsgContainer.Create(omi, out msgContainer) != Globals.ReturnStatus.Success)
   18.40 +                        {
   18.41 +                            throw new Exception("Error creating MsgContainer.");
   18.42 +                        }
   18.43 +
   18.44 +                        // Get own identity
   18.45 +                        if (PEPIdentity.GetOwnIdentity(omi, out ownIdent) != Globals.ReturnStatus.Success)
   18.46 +                        {
   18.47 +                            throw new Exception("Error getting own identity.");
   18.48 +                        }
   18.49 +
   18.50 +                        omi = null;
   18.51 +
   18.52 +                        handshakeDialog = new HandshakeDialog(ownIdent,
   18.53 +                                                              msgContainer.Message);
   18.54 +                        handshakeDialog.OnUpdateStatus += HandshakeDialog_Updated;
   18.55 +                        handshakeDialog.Closed += HandshakeDialog_Closed;
   18.56 +                        handshakeDialog.ShowDialog();
   18.57 +                    }
   18.58 +                }
   18.59 +
   18.60 +            }
   18.61 +            catch (Exception ex)
   18.62 +            {
   18.63 +                Globals.StopAndSendCrashReport(ex);
   18.64 +            }
   18.65 +            finally
   18.66 +            {
   18.67 +                explorer = null;
   18.68 +                omi = null;
   18.69 +            }
   18.70 +        }
   18.71 +
   18.72 +        /// <summary>
   18.73 +        /// Event handler for when a handshake dialog was closed.
   18.74 +        /// </summary>
   18.75 +        private void HandshakeDialog_Closed(object sender, EventArgs e)
   18.76 +        {
   18.77 +            if (this.handshakeDialog != null)
   18.78 +            {
   18.79 +                this.handshakeDialog.OnUpdateStatus -= HandshakeDialog_Updated;
   18.80 +                this.handshakeDialog.Closed -= HandshakeDialog_Closed;
   18.81 +                this.handshakeDialog = null;
   18.82 +            }
   18.83 +        }
   18.84 +
   18.85 +        /// <summary>
   18.86 +        /// Event handler for when a handshake dialog was updated.
   18.87 +        /// </summary>
   18.88 +        private void HandshakeDialog_Updated(object sender, EventArgs e)
   18.89 +        {
   18.90 +            var handshakeDialog = sender as HandshakeDialog;
   18.91 +            if (handshakeDialog != null)
   18.92 +            {
   18.93 +                pEpRating rating = AdapterExtensions.ReevaluateMessageRating(handshakeDialog.Message);
   18.94 +                this.pEpGroupExplorer.UpdatePEPGroup(rating);
   18.95 +            }
   18.96 +        }
   18.97 +    }
   18.98 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/UI/Ribbon/InspectorRibbonCompose.Designer.cs	Fri Jul 14 14:26:43 2017 +0200
    19.3 @@ -0,0 +1,98 @@
    19.4 +namespace pEp
    19.5 +{
    19.6 +    partial class InspectorRibbonCompose : Microsoft.Office.Tools.Ribbon.RibbonBase
    19.7 +    {
    19.8 +        /// <summary>
    19.9 +        /// Required designer variable.
   19.10 +        /// </summary>
   19.11 +        private System.ComponentModel.IContainer components = null;
   19.12 +
   19.13 +        public InspectorRibbonCompose()
   19.14 +            : base(Globals.Factory.GetRibbonFactory())
   19.15 +        {
   19.16 +            InitializeComponent();
   19.17 +        }
   19.18 +
   19.19 +        /// <summary>
   19.20 +        /// Clean up any resources being used.
   19.21 +        /// </summary>
   19.22 +        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   19.23 +        protected override void Dispose(bool disposing)
   19.24 +        {
   19.25 +            if (disposing && (components != null))
   19.26 +            {
   19.27 +                this.internalDraftMailItem.PropertyChanged -= MailItem_PropertyChanged;
   19.28 +                this.internalDraftMailItem.Dispose();
   19.29 +                this.internalDraftMailItem = null;
   19.30 +
   19.31 +                components.Dispose();
   19.32 +            }
   19.33 +            base.Dispose(disposing);
   19.34 +        }
   19.35 +
   19.36 +        #region Component Designer generated code
   19.37 +
   19.38 +        /// <summary>
   19.39 +        /// Required method for Designer support - do not modify
   19.40 +        /// the contents of this method with the code editor.
   19.41 +        /// </summary>
   19.42 +        private void InitializeComponent()
   19.43 +        {
   19.44 +            this.tab1 = this.Factory.CreateRibbonTab();
   19.45 +            this.pEpGroupInspector = this.Factory.CreateRibbonGroup();
   19.46 +            this.pEpButton = this.Factory.CreateRibbonSplitButton();
   19.47 +            this.tab1.SuspendLayout();
   19.48 +            this.pEpGroupInspector.SuspendLayout();
   19.49 +            this.SuspendLayout();
   19.50 +            // 
   19.51 +            // tab1
   19.52 +            // 
   19.53 +            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
   19.54 +            this.tab1.ControlId.OfficeId = "TabNewMailMessage";
   19.55 +            this.tab1.Groups.Add(this.pEpGroupInspector);
   19.56 +            this.tab1.Label = "TabNewMailMessage";
   19.57 +            this.tab1.Name = "tab1";
   19.58 +            // 
   19.59 +            // pEpGroupInspector
   19.60 +            // 
   19.61 +            this.pEpGroupInspector.Items.Add(this.pEpButton);
   19.62 +            this.pEpGroupInspector.Label = "pEp";
   19.63 +            this.pEpGroupInspector.Name = "pEpGroupInspector";
   19.64 +            this.pEpGroupInspector.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupZoom");
   19.65 +            // 
   19.66 +            // pEpButton
   19.67 +            // 
   19.68 +            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
   19.69 +            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
   19.70 +            this.pEpButton.Label = "pEp";
   19.71 +            this.pEpButton.Name = "pEpButton";
   19.72 +            // 
   19.73 +            // InspectorRibbon
   19.74 +            // 
   19.75 +            this.Name = "InspectorRibbon";
   19.76 +            this.RibbonType = "Microsoft.Outlook.Mail.Compose";
   19.77 +            this.Tabs.Add(this.tab1);
   19.78 +            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.InspectorRibbonCompose_Load);
   19.79 +            this.tab1.ResumeLayout(false);
   19.80 +            this.tab1.PerformLayout();
   19.81 +            this.pEpGroupInspector.ResumeLayout(false);
   19.82 +            this.pEpGroupInspector.PerformLayout();
   19.83 +            this.ResumeLayout(false);
   19.84 +
   19.85 +        }
   19.86 +
   19.87 +        #endregion
   19.88 +
   19.89 +        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
   19.90 +        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupInspector;
   19.91 +        internal Microsoft.Office.Tools.Ribbon.RibbonSplitButton pEpButton;
   19.92 +    }
   19.93 +
   19.94 +    partial class ThisRibbonCollection
   19.95 +    {
   19.96 +        internal InspectorRibbonCompose InspectorRibbonCompose
   19.97 +        {
   19.98 +            get { return this.GetRibbon<InspectorRibbonCompose>(); }
   19.99 +        }
  19.100 +    }
  19.101 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/UI/Ribbon/InspectorRibbonCompose.cs	Fri Jul 14 14:26:43 2017 +0200
    20.3 @@ -0,0 +1,142 @@
    20.4 +using Microsoft.Office.Tools.Ribbon;
    20.5 +using System;
    20.6 +using System.ComponentModel;
    20.7 +using Outlook = Microsoft.Office.Interop.Outlook;
    20.8 +
    20.9 +namespace pEp
   20.10 +{
   20.11 +    public partial class InspectorRibbonCompose
   20.12 +    {
   20.13 +        private DraftMailItem   internalDraftMailItem   = null;
   20.14 +        private bool            isEnabled               = true;
   20.15 +
   20.16 +        /// <summary>
   20.17 +        /// Event handler fom when this ribbon group is loaded.
   20.18 +        /// </summary>
   20.19 +        private void InspectorRibbonCompose_Load(object sender, RibbonUIEventArgs e)
   20.20 +        {
   20.21 +            Outlook.MailItem omi = null;
   20.22 +
   20.23 +            // Hook up this inspector's mail item as DraftMailItem and update UI
   20.24 +            try
   20.25 +            {
   20.26 +                omi = (this.Context as Outlook.Inspector)?.CurrentItem as Outlook.MailItem;
   20.27 +
   20.28 +                if (omi != null &&
   20.29 +                    omi.GetIsPEPEnabled())
   20.30 +                {
   20.31 +                    // Create draft item and subscribe to property change event
   20.32 +                    internalDraftMailItem = new DraftMailItem(omi);
   20.33 +                    internalDraftMailItem.PropertyChanged += MailItem_PropertyChanged;
   20.34 +
   20.35 +                    // Update the UI
   20.36 +                    var rating = omi.GetOutgoingRating();
   20.37 +                    this.pEpGroupInspector.UpdatePEPGroup(rating);
   20.38 +                }
   20.39 +                else
   20.40 +                {
   20.41 +                    omi = null;
   20.42 +                    this.isEnabled = false;
   20.43 +                    this.pEpGroupInspector.Visible = false;
   20.44 +                }
   20.45 +            }
   20.46 +            catch (Exception ex)
   20.47 +            {
   20.48 +                Log.Error("InspectorRibbonCompose_Load: Error. " + ex.ToString());
   20.49 +            }
   20.50 +            finally
   20.51 +            {
   20.52 +                omi = null;
   20.53 +            }
   20.54 +        }
   20.55 +
   20.56 +        /// <summary>
   20.57 +        /// Event handler for when a property of the draft mail item changes.
   20.58 +        /// </summary>
   20.59 +        private void MailItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
   20.60 +        {
   20.61 +            switch (e.PropertyName?.ToUpperInvariant())
   20.62 +            {
   20.63 +                case "BCC":
   20.64 +                    {
   20.65 +                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   20.66 +                        break;
   20.67 +                    }
   20.68 +                case "CC":
   20.69 +                    {
   20.70 +                        // Outlook always fires Bcc, Cc and To together so only "TO" is used
   20.71 +                        break;
   20.72 +                    }
   20.73 +                case "SENTONBEHALFOFNAME":
   20.74 +                    {
   20.75 +                        // Always fired with "SENDUSINGACCOUNT" so is ignored
   20.76 +                        break;
   20.77 +                    }
   20.78 +                case "SENDUSINGACCOUNT":
   20.79 +                    {
   20.80 +                        Outlook.MailItem omi = null;
   20.81 +
   20.82 +                        try
   20.83 +                        {
   20.84 +                            omi = (this.Context as Outlook.Inspector)?.CurrentItem as Outlook.MailItem;
   20.85 +
   20.86 +                            // Update pEp enabled status
   20.87 +                            this.isEnabled = omi?.GetIsPEPEnabled() ?? false;
   20.88 +
   20.89 +                            if (this.isEnabled)
   20.90 +                            {
   20.91 +                                // Refresh the UI
   20.92 +                                omi.Recipients.ResolveAll();
   20.93 +                                var rating = omi.GetOutgoingRating();
   20.94 +                                this.pEpGroupInspector.UpdatePEPGroup(rating);
   20.95 +                            }
   20.96 +                            else
   20.97 +                            {
   20.98 +                                this.pEpGroupInspector.Visible = false;
   20.99 +                            }
  20.100 +                        }
  20.101 +                        catch (Exception ex)
  20.102 +                        {
  20.103 +                            Log.Error("MailItem_PropertyChange: Error. " + ex.ToString());
  20.104 +                        }
  20.105 +                        finally
  20.106 +                        {
  20.107 +                            omi = null;
  20.108 +                        }
  20.109 +
  20.110 +                        break;
  20.111 +                    }
  20.112 +                case "TO":
  20.113 +                    {
  20.114 +                        Outlook.MailItem omi = null;
  20.115 +
  20.116 +                        try
  20.117 +                        {
  20.118 +                            omi = (this.Context as Outlook.Inspector)?.CurrentItem as Outlook.MailItem;
  20.119 +
  20.120 +                            if (omi != null)
  20.121 +                            {
  20.122 +                                // Refresh the UI
  20.123 +                                var rating = omi.GetOutgoingRating();
  20.124 +                                this.pEpGroupInspector.UpdatePEPGroup(rating);
  20.125 +                            }
  20.126 +                            else
  20.127 +                            {
  20.128 +                                this.pEpGroupInspector.Visible = false;
  20.129 +                            }
  20.130 +                        }
  20.131 +                        catch (Exception ex)
  20.132 +                        {
  20.133 +                            Log.Error("MailItem_PropertyChange: Error. " + ex.ToString());
  20.134 +                        }
  20.135 +                        finally
  20.136 +                        {
  20.137 +                            omi = null;
  20.138 +                        }
  20.139 +
  20.140 +                        break;
  20.141 +                    }
  20.142 +            }
  20.143 +        }
  20.144 +    }
  20.145 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/UI/Ribbon/InspectorRibbonRead.Designer.cs	Fri Jul 14 14:26:43 2017 +0200
    21.3 @@ -0,0 +1,96 @@
    21.4 +namespace pEp
    21.5 +{
    21.6 +    partial class InspectorRibbonRead : Microsoft.Office.Tools.Ribbon.RibbonBase
    21.7 +    {
    21.8 +        /// <summary>
    21.9 +        /// Required designer variable.
   21.10 +        /// </summary>
   21.11 +        private System.ComponentModel.IContainer components = null;
   21.12 +
   21.13 +        public InspectorRibbonRead()
   21.14 +            : base(Globals.Factory.GetRibbonFactory())
   21.15 +        {
   21.16 +            InitializeComponent();
   21.17 +        }
   21.18 +
   21.19 +        /// <summary>
   21.20 +        /// Clean up any resources being used.
   21.21 +        /// </summary>
   21.22 +        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
   21.23 +        protected override void Dispose(bool disposing)
   21.24 +        {
   21.25 +            if (disposing && (components != null))
   21.26 +            {
   21.27 +                components.Dispose();
   21.28 +            }
   21.29 +            base.Dispose(disposing);
   21.30 +        }
   21.31 +
   21.32 +        #region Component Designer generated code
   21.33 +
   21.34 +        /// <summary>
   21.35 +        /// Required method for Designer support - do not modify
   21.36 +        /// the contents of this method with the code editor.
   21.37 +        /// </summary>
   21.38 +        private void InitializeComponent()
   21.39 +        {
   21.40 +            this.tab1 = this.Factory.CreateRibbonTab();
   21.41 +            this.pEpGroupInspector = this.Factory.CreateRibbonGroup();
   21.42 +            this.pEpButton = this.Factory.CreateRibbonButton();
   21.43 +            this.tab1.SuspendLayout();
   21.44 +            this.pEpGroupInspector.SuspendLayout();
   21.45 +            this.SuspendLayout();
   21.46 +            // 
   21.47 +            // tab1
   21.48 +            // 
   21.49 +            this.tab1.ControlId.ControlIdType = Microsoft.Office.Tools.Ribbon.RibbonControlIdType.Office;
   21.50 +            this.tab1.ControlId.OfficeId = "TabReadMessage";
   21.51 +            this.tab1.Groups.Add(this.pEpGroupInspector);
   21.52 +            this.tab1.Label = "TabReadMessage";
   21.53 +            this.tab1.Name = "tab1";
   21.54 +            // 
   21.55 +            // pEpGroupInspector
   21.56 +            // 
   21.57 +            this.pEpGroupInspector.Items.Add(this.pEpButton);
   21.58 +            this.pEpGroupInspector.Label = "pEp";
   21.59 +            this.pEpGroupInspector.Name = "pEpGroupInspector";
   21.60 +            this.pEpGroupInspector.Position = this.Factory.RibbonPosition.AfterOfficeId("GroupZoom");
   21.61 +            // 
   21.62 +            // pEpButton
   21.63 +            // 
   21.64 +            this.pEpButton.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
   21.65 +            this.pEpButton.Image = global::pEp.Properties.Resources.ImagePrivacyStatusNoColor;
   21.66 +            this.pEpButton.Label = "pEp";
   21.67 +            this.pEpButton.Name = "pEpButton";
   21.68 +            this.pEpButton.ShowImage = true;
   21.69 +            this.pEpButton.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.pEpButton_Click);
   21.70 +            // 
   21.71 +            // InspectorRibbonRead
   21.72 +            // 
   21.73 +            this.Name = "InspectorRibbonRead";
   21.74 +            this.RibbonType = "Microsoft.Outlook.Mail.Read";
   21.75 +            this.Tabs.Add(this.tab1);
   21.76 +            this.Load += new Microsoft.Office.Tools.Ribbon.RibbonUIEventHandler(this.InspectorRibbon_Load);
   21.77 +            this.tab1.ResumeLayout(false);
   21.78 +            this.tab1.PerformLayout();
   21.79 +            this.pEpGroupInspector.ResumeLayout(false);
   21.80 +            this.pEpGroupInspector.PerformLayout();
   21.81 +            this.ResumeLayout(false);
   21.82 +
   21.83 +        }
   21.84 +
   21.85 +        #endregion
   21.86 +
   21.87 +        internal Microsoft.Office.Tools.Ribbon.RibbonTab tab1;
   21.88 +        internal Microsoft.Office.Tools.Ribbon.RibbonGroup pEpGroupInspector;
   21.89 +        internal Microsoft.Office.Tools.Ribbon.RibbonButton pEpButton;
   21.90 +    }
   21.91 +
   21.92 +    partial class ThisRibbonCollection
   21.93 +    {
   21.94 +        internal InspectorRibbonRead InspectorRibbonRead
   21.95 +        {
   21.96 +            get { return this.GetRibbon<InspectorRibbonRead>(); }
   21.97 +        }
   21.98 +    }
   21.99 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/UI/Ribbon/InspectorRibbonRead.cs	Fri Jul 14 14:26:43 2017 +0200
    22.3 @@ -0,0 +1,48 @@
    22.4 +using Microsoft.Office.Tools.Ribbon;
    22.5 +using pEpCOMServerAdapterLib;
    22.6 +using Outlook = Microsoft.Office.Interop.Outlook;
    22.7 +
    22.8 +namespace pEp
    22.9 +{
   22.10 +    public partial class InspectorRibbonRead
   22.11 +    {
   22.12 +        private void InspectorRibbon_Load(object sender, RibbonUIEventArgs e)
   22.13 +        {
   22.14 +            Outlook.MailItem omi = null;
   22.15 +            PEPMessage message = null;
   22.16 +            pEpRating rating = pEpRating.pEpRatingUndefined;
   22.17 +
   22.18 +            omi = (this.Context as Outlook.Inspector)?.CurrentItem as Outlook.MailItem;
   22.19 +
   22.20 +            if (omi != null)
   22.21 +            {
   22.22 +                if (PEPMessage.Create(omi, out message) == Globals.ReturnStatus.Success)
   22.23 +                {
   22.24 +                    rating = AdapterExtensions.ReevaluateMessageRating(message);
   22.25 +                }
   22.26 +                else
   22.27 +                {
   22.28 +                    Log.Error("InspectorRibbon_Load: Error creating MsgContainer.");
   22.29 +                }
   22.30 +
   22.31 +                this.pEpGroupInspector.UpdatePEPGroup(rating);
   22.32 +
   22.33 +                omi = null;
   22.34 +            }
   22.35 +        }
   22.36 +
   22.37 +        private void pEpButton_Click(object sender, RibbonControlEventArgs e)
   22.38 +        {
   22.39 +            Outlook.MailItem omi = (this.Context as Outlook.Inspector)?.CurrentItem as Outlook.MailItem;
   22.40 +
   22.41 +            if (omi != null)
   22.42 +            {
   22.43 +                
   22.44 +            }
   22.45 +            else
   22.46 +            {
   22.47 +                Log.Error("pEpButton_Click: Mail item is null.");
   22.48 +            }
   22.49 +        }
   22.50 +    }
   22.51 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/UI/Ribbon/InspectorRibbonRead.resx	Fri Jul 14 14:26:43 2017 +0200
    23.3 @@ -0,0 +1,120 @@
    23.4 +<?xml version="1.0" encoding="utf-8"?>
    23.5 +<root>
    23.6 +  <!-- 
    23.7 +    Microsoft ResX Schema 
    23.8 +    
    23.9 +    Version 2.0
   23.10 +    
   23.11 +    The primary goals of this format is to allow a simple XML format 
   23.12 +    that is mostly human readable. The generation and parsing of the 
   23.13 +    various data types are done through the TypeConverter classes 
   23.14 +    associated with the data types.
   23.15 +    
   23.16 +    Example:
   23.17 +    
   23.18 +    ... ado.net/XML headers & schema ...
   23.19 +    <resheader name="resmimetype">text/microsoft-resx</resheader>
   23.20 +    <resheader name="version">2.0</resheader>
   23.21 +    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
   23.22 +    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
   23.23 +    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
   23.24 +    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
   23.25 +    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
   23.26 +        <value>[base64 mime encoded serialized .NET Framework object]</value>
   23.27 +    </data>
   23.28 +    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
   23.29 +        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
   23.30 +        <comment>This is a comment</comment>
   23.31 +    </data>
   23.32 +                
   23.33 +    There are any number of "resheader" rows that contain simple 
   23.34 +    name/value pairs.
   23.35 +    
   23.36 +    Each data row contains a name, and value. The row also contains a 
   23.37 +    type or mimetype. Type corresponds to a .NET class that support 
   23.38 +    text/value conversion through the TypeConverter architecture. 
   23.39 +    Classes that don't support this are serialized and stored with the 
   23.40 +    mimetype set.
   23.41 +    
   23.42 +    The mimetype is used for serialized objects, and tells the 
   23.43 +    ResXResourceReader how to depersist the object. This is currently not 
   23.44 +    extensible. For a given mimetype the value must be set accordingly:
   23.45 +    
   23.46 +    Note - application/x-microsoft.net.object.binary.base64 is the format 
   23.47 +    that the ResXResourceWriter will generate, however the reader can 
   23.48 +    read any of the formats listed below.
   23.49 +    
   23.50 +    mimetype: application/x-microsoft.net.object.binary.base64
   23.51 +    value   : The object must be serialized with 
   23.52 +            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
   23.53 +            : and then encoded with base64 encoding.
   23.54 +    
   23.55 +    mimetype: application/x-microsoft.net.object.soap.base64
   23.56 +    value   : The object must be serialized with 
   23.57 +            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
   23.58 +            : and then encoded with base64 encoding.
   23.59 +
   23.60 +    mimetype: application/x-microsoft.net.object.bytearray.base64
   23.61 +    value   : The object must be serialized into a byte array 
   23.62 +            : using a System.ComponentModel.TypeConverter
   23.63 +            : and then encoded with base64 encoding.
   23.64 +    -->
   23.65 +  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
   23.66 +    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
   23.67 +    <xsd:element name="root" msdata:IsDataSet="true">
   23.68 +      <xsd:complexType>
   23.69 +        <xsd:choice maxOccurs="unbounded">
   23.70 +          <xsd:element name="metadata">
   23.71 +            <xsd:complexType>
   23.72 +              <xsd:sequence>
   23.73 +                <xsd:element name="value" type="xsd:string" minOccurs="0" />
   23.74 +              </xsd:sequence>
   23.75 +              <xsd:attribute name="name" use="required" type="xsd:string" />
   23.76 +              <xsd:attribute name="type" type="xsd:string" />
   23.77 +              <xsd:attribute name="mimetype" type="xsd:string" />
   23.78 +              <xsd:attribute ref="xml:space" />
   23.79 +            </xsd:complexType>
   23.80 +          </xsd:element>
   23.81 +          <xsd:element name="assembly">
   23.82 +            <xsd:complexType>
   23.83 +              <xsd:attribute name="alias" type="xsd:string" />
   23.84 +              <xsd:attribute name="name" type="xsd:string" />
   23.85 +            </xsd:complexType>
   23.86 +          </xsd:element>
   23.87 +          <xsd:element name="data">
   23.88 +            <xsd:complexType>
   23.89 +              <xsd:sequence>
   23.90 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
   23.91 +                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
   23.92 +              </xsd:sequence>
   23.93 +              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
   23.94 +              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
   23.95 +              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
   23.96 +              <xsd:attribute ref="xml:space" />
   23.97 +            </xsd:complexType>
   23.98 +          </xsd:element>
   23.99 +          <xsd:element name="resheader">
  23.100 +            <xsd:complexType>
  23.101 +              <xsd:sequence>
  23.102 +                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
  23.103 +              </xsd:sequence>
  23.104 +              <xsd:attribute name="name" type="xsd:string" use="required" />
  23.105 +            </xsd:complexType>
  23.106 +          </xsd:element>
  23.107 +        </xsd:choice>
  23.108 +      </xsd:complexType>
  23.109 +    </xsd:element>
  23.110 +  </xsd:schema>
  23.111 +  <resheader name="resmimetype">
  23.112 +    <value>text/microsoft-resx</value>
  23.113 +  </resheader>
  23.114 +  <resheader name="version">
  23.115 +    <value>2.0</value>
  23.116 +  </resheader>
  23.117 +  <resheader name="reader">
  23.118 +    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  23.119 +  </resheader>
  23.120 +  <resheader name="writer">
  23.121 +    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  23.122 +  </resheader>
  23.123 +</root>
  23.124 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/UI/Ribbon/RibbonExtensions.cs	Fri Jul 14 14:26:43 2017 +0200
    24.3 @@ -0,0 +1,179 @@
    24.4 +using Microsoft.Office.Tools.Ribbon;
    24.5 +using pEpCOMServerAdapterLib;
    24.6 +using System;
    24.7 +
    24.8 +namespace pEp
    24.9 +{
   24.10 +    /// <summary>
   24.11 +    /// Contains extension methods for the pEp Ribbon Group and its components
   24.12 +    /// </summary>
   24.13 +    internal static class RibbonExtensions
   24.14 +    {
   24.15 +        /// <summary>
   24.16 +        /// Updates the image and label of the pEp button according to the given rating
   24.17 +        /// </summary>
   24.18 +        /// <param name="pEpButton">The pEp button to update</param>
   24.19 +        /// <param name="rating">The rating that determines the button's appearance</param>
   24.20 +        public static void UpdateButton(this RibbonButton pEpButton, pEpRating rating)
   24.21 +        {
   24.22 +            try
   24.23 +            {
   24.24 +                pEpButton.Image = GetPEPButtonImage(rating);
   24.25 +                pEpButton.Label = GetPEPButtonLabel(rating);
   24.26 +            }
   24.27 +            catch (Exception ex)
   24.28 +            {
   24.29 +                Log.Error("UpdateButton. Error occured. " + ex.ToString());
   24.30 +            }
   24.31 +        }
   24.32 +
   24.33 +        /// <summary>
   24.34 +        /// Updates the image and label of the pEp button according to the given rating
   24.35 +        /// </summary>
   24.36 +        /// <param name="pEpButton">The pEp button to update</param>
   24.37 +        /// <param name="rating">The rating that determines the button's appearance</param>
   24.38 +        public static void UpdateButton(this RibbonSplitButton pEpButton, pEpRating rating)
   24.39 +        {
   24.40 +            try
   24.41 +            {
   24.42 +                pEpButton.Image = GetPEPButtonImage(rating);
   24.43 +                pEpButton.Label = GetPEPButtonLabel(rating);
   24.44 +            }
   24.45 +            catch (Exception ex)
   24.46 +            {
   24.47 +                Log.Error("UpdateButton. Error occured. " + ex.ToString());
   24.48 +            }
   24.49 +        }
   24.50 +
   24.51 +        /// <summary>
   24.52 +        /// Updates pEp Ribbon Group according to the given rating
   24.53 +        /// </summary>
   24.54 +        /// <param name="ribbonGroup">The RibbonGroup to update</param>
   24.55 +        /// <param name="rating">The rating that determines the group's appearance</param>
   24.56 +        public static void UpdatePEPGroup(this RibbonGroup ribbonGroup, pEpRating rating)
   24.57 +        {
   24.58 +            ribbonGroup.UpdateVisibility(rating);
   24.59 +
   24.60 +            if (ribbonGroup.Visible)
   24.61 +            {
   24.62 +                foreach (var item in ribbonGroup.Items)
   24.63 +                {
   24.64 +                    if (item is RibbonButton)
   24.65 +                    {
   24.66 +                        (item as RibbonButton)?.UpdateButton(rating);
   24.67 +                    }
   24.68 +                    else if (item is RibbonSplitButton)
   24.69 +                    {
   24.70 +                        (item as RibbonSplitButton)?.UpdateButton(rating);
   24.71 +                    }
   24.72 +                }
   24.73 +            }     
   24.74 +        }
   24.75 +
   24.76 +        /// <summary>
   24.77 +        /// Determines the RibbonGroup's visibility according to a given rating.
   24.78 +        /// </summary>
   24.79 +        /// <param name="ribbonGroup">The RibbonGroup to update its visibility</param>
   24.80 +        /// <param name="rating">The rating that determines the visibility</param>
   24.81 +        public static void UpdateVisibility(this RibbonGroup ribbonGroup, pEpRating rating)
   24.82 +        {
   24.83 +            switch (rating)
   24.84 +            {
   24.85 +                case pEpRating.pEpRatingMistrust:
   24.86 +                case pEpRating.pEpRatingB0rken:
   24.87 +                case pEpRating.pEpRatingUnderAttack:
   24.88 +                case pEpRating.pEpRatingReliable:
   24.89 +                case pEpRating.pEpRatingTrusted:
   24.90 +                case pEpRating.pEpRatingTrustedAndAnonymized:
   24.91 +                case pEpRating.pEpRatingFullyAnonymous:
   24.92 +                    try
   24.93 +                    {
   24.94 +                        ribbonGroup.Visible = true;
   24.95 +                    }
   24.96 +                    catch (Exception ex)
   24.97 +                    {
   24.98 +                        Log.Error("UpdateVisibility. Error occured. " + ex.ToString());
   24.99 +                    }
  24.100 +                    break;
  24.101 +                case pEpRating.pEpRatingCannotDecrypt:
  24.102 +                case pEpRating.pEpRatingHaveNoKey:
  24.103 +                case pEpRating.pEpRatingUnencrypted:
  24.104 +                case pEpRating.pEpRatingUnencryptedForSome:
  24.105 +                case pEpRating.pEpRatingUnreliable:
  24.106 +                case pEpRating.pEpRatingUndefined:
  24.107 +                default:
  24.108 +                    try
  24.109 +                    {
  24.110 +                        ribbonGroup.Visible = false;
  24.111 +                    }
  24.112 +                    catch (Exception ex)
  24.113 +                    {
  24.114 +                        Log.Error("UpdateVisibility. Error occured. " + ex.ToString());
  24.115 +                    }
  24.116 +                    break;
  24.117 +            }
  24.118 +        }
  24.119 +
  24.120 +        /// <summary>
  24.121 +        /// Gets the image for the pEp button depending on the rating.
  24.122 +        /// </summary>
  24.123 +        public static System.Drawing.Bitmap GetPEPButtonImage(pEpRating rating)
  24.124 +        {
  24.125 +            switch (rating)
  24.126 +            {
  24.127 +                case pEpRating.pEpRatingMistrust:
  24.128 +                case pEpRating.pEpRatingB0rken:
  24.129 +                case pEpRating.pEpRatingUnderAttack:
  24.130 +                    return Properties.Resources.ImageRatingRed;
  24.131 +                case pEpRating.pEpRatingReliable:
  24.132 +                    return Properties.Resources.ImageRatingYellow;
  24.133 +                case pEpRating.pEpRatingTrusted:
  24.134 +                case pEpRating.pEpRatingTrustedAndAnonymized:
  24.135 +                case pEpRating.pEpRatingFullyAnonymous:
  24.136 +                    return Properties.Resources.ImageRatingGreen;
  24.137 +                case pEpRating.pEpRatingUndefined:
  24.138 +                case pEpRating.pEpRatingCannotDecrypt:
  24.139 +                case pEpRating.pEpRatingHaveNoKey:
  24.140 +                case pEpRating.pEpRatingUnencrypted:
  24.141 +                case pEpRating.pEpRatingUnencryptedForSome:
  24.142 +                case pEpRating.pEpRatingUnreliable:
  24.143 +                default:
  24.144 +                    return Properties.Resources.ImagePrivacyStatusNoColor;
  24.145 +            }
  24.146 +        }
  24.147 +
  24.148 +        /// <summary>
  24.149 +        /// Gets the label text for the pEp button depending on the rating.
  24.150 +        /// </summary>
  24.151 +        public static string GetPEPButtonLabel(pEpRating rating)
  24.152 +        {
  24.153 +            switch (rating)
  24.154 +            {
  24.155 +                case pEpRating.pEpRatingMistrust:
  24.156 +                    return Properties.Resources.PrivacyStatus_RatingMistrustText;
  24.157 +                case pEpRating.pEpRatingB0rken:
  24.158 +                    return Properties.Resources.PrivacyStatus_RatingBrokenText;
  24.159 +                case pEpRating.pEpRatingUnderAttack:
  24.160 +                    return Properties.Resources.PrivacyStatus_RatingUnderAttackText;
  24.161 +                case pEpRating.pEpRatingReliable:
  24.162 +                    return Properties.Resources.PrivacyStatus_RatingReliableText;
  24.163 +                case pEpRating.pEpRatingTrusted:
  24.164 +                case pEpRating.pEpRatingTrustedAndAnonymized:
  24.165 +                case pEpRating.pEpRatingFullyAnonymous:
  24.166 +                    return Properties.Resources.PrivacyStatus_RatingTrustedText;
  24.167 +                case pEpRating.pEpRatingCannotDecrypt:
  24.168 +                case pEpRating.pEpRatingHaveNoKey:
  24.169 +                    return Properties.Resources.PrivacyStatus_RatingHaveNoKeyText;
  24.170 +                case pEpRating.pEpRatingUnencrypted:
  24.171 +                    return Properties.Resources.PrivacyStatus_RatingUnencryptedText;
  24.172 +                case pEpRating.pEpRatingUnencryptedForSome:
  24.173 +                    return Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeText;
  24.174 +                case pEpRating.pEpRatingUnreliable:
  24.175 +                    return Properties.Resources.PrivacyStatus_RatingUnreliableText;
  24.176 +                case pEpRating.pEpRatingUndefined:
  24.177 +                default:
  24.178 +                    return Properties.Resources.PrivacyStatus_RatingUndefinedText;
  24.179 +            }
  24.180 +        }
  24.181 +    }
  24.182 +}
    25.1 --- a/UI/RibbonExtensions.cs	Thu Jul 13 13:26:16 2017 +0200
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,136 +0,0 @@
    25.4 -using Microsoft.Office.Tools.Ribbon;
    25.5 -using pEpCOMServerAdapterLib;
    25.6 -using System;
    25.7 -
    25.8 -namespace pEp
    25.9 -{
   25.10 -    internal static class RibbonExtensions
   25.11 -    {
   25.12 -        public static void UpdateButton(this RibbonButton pEpButton, pEpRating rating)
   25.13 -        {
   25.14 -            try
   25.15 -            {
   25.16 -                pEpButton.Image = GetPEPButtonImage(rating);
   25.17 -                pEpButton.Label = GetPEPButtonLabel(rating);
   25.18 -            }
   25.19 -            catch (Exception ex)
   25.20 -            {
   25.21 -                Log.Error("UpdateButton. Error occured. " + ex.ToString());
   25.22 -            }
   25.23 -        }
   25.24 -
   25.25 -        public static void UpdateButton(this RibbonSplitButton pEpButton, pEpRating rating)
   25.26 -        {
   25.27 -            try
   25.28 -            {
   25.29 -                pEpButton.Image = GetPEPButtonImage(rating);
   25.30 -                pEpButton.Label = GetPEPButtonLabel(rating);
   25.31 -            }
   25.32 -            catch (Exception ex)
   25.33 -            {
   25.34 -                Log.Error("UpdateButton. Error occured. " + ex.ToString());
   25.35 -            }
   25.36 -        }
   25.37 -
   25.38 -        public static void UpdateVisibility(this RibbonGroup ribbonGroup, pEpRating rating)
   25.39 -        {
   25.40 -            switch (rating)
   25.41 -            {
   25.42 -                case pEpRating.pEpRatingMistrust:
   25.43 -                case pEpRating.pEpRatingB0rken:
   25.44 -                case pEpRating.pEpRatingUnderAttack:
   25.45 -                case pEpRating.pEpRatingReliable:
   25.46 -                case pEpRating.pEpRatingTrusted:
   25.47 -                case pEpRating.pEpRatingTrustedAndAnonymized:
   25.48 -                case pEpRating.pEpRatingFullyAnonymous:
   25.49 -                    try
   25.50 -                    {
   25.51 -                        ribbonGroup.Visible = true;
   25.52 -                    }
   25.53 -                    catch (Exception ex)
   25.54 -                    {
   25.55 -                        Log.Error("UpdateVisibility. Error occured. " + ex.ToString());
   25.56 -                    }
   25.57 -                    break;
   25.58 -                case pEpRating.pEpRatingCannotDecrypt:
   25.59 -                case pEpRating.pEpRatingHaveNoKey:
   25.60 -                case pEpRating.pEpRatingUnencrypted:
   25.61 -                case pEpRating.pEpRatingUnencryptedForSome:
   25.62 -                case pEpRating.pEpRatingUnreliable:
   25.63 -                case pEpRating.pEpRatingUndefined:
   25.64 -                default:
   25.65 -                    try
   25.66 -                    {
   25.67 -                        ribbonGroup.Visible = false;
   25.68 -                    }
   25.69 -                    catch (Exception ex)
   25.70 -                    {
   25.71 -                        Log.Error("UpdateVisibility. Error occured. " + ex.ToString());
   25.72 -                    }
   25.73 -                    break;
   25.74 -            }
   25.75 -        }
   25.76 -
   25.77 -        /// <summary>
   25.78 -        /// Gets the image for the pEp button depending on the rating.
   25.79 -        /// </summary>
   25.80 -        public static System.Drawing.Bitmap GetPEPButtonImage(pEpRating rating)
   25.81 -        {
   25.82 -            switch (rating)
   25.83 -            {
   25.84 -                case pEpRating.pEpRatingMistrust:
   25.85 -                case pEpRating.pEpRatingB0rken:
   25.86 -                case pEpRating.pEpRatingUnderAttack:
   25.87 -                    return Properties.Resources.ImageRatingRed;
   25.88 -                case pEpRating.pEpRatingReliable:
   25.89 -                    return Properties.Resources.ImageRatingYellow;
   25.90 -                case pEpRating.pEpRatingTrusted:
   25.91 -                case pEpRating.pEpRatingTrustedAndAnonymized:
   25.92 -                case pEpRating.pEpRatingFullyAnonymous:
   25.93 -                    return Properties.Resources.ImageRatingGreen;
   25.94 -                case pEpRating.pEpRatingUndefined:
   25.95 -                case pEpRating.pEpRatingCannotDecrypt:
   25.96 -                case pEpRating.pEpRatingHaveNoKey:
   25.97 -                case pEpRating.pEpRatingUnencrypted:
   25.98 -                case pEpRating.pEpRatingUnencryptedForSome:
   25.99 -                case pEpRating.pEpRatingUnreliable:
  25.100 -                default:
  25.101 -                    return Properties.Resources.ImagePrivacyStatusNoColor;
  25.102 -            }
  25.103 -        }
  25.104 -
  25.105 -        /// <summary>
  25.106 -        /// Gets the label text for the pEp button depending on the rating.
  25.107 -        /// </summary>
  25.108 -        public static string GetPEPButtonLabel(pEpRating rating)
  25.109 -        {
  25.110 -            switch (rating)
  25.111 -            {
  25.112 -                case pEpRating.pEpRatingMistrust:
  25.113 -                    return Properties.Resources.PrivacyStatus_RatingMistrustText;
  25.114 -                case pEpRating.pEpRatingB0rken:
  25.115 -                    return Properties.Resources.PrivacyStatus_RatingBrokenText;
  25.116 -                case pEpRating.pEpRatingUnderAttack:
  25.117 -                    return Properties.Resources.PrivacyStatus_RatingUnderAttackText;
  25.118 -                case pEpRating.pEpRatingReliable:
  25.119 -                    return Properties.Resources.PrivacyStatus_RatingReliableText;
  25.120 -                case pEpRating.pEpRatingTrusted:
  25.121 -                case pEpRating.pEpRatingTrustedAndAnonymized:
  25.122 -                case pEpRating.pEpRatingFullyAnonymous:
  25.123 -                    return Properties.Resources.PrivacyStatus_RatingTrustedText;
  25.124 -                case pEpRating.pEpRatingCannotDecrypt:
  25.125 -                case pEpRating.pEpRatingHaveNoKey:
  25.126 -                    return Properties.Resources.PrivacyStatus_RatingHaveNoKeyText;
  25.127 -                case pEpRating.pEpRatingUnencrypted:
  25.128 -                    return Properties.Resources.PrivacyStatus_RatingUnencryptedText;
  25.129 -                case pEpRating.pEpRatingUnencryptedForSome:
  25.130 -                    return Properties.Resources.PrivacyStatus_RatingUnencryptedForSomeText;
  25.131 -                case pEpRating.pEpRatingUnreliable:
  25.132 -                    return Properties.Resources.PrivacyStatus_RatingUnreliableText;
  25.133 -                case pEpRating.pEpRatingUndefined:
  25.134 -                default:
  25.135 -                    return Properties.Resources.PrivacyStatus_RatingUndefinedText;
  25.136 -            }
  25.137 -        }
  25.138 -    }
  25.139 -}
    26.1 --- a/WatchedExplorer.cs	Thu Jul 13 13:26:16 2017 +0200
    26.2 +++ b/WatchedExplorer.cs	Fri Jul 14 14:26:43 2017 +0200
    26.3 @@ -20,6 +20,7 @@
    26.4          private Outlook.MailItem             currentMailItem            = null;
    26.5          private Stack<string>                decryptionStack            = new Stack<string>();
    26.6          private object                       mutexDecryptionStack       = new object();
    26.7 +        private DraftMailItem                inlineResponseItem         = null;
    26.8  
    26.9          /**************************************************************
   26.10           * 
   26.11 @@ -41,6 +42,7 @@
   26.12                  ((Outlook.ExplorerEvents_10_Event)this.explorer).SelectionChange += WatchedExplorer_SelectionChange;
   26.13                  ((Outlook.ExplorerEvents_10_Event)this.explorer).BeforeFolderSwitch += WatchedExplorer_BeforeFolderSwitch;
   26.14                  ((Outlook.ExplorerEvents_10_Event)this.explorer).InlineResponse += WatchedExplorer_InlineResponse;
   26.15 +                ((Outlook.ExplorerEvents_10_Event)this.explorer).InlineResponseClose += WatchedExplorer_InlineResponseClose;
   26.16  
   26.17                  this.currentFolder = this.explorer.CurrentFolder as Outlook.Folder;
   26.18                  this.ConnectFolderEvents(this.currentFolder);
   26.19 @@ -118,6 +120,7 @@
   26.20                  ((Outlook.ExplorerEvents_10_Event)this.explorer).SelectionChange -= WatchedExplorer_SelectionChange;
   26.21                  ((Outlook.ExplorerEvents_10_Event)this.explorer).BeforeFolderSwitch -= WatchedExplorer_BeforeFolderSwitch;
   26.22                  ((Outlook.ExplorerEvents_10_Event)this.explorer).InlineResponse -= WatchedExplorer_InlineResponse;
   26.23 +                ((Outlook.ExplorerEvents_10_Event)this.explorer).InlineResponseClose -= WatchedExplorer_InlineResponseClose;
   26.24  
   26.25                  this.DisconnectFolderEvents(this.currentFolder);
   26.26                  this.DisconnectMailItemEvents(this.currentMailItem);
   26.27 @@ -244,10 +247,24 @@
   26.28          /// <summary>
   26.29          /// Event handler for when an inline response is being opened
   26.30          /// </summary>
   26.31 -        /// <param name="Item"></param>
   26.32 -        private void WatchedExplorer_InlineResponse(object Item)
   26.33 +        /// <param name="item"></param>
   26.34 +        private void WatchedExplorer_InlineResponse(object item)
   26.35          {
   26.36 -            
   26.37 +            Outlook.MailItem omi = item as Outlook.MailItem;
   26.38 +
   26.39 +            if (omi != null)
   26.40 +            {
   26.41 +                this.inlineResponseItem = new DraftMailItem(omi);
   26.42 +            }
   26.43 +        }
   26.44 +
   26.45 +        /// <summary>
   26.46 +        /// Event handler for when an inline response is being closed
   26.47 +        /// </summary>
   26.48 +        private void WatchedExplorer_InlineResponseClose()
   26.49 +        {
   26.50 +            this.inlineResponseItem.Dispose();
   26.51 +            this.inlineResponseItem = null;
   26.52          }
   26.53  
   26.54          /// <summary>
   26.55 @@ -287,7 +304,7 @@
   26.56                          }
   26.57  
   26.58                          // Create message container and set mail item to null
   26.59 -                        if (MsgContainer.Create(omi, out msgContainer) != Globals.ReturnStatus.Success)
   26.60 +                        if (MsgContainer.Create(omi, out msgContainer, true) != Globals.ReturnStatus.Success)
   26.61                          {
   26.62                              throw new Exception("Error while creating MsgContainer. Processing skipped.");
   26.63                          }
   26.64 @@ -301,7 +318,7 @@
   26.65  
   26.66                          // Process mail item
   26.67                          var msgProcessor = new MsgProcessor();
   26.68 -                        msgProcessor.ProcessingCompleted2 += Explorer_ProcessingCompleted;
   26.69 +                        msgProcessor.ProcessingCompleted += Explorer_ProcessingCompleted;
   26.70                          msgProcessor.ProcessMailItem(msgContainer, true);
   26.71                      }
   26.72                  }
   26.73 @@ -320,7 +337,7 @@
   26.74          /// <summary>
   26.75          /// Event handler for when the processing of an item in the WatchedExplorer has finished.
   26.76          /// </summary>
   26.77 -        private void Explorer_ProcessingCompleted(object sender, MsgProcessor.ProcessingCompletedEventArgs2 e)
   26.78 +        private void Explorer_ProcessingCompleted(object sender, MsgProcessor.ProcessingCompletedEventArgs e)
   26.79          {
   26.80              string entryId = string.Empty;
   26.81              bool continueProcessing = false;
   26.82 @@ -347,6 +364,7 @@
   26.83                  if (msgProcessor != null)
   26.84                  {
   26.85                      msgProcessor.CompleteProcessing(e.Result, this.explorer, true);
   26.86 +                    msgProcessor.ProcessingCompleted -= Explorer_ProcessingCompleted;
   26.87                  }
   26.88              }
   26.89          }
    27.1 --- a/pEpForOutlook.csproj	Thu Jul 13 13:26:16 2017 +0200
    27.2 +++ b/pEpForOutlook.csproj	Fri Jul 14 14:26:43 2017 +0200
    27.3 @@ -281,6 +281,7 @@
    27.4      <Compile Include="AdapterCallbacks.cs" />
    27.5      <Compile Include="AdapterExtensions.cs" />
    27.6      <Compile Include="Comparisons.cs" />
    27.7 +    <Compile Include="DraftMailItem.cs" />
    27.8      <Compile Include="Extensions\AccountExtensions.cs" />
    27.9      <Compile Include="Extensions\ContactItemExtensions.cs" />
   27.10      <Compile Include="Extensions\StoreExtensions.cs" />
   27.11 @@ -351,10 +352,10 @@
   27.12        <DesignTime>True</DesignTime>
   27.13        <DependentUpon>Resources.zh.resx</DependentUpon>
   27.14      </Compile>
   27.15 -    <Compile Include="UI\ExplorerRibbon.cs">
   27.16 +    <Compile Include="UI\Ribbon\ExplorerRibbon.cs">
   27.17        <SubType>Component</SubType>
   27.18      </Compile>
   27.19 -    <Compile Include="UI\ExplorerRibbon.Designer.cs">
   27.20 +    <Compile Include="UI\Ribbon\ExplorerRibbon.Designer.cs">
   27.21        <DependentUpon>ExplorerRibbon.cs</DependentUpon>
   27.22      </Compile>
   27.23      <Compile Include="UI\FormControlCrashReport.xaml.cs">
   27.24 @@ -401,20 +402,20 @@
   27.25        <DependentUpon>HandshakeDialog.xaml</DependentUpon>
   27.26      </Compile>
   27.27      <Compile Include="UI\HandshakeItem.cs" />
   27.28 -    <Compile Include="UI\InspectorRibbonCompose.cs">
   27.29 +    <Compile Include="UI\Ribbon\InspectorRibbonCompose.cs">
   27.30        <SubType>Component</SubType>
   27.31      </Compile>
   27.32 -    <Compile Include="UI\InspectorRibbonCompose.Designer.cs">
   27.33 +    <Compile Include="UI\Ribbon\InspectorRibbonCompose.Designer.cs">
   27.34        <DependentUpon>InspectorRibbonCompose.cs</DependentUpon>
   27.35      </Compile>
   27.36 -    <Compile Include="UI\InspectorRibbonRead.cs">
   27.37 +    <Compile Include="UI\Ribbon\InspectorRibbonRead.cs">
   27.38        <SubType>Component</SubType>
   27.39      </Compile>
   27.40 -    <Compile Include="UI\InspectorRibbonRead.Designer.cs">
   27.41 +    <Compile Include="UI\Ribbon\InspectorRibbonRead.Designer.cs">
   27.42        <DependentUpon>InspectorRibbonRead.cs</DependentUpon>
   27.43      </Compile>
   27.44      <Compile Include="UI\RibbonCustomizations.cs" />
   27.45 -    <Compile Include="UI\RibbonExtensions.cs" />
   27.46 +    <Compile Include="UI\Ribbon\RibbonExtensions.cs" />
   27.47      <Compile Include="UI\SelectionItem.cs" />
   27.48      <Compile Include="Interfaces.cs" />
   27.49      <Compile Include="MsgConverter.cs" />
   27.50 @@ -494,6 +495,9 @@
   27.51        <LastGenOutput>Resources.mr.Designer.cs</LastGenOutput>
   27.52        <SubType>Designer</SubType>
   27.53      </EmbeddedResource>
   27.54 +    <EmbeddedResource Include="UI\Ribbon\InspectorRibbonRead.resx">
   27.55 +      <DependentUpon>InspectorRibbonRead.cs</DependentUpon>
   27.56 +    </EmbeddedResource>
   27.57      <None Include="app.config" />
   27.58      <None Include="packages.config" />
   27.59      <None Include="pep_test.snk" />
   27.60 @@ -524,12 +528,6 @@
   27.61      <WCFMetadata Include="Service References\" />
   27.62    </ItemGroup>
   27.63    <ItemGroup>
   27.64 -    <EmbeddedResource Include="UI\ExplorerRibbon.resx">
   27.65 -      <DependentUpon>ExplorerRibbon.cs</DependentUpon>
   27.66 -    </EmbeddedResource>
   27.67 -    <EmbeddedResource Include="UI\InspectorRibbonRead.resx">
   27.68 -      <DependentUpon>InspectorRibbonRead.cs</DependentUpon>
   27.69 -    </EmbeddedResource>
   27.70      <EmbeddedResource Include="UI\RibbonCustomizationsCompose.xml">
   27.71        <SubType>Designer</SubType>
   27.72      </EmbeddedResource>