OUT-590: Further implementation refactor_dialogs
authorThomas
Fri, 23 Aug 2019 14:51:16 +0200
branchrefactor_dialogs
changeset 2715f0fc49313372
parent 2714 9eaea1577fa4
child 2716 2a8a3732bbc2
OUT-590: Further implementation
FPPMessage.cs
Properties/Resources.Designer.cs
Properties/Resources.de.resx
Properties/Resources.es.resx
Properties/Resources.resx
Resources/Dictionary.xaml
UI/Dialog.cs
UI/Models/Dialog.cs
UI/ViewModels/HandshakeViewModel.cs
UI/ViewModels/IDialogWindowViewModel.cs
UI/ViewModels/SyncWizardViewModel.cs
UI/ViewModels/WizardGenericPageViewModel.cs
UI/ViewModels/WizardPageViewModelBase.cs
UI/ViewModels/WizardViewModelBase.cs
UI/Views/DialogWindow.xaml
UI/Views/DialogWindow.xaml.cs
UI/Views/HandshakeView.xaml
UI/Views/WizardView.xaml
Wrappers/WatchedWindow.cs
pEpForOutlook.csproj
     1.1 --- a/FPPMessage.cs	Thu Aug 22 17:04:24 2019 +0200
     1.2 +++ b/FPPMessage.cs	Fri Aug 23 14:51:16 2019 +0200
     1.3 @@ -43,8 +43,8 @@
     1.4          public const string PEP_FPP_ATTACHMENT_FILE_NAME                = "ignore_this_attachment.pEp";
     1.5          public const string PEP_FPP_ATTACHMENT_MIME_TYPE                = "application/pEp.forceProtected";
     1.6  
     1.7 -        private static HandshakeDialog              handshakeDialog     = null;
     1.8 -        private static Dictionary<KeyValuePair<string, MessageType>, DateTime> processedMessages   = new Dictionary<KeyValuePair<string, MessageType>, DateTime>();
     1.9 +        private static DialogWindow                                             handshakeDialog     = null;
    1.10 +        private static Dictionary<KeyValuePair<string, MessageType>, DateTime>  processedMessages   = new Dictionary<KeyValuePair<string, MessageType>, DateTime>();
    1.11  
    1.12          /// <summary>
    1.13          /// The message types that are supported by the FPP.
    1.14 @@ -844,11 +844,7 @@
    1.15                  // Show handshake dialog
    1.16                  if (handshakeDialog == null)
    1.17                  {
    1.18 -                    handshakeDialog = new HandshakeDialog(ownIdentity,
    1.19 -                                                          partnerIdentity,
    1.20 -                                                          mode);
    1.21 -
    1.22 -                    dialogResult = handshakeDialog.ShowDialog();
    1.23 +                    DialogWindow.CreateAndShow(Dialog.DialogType.ForceProtection, ownIdentity, partnerIdentity);
    1.24                  }
    1.25                  else
    1.26                  {
     2.1 --- a/Properties/Resources.Designer.cs	Thu Aug 22 17:04:24 2019 +0200
     2.2 +++ b/Properties/Resources.Designer.cs	Fri Aug 23 14:51:16 2019 +0200
     2.3 @@ -125,6 +125,15 @@
     2.4          }
     2.5          
     2.6          /// <summary>
     2.7 +        ///   Looks up a localized string similar to Not Now.
     2.8 +        /// </summary>
     2.9 +        public static string DialogWindow_NotNow {
    2.10 +            get {
    2.11 +                return ResourceManager.GetString("DialogWindow_NotNow", resourceCulture);
    2.12 +            }
    2.13 +        }
    2.14 +        
    2.15 +        /// <summary>
    2.16          ///   Looks up a localized string similar to Outlook Message Format.
    2.17          /// </summary>
    2.18          public static string DraftProtection_MSG_Format {
     3.1 --- a/Properties/Resources.de.resx	Thu Aug 22 17:04:24 2019 +0200
     3.2 +++ b/Properties/Resources.de.resx	Fri Aug 23 14:51:16 2019 +0200
     3.3 @@ -861,4 +861,7 @@
     3.4    <data name="Notifications_AccountReset" xml:space="preserve">
     3.5      <value>Das Konto wurde zurückgesetzt</value>
     3.6    </data>
     3.7 +  <data name="DialogWindow_NotNow" xml:space="preserve">
     3.8 +    <value>Nicht jetzt</value>
     3.9 +  </data>
    3.10  </root>
    3.11 \ No newline at end of file
     4.1 --- a/Properties/Resources.es.resx	Thu Aug 22 17:04:24 2019 +0200
     4.2 +++ b/Properties/Resources.es.resx	Fri Aug 23 14:51:16 2019 +0200
     4.3 @@ -861,4 +861,7 @@
     4.4    <data name="Notifications_AccountReset" xml:space="preserve">
     4.5      <value>La cuenta ha sido restablecida.</value>
     4.6    </data>
     4.7 +  <data name="DialogWindow_NotNow" xml:space="preserve">
     4.8 +    <value>Ahora no</value>
     4.9 +  </data>
    4.10  </root>
    4.11 \ No newline at end of file
     5.1 --- a/Properties/Resources.resx	Thu Aug 22 17:04:24 2019 +0200
     5.2 +++ b/Properties/Resources.resx	Fri Aug 23 14:51:16 2019 +0200
     5.3 @@ -982,4 +982,7 @@
     5.4    <data name="Notifications_AccountReset" xml:space="preserve">
     5.5      <value>The account has been reset.</value>
     5.6    </data>
     5.7 +  <data name="DialogWindow_NotNow" xml:space="preserve">
     5.8 +    <value>Not Now</value>
     5.9 +  </data>
    5.10  </root>
    5.11 \ No newline at end of file
     6.1 --- a/Resources/Dictionary.xaml	Thu Aug 22 17:04:24 2019 +0200
     6.2 +++ b/Resources/Dictionary.xaml	Fri Aug 23 14:51:16 2019 +0200
     6.3 @@ -181,10 +181,10 @@
     6.4      <Style x:Key="StyleButtonCancel"
     6.5             TargetType="Button"
     6.6             BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
     6.7 -        <Setter Property="Background"
     6.8 +        <Setter Property="BorderBrush"
     6.9                  Value="{StaticResource BrushGray}" />
    6.10          <Setter Property="Foreground"
    6.11 -                Value="{StaticResource BrushTextWhite}" />
    6.12 +                Value="{StaticResource BrushTextBlack}" />
    6.13          <Setter Property="Margin"
    6.14                  Value="0,0,0,0" />
    6.15          <Setter Property="Padding"
     7.1 --- a/UI/Dialog.cs	Thu Aug 22 17:04:24 2019 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,78 +0,0 @@
     7.4 -using pEp.UI.Models;
     7.5 -using pEp.UI.Views;
     7.6 -using System.Threading.Tasks;
     7.7 -
     7.8 -namespace pEp.UI
     7.9 -{
    7.10 -    internal class Dialog
    7.11 -    {
    7.12 -        public enum DialogType
    7.13 -        {
    7.14 -            Undefined,
    7.15 -            Handshake,
    7.16 -            KeySync,
    7.17 -            KeyImportPEP,
    7.18 -            KeyImportPGP,
    7.19 -            ForceProtection
    7.20 -        }
    7.21 -
    7.22 -        /// <summary>
    7.23 -        /// Gets the dialog's own identity.
    7.24 -        /// </summary>
    7.25 -        public PEPIdentity Myself { get; } = null;
    7.26 -
    7.27 -        /// <summary>
    7.28 -        /// Gets the sync partner identity.
    7.29 -        /// </summary>
    7.30 -        public PEPIdentity Partner { get; } = null;
    7.31 -
    7.32 -        /// <summary>
    7.33 -        /// Gets the dialog type.
    7.34 -        /// </summary>
    7.35 -        public DialogType Type { get; } = DialogType.Undefined;
    7.36 -
    7.37 -        public Dialog(DialogType type, PEPIdentity myself, PEPIdentity partner)
    7.38 -        {
    7.39 -            this.Myself = myself;
    7.40 -            this.Partner = partner;
    7.41 -            this.Type = type;
    7.42 -        }
    7.43 -
    7.44 -        public static async Task<bool?> Show(DialogType type, PEPIdentity myself, PEPIdentity partner)
    7.45 -        {
    7.46 -            bool? dialogResult = null;
    7.47 -            bool modal = false;
    7.48 -            DialogWindow dialog = null;
    7.49 -
    7.50 -
    7.51 -            switch (type)
    7.52 -            {
    7.53 -                case DialogType.Handshake:
    7.54 -                    break;
    7.55 -                case DialogType.KeySync:
    7.56 -                    {
    7.57 -                        modal = true;
    7.58 -                    }
    7.59 -                    break;
    7.60 -                case DialogType.KeyImportPEP:
    7.61 -                    break;
    7.62 -                case DialogType.KeyImportPGP:
    7.63 -                    break;
    7.64 -                default:
    7.65 -                    break;
    7.66 -            }
    7.67 -
    7.68 -            if (modal)
    7.69 -            {
    7.70 -                dialog = new DialogWindow(new Dialog(DialogType.KeySync, myself, partner));
    7.71 -                dialogResult = dialog.ShowDialog();
    7.72 -            }
    7.73 -            else
    7.74 -            {
    7.75 -                dialog?.Show();
    7.76 -            }
    7.77 -
    7.78 -            return dialogResult;
    7.79 -        }
    7.80 -    }
    7.81 -}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/UI/Models/Dialog.cs	Fri Aug 23 14:51:16 2019 +0200
     8.3 @@ -0,0 +1,71 @@
     8.4 +using pEpCOMServerAdapterLib;
     8.5 +using System;
     8.6 +
     8.7 +namespace pEp.UI.Models
     8.8 +{
     8.9 +    internal class Dialog
    8.10 +    {
    8.11 +        /// <summary>
    8.12 +        /// The different dialog types.
    8.13 +        /// </summary>
    8.14 +        public enum DialogType
    8.15 +        {
    8.16 +            Undefined,
    8.17 +            Handshake,
    8.18 +            KeySync,
    8.19 +            KeyImportPEP,
    8.20 +            KeyImportPGP,
    8.21 +            ForceProtection
    8.22 +        }
    8.23 +
    8.24 +        /// <summary>
    8.25 +        /// Gets the dialog's own identity.
    8.26 +        /// </summary>
    8.27 +        public PEPIdentity Myself { get; } = null;
    8.28 +
    8.29 +        /// <summary>
    8.30 +        /// Gets the sync partner identity.
    8.31 +        /// </summary>
    8.32 +        public PEPIdentity Partner { get; } = null;
    8.33 +
    8.34 +        /// <summary>
    8.35 +        /// Gets the dialog type.
    8.36 +        /// </summary>
    8.37 +        public DialogType Type { get; } = DialogType.Undefined;
    8.38 +
    8.39 +        /// <summary>
    8.40 +        /// Primary constructor.
    8.41 +        /// </summary>
    8.42 +        /// <param name="type">The type of the dialog.</param>
    8.43 +        /// <param name="myself">The myself identity.</param>
    8.44 +        /// <param name="partner">The partner identity.</param>
    8.45 +        public Dialog(DialogType type, PEPIdentity myself, PEPIdentity partner)
    8.46 +        {
    8.47 +            this.Type = type;
    8.48 +
    8.49 +            // Update myself and partner identity
    8.50 +            try
    8.51 +            {
    8.52 +                pEpIdentity _myself = myself.ToCOMType();
    8.53 +                _myself = ThisAddIn.PEPEngine.Myself(_myself);
    8.54 +                this.Myself = new PEPIdentity(_myself);
    8.55 +
    8.56 +            }
    8.57 +            catch (Exception ex)
    8.58 +            {
    8.59 +                Log.Error("DialogWindow.Ctr: Error updating myself. " + ex.ToString());
    8.60 +            }
    8.61 +
    8.62 +            try
    8.63 +            {
    8.64 +                pEpIdentity _partner = partner.ToCOMType();
    8.65 +                _partner = ThisAddIn.PEPEngine.UpdateIdentity(_partner);
    8.66 +                this.Partner = new PEPIdentity(_partner);
    8.67 +            }
    8.68 +            catch (Exception ex)
    8.69 +            {
    8.70 +                Log.Error("DialogWindow.Ctr: Error updating partner. " + ex.ToString());
    8.71 +            }
    8.72 +        }
    8.73 +    }
    8.74 +}
     9.1 --- a/UI/ViewModels/HandshakeViewModel.cs	Thu Aug 22 17:04:24 2019 +0200
     9.2 +++ b/UI/ViewModels/HandshakeViewModel.cs	Fri Aug 23 14:51:16 2019 +0200
     9.3 @@ -38,7 +38,6 @@
     9.4          private string                              _TrustwordsShort            = null;
     9.5          private string                              _UIDMyself                  = null;
     9.6          private string                              _UIDPartner                 = null;
     9.7 -        private string                              _WindowTitle                = null;
     9.8  
     9.9          /// <summary>
    9.10          /// Gets or sets the active tab.
    9.11 @@ -207,12 +206,12 @@
    9.12          /// <summary>
    9.13          /// Gets the myself identity.
    9.14          /// </summary>
    9.15 -        public PEPIdentity Myself { get; } = null;
    9.16 +        public PEPIdentity Myself => this.Dialog?.Myself;
    9.17  
    9.18          /// <summary>
    9.19          /// Gets the partner identity.
    9.20          /// </summary>
    9.21 -        public PEPIdentity Partner { get; } = null;
    9.22 +        public PEPIdentity Partner => this.Dialog?.Partner;
    9.23  
    9.24          /// <summary>
    9.25          /// Gets or sets the identities to synchronize.
    9.26 @@ -303,19 +302,6 @@
    9.27              }
    9.28          }
    9.29  
    9.30 -        /// <summary>
    9.31 -        /// Gets or sets the title of the dialog window.
    9.32 -        /// </summary>
    9.33 -        public string WindowTitle
    9.34 -        {
    9.35 -            get => this._WindowTitle;
    9.36 -            set
    9.37 -            {
    9.38 -                this._WindowTitle = value;
    9.39 -                this.OnPropertyChanged();
    9.40 -            }
    9.41 -        }
    9.42 -
    9.43          #endregion
    9.44  
    9.45          #region Constructors
    9.46 @@ -330,36 +316,6 @@
    9.47              this.Dialog = dialog;
    9.48              this.CloseWindowAction = closeWindow;
    9.49  
    9.50 -            // Update myself and partner identities
    9.51 -            try
    9.52 -            {
    9.53 -                pEpIdentity _myself = dialog.Myself.ToCOMType();
    9.54 -                _myself = ThisAddIn.PEPEngine.Myself(_myself);
    9.55 -                this.Myself = new PEPIdentity(_myself);
    9.56 -
    9.57 -            }
    9.58 -            catch (Exception ex)
    9.59 -            {
    9.60 -                Log.Error("HandshakeViewModel.Ctr: Error updating myself. " + ex.ToString());
    9.61 -            }
    9.62 -
    9.63 -            try
    9.64 -            {
    9.65 -                pEpIdentity _partner = dialog.Partner.ToCOMType();
    9.66 -                _partner = ThisAddIn.PEPEngine.UpdateIdentity(_partner);
    9.67 -                this.Partner = new PEPIdentity(_partner);
    9.68 -
    9.69 -                if (ThisAddIn.PEPEngine.IspEpUser(_partner) == false)
    9.70 -                {
    9.71 -                    this.ActiveTab = Tabs.Fingerprint;
    9.72 -                    this.AreTabControlsVisible = true;
    9.73 -                }
    9.74 -            }
    9.75 -            catch (Exception ex)
    9.76 -            {
    9.77 -                Log.Error("HandshakeViewModel.Ctr: Error updating partner. " + ex.ToString());
    9.78 -            }
    9.79 -
    9.80              // Create User Ids
    9.81              this.UIDMyself = this.Myself?.UserName + " <" + this.Myself?.Address + ">";
    9.82              this.UIDPartner = this.Partner?.UserName + " <" + this.Partner?.Address + ">";
    9.83 @@ -370,33 +326,78 @@
    9.84              // Set image
    9.85              this.SetPartnerIcon();
    9.86  
    9.87 -            // Format Fingerprints
    9.88 -            if (this.Myself?.Fingerprint is string fprMyself)
    9.89 -            {
    9.90 -                this.FingerprintMyself = Globals.ThisAddIn.ToQuadruple(fprMyself, false);
    9.91 -            }
    9.92 -
    9.93 -            if (this.Partner?.Fingerprint is string fprPartner)
    9.94 -            {
    9.95 -                this.FingerprintPartner = Globals.ThisAddIn.ToQuadruple(fprPartner, false);
    9.96 -            }
    9.97 -
    9.98              // Set Trustwords culture and update the Trustwords itself
    9.99              this.TrustwordsCulture = Globals.ThisAddIn.Settings.TrustwordsCulture;
   9.100              this.UpdateTrustwords();
   9.101  
   9.102 -            // Set button texts
   9.103 -            this.SetButtonsText();
   9.104 +            switch (this.DialogType)
   9.105 +            {
   9.106 +                case Dialog.DialogType.Handshake:
   9.107 +                    {
   9.108 +                        // Check if pEp user
   9.109 +                        try
   9.110 +                        {
   9.111 +                            if (ThisAddIn.PEPEngine.IspEpUser(this.Partner.ToCOMType()) == false)
   9.112 +                            {
   9.113 +                                this.ActiveTab = Tabs.Fingerprint;
   9.114 +                                this.AreTabControlsVisible = true;
   9.115 +                            }
   9.116 +                        }
   9.117 +                        catch (Exception ex)
   9.118 +                        {
   9.119 +                            Log.Error("HandshakeViewModel.Ctr: Error occured. " + ex.ToString());
   9.120 +                        }
   9.121  
   9.122 -            // Get own identities to select whether to sync them or not
   9.123 -            if ((this.DialogType == Dialog.DialogType.KeySync) &&
   9.124 -                (ThisAddIn.PEPEngine.OwnIdentitiesRetrieve() is pEpIdentity[] ownIdentities))
   9.125 -            {
   9.126 -                this._SyncIdentities = new ObservableCollection<SyncIdentity>();
   9.127 -                foreach (pEpIdentity ownIdentity in ownIdentities)
   9.128 -                {
   9.129 -                    this._SyncIdentities.Add(new SyncIdentity { Identity = ownIdentity, Synchronize = true });
   9.130 -                }
   9.131 +                        // Format Fingerprints
   9.132 +                        if (this.Myself?.Fingerprint is string fprMyself)
   9.133 +                        {
   9.134 +                            this.FingerprintMyself = Globals.ThisAddIn.ToQuadruple(fprMyself, false);
   9.135 +                        }
   9.136 +
   9.137 +                        if (this.Partner?.Fingerprint is string fprPartner)
   9.138 +                        {
   9.139 +                            this.FingerprintPartner = Globals.ThisAddIn.ToQuadruple(fprPartner, false);
   9.140 +                        }
   9.141 +
   9.142 +                        // Set button texts
   9.143 +                        this.SetButtonsText();
   9.144 +
   9.145 +                        // Set explanation text
   9.146 +                        this.ExplanationText = Properties.Resources.Handshake_StandardExplanationText;
   9.147 +                    }
   9.148 +                    break;
   9.149 +                case Dialog.DialogType.KeySync:
   9.150 +                    {
   9.151 +                        // Get own identities to select whether to sync them or not
   9.152 +                        try
   9.153 +                        {
   9.154 +                            if (ThisAddIn.PEPEngine.OwnIdentitiesRetrieve() is pEpIdentity[] ownIdentities)
   9.155 +                            {
   9.156 +                                this._SyncIdentities = new ObservableCollection<SyncIdentity>();
   9.157 +                                foreach (pEpIdentity ownIdentity in ownIdentities)
   9.158 +                                {
   9.159 +                                    this._SyncIdentities.Add(new SyncIdentity { Identity = ownIdentity, Synchronize = true });
   9.160 +                                }
   9.161 +                            }
   9.162 +                        }
   9.163 +                        catch (Exception ex)
   9.164 +                        {
   9.165 +                            Log.Error("HandshakeViewModel.Ctr: Error occured. " + ex.ToString());
   9.166 +                        }
   9.167 +
   9.168 +                        // Set explanation text
   9.169 +                        this.ExplanationText = Properties.Resources.Handshake_SyncTypeAExplanationText;
   9.170 +                    }
   9.171 +                    break;
   9.172 +                case Dialog.DialogType.KeyImportPEP:
   9.173 +                    break;
   9.174 +                case Dialog.DialogType.KeyImportPGP:
   9.175 +                    break;
   9.176 +                case Dialog.DialogType.ForceProtection:
   9.177 +                    break;
   9.178 +                case Dialog.DialogType.Undefined:
   9.179 +                default:
   9.180 +                    break;
   9.181              }
   9.182          }
   9.183  
    10.1 --- a/UI/ViewModels/IDialogWindowViewModel.cs	Thu Aug 22 17:04:24 2019 +0200
    10.2 +++ b/UI/ViewModels/IDialogWindowViewModel.cs	Fri Aug 23 14:51:16 2019 +0200
    10.3 @@ -19,10 +19,5 @@
    10.4          /// The result of the dialog.
    10.5          /// </summary>
    10.6          bool? DialogResult { get; }
    10.7 -
    10.8 -        /// <summary>
    10.9 -        /// The title of the dialog window.
   10.10 -        /// </summary>
   10.11 -        string WindowTitle { get; set; }
   10.12      }
   10.13  }
    11.1 --- a/UI/ViewModels/SyncWizardViewModel.cs	Thu Aug 22 17:04:24 2019 +0200
    11.2 +++ b/UI/ViewModels/SyncWizardViewModel.cs	Fri Aug 23 14:51:16 2019 +0200
    11.3 @@ -1,4 +1,5 @@
    11.4 -using System;
    11.5 +using pEp.UI.Models;
    11.6 +using System;
    11.7  using System.Collections.Generic;
    11.8  using System.Collections.ObjectModel;
    11.9  using System.Windows.Media.Imaging;
   11.10 @@ -14,6 +15,7 @@
   11.11          /// <param name="closeWindow">The Action to close the Dialog window.</param>
   11.12          public SyncWizardViewModel(Dialog dialog, Action closeWindow) : base(dialog, closeWindow)
   11.13          {
   11.14 +
   11.15          }
   11.16  
   11.17          /// <summary>
   11.18 @@ -39,6 +41,7 @@
   11.19                  new WizardGenericPageViewModel
   11.20                  {
   11.21                      ButtonCancelStyle = WizardPageViewModelBase.RedButtonStyle,
   11.22 +                    ButtonCancelText = Properties.Resources.Options_CancelText,
   11.23                      ExplanationText = Properties.Resources.KeySyncWizard_PEPStep3ExplanationText,
   11.24                      Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute)),
   11.25                      IsButtonBackVisible = false,
    12.1 --- a/UI/ViewModels/WizardGenericPageViewModel.cs	Thu Aug 22 17:04:24 2019 +0200
    12.2 +++ b/UI/ViewModels/WizardGenericPageViewModel.cs	Fri Aug 23 14:51:16 2019 +0200
    12.3 @@ -7,7 +7,9 @@
    12.4          private string          _ExplanationText    = null;
    12.5          private ImageSource     _Image              = null;
    12.6  
    12.7 -
    12.8 +        /// <summary>
    12.9 +        /// Gets or sets the text that explains the current wizard step.
   12.10 +        /// </summary>
   12.11          public string ExplanationText
   12.12          {
   12.13              get => this._ExplanationText;
   12.14 @@ -18,6 +20,9 @@
   12.15              }
   12.16          }
   12.17  
   12.18 +        /// <summary>
   12.19 +        /// Gets or sets the image/icon to display in the current wizard step.
   12.20 +        /// </summary>
   12.21          public ImageSource Image
   12.22          {
   12.23              get => this._Image;
   12.24 @@ -28,6 +33,9 @@
   12.25              }
   12.26          }
   12.27  
   12.28 +        /// <summary>
   12.29 +        /// Primary constructor.
   12.30 +        /// </summary>
   12.31          public WizardGenericPageViewModel()
   12.32          {
   12.33              this.Content = this;
    13.1 --- a/UI/ViewModels/WizardPageViewModelBase.cs	Thu Aug 22 17:04:24 2019 +0200
    13.2 +++ b/UI/ViewModels/WizardPageViewModelBase.cs	Fri Aug 23 14:51:16 2019 +0200
    13.3 @@ -8,7 +8,8 @@
    13.4          private Style               _ButtonAcceptHandshakeStyle         = WizardPageViewModelBase.GreenButtonStyle;
    13.5          private Style               _ButtonBackStyle                    = WizardPageViewModelBase.GreyButtonStyle;
    13.6          private Style               _ButtonCancelStyle                  = WizardPageViewModelBase.GreyButtonStyle;
    13.7 -        private Style               _ButtonNextHandshakeStyle           = WizardPageViewModelBase.GreyButtonStyle;
    13.8 +        private string              _ButtonCancelText                   = Properties.Resources.DialogWindow_NotNow;
    13.9 +        private Style               _ButtonNextStyle                    = WizardPageViewModelBase.GreyButtonStyle;
   13.10          private Style               _ButtonRejectHandshakeStyle         = WizardPageViewModelBase.RedButtonStyle;
   13.11          private ViewModelBase       _Content                            = null;
   13.12          private bool                _IsButtonAcceptHandshakeVisible     = false;
   13.13 @@ -63,14 +64,27 @@
   13.14          }
   13.15  
   13.16          /// <summary>
   13.17 +        /// Gets or sets the Cancel button text.
   13.18 +        /// </summary>
   13.19 +        public string ButtonCancelText
   13.20 +        {
   13.21 +            get => this._ButtonCancelText;
   13.22 +            set
   13.23 +            {
   13.24 +                this._ButtonCancelText = value;
   13.25 +                this.OnPropertyChanged();
   13.26 +            }
   13.27 +        }
   13.28 +
   13.29 +        /// <summary>
   13.30          /// Gets ot sets the style of the Next button.
   13.31          /// </summary>
   13.32 -        public Style ButtonNextHandshakeStyle
   13.33 +        public Style ButtonNextStyle
   13.34          {
   13.35 -            get => this._ButtonNextHandshakeStyle;
   13.36 +            get => this._ButtonNextStyle;
   13.37              set
   13.38              {
   13.39 -                this._ButtonNextHandshakeStyle = value;
   13.40 +                this._ButtonNextStyle = value;
   13.41                  this.OnPropertyChanged();
   13.42              }
   13.43          }
    14.1 --- a/UI/ViewModels/WizardViewModelBase.cs	Thu Aug 22 17:04:24 2019 +0200
    14.2 +++ b/UI/ViewModels/WizardViewModelBase.cs	Fri Aug 23 14:51:16 2019 +0200
    14.3 @@ -1,4 +1,5 @@
    14.4 -using pEpCOMServerAdapterLib;
    14.5 +using pEp.UI.Models;
    14.6 +using pEpCOMServerAdapterLib;
    14.7  using System;
    14.8  using System.Collections.ObjectModel;
    14.9  
   14.10 @@ -9,12 +10,12 @@
   14.11          #region Fields
   14.12  
   14.13          protected           RelayCommand                                    _AcceptHandshakeCommand;
   14.14 +        protected           RelayCommand                                    _CancelCommand;
   14.15          private             ViewModelBase                                   _CurrentPage;
   14.16          protected           RelayCommand                                    _MoveBackCommand;
   14.17          protected           RelayCommand                                    _MoveNextCommand;
   14.18          protected           ReadOnlyCollection<ViewModelBase>               _Pages;
   14.19          protected           RelayCommand                                    _RejectHandshakeCommand;
   14.20 -        protected           string                                          _WindowTitle;
   14.21  
   14.22          #endregion
   14.23  
   14.24 @@ -37,6 +38,22 @@
   14.25          }
   14.26  
   14.27          /// <summary>
   14.28 +        /// The command for when a handshake has been canceled.
   14.29 +        /// </summary>
   14.30 +        public RelayCommand CancelCommand
   14.31 +        {
   14.32 +            get
   14.33 +            {
   14.34 +                if (this._CancelCommand == null)
   14.35 +                {
   14.36 +                    this._CancelCommand = new RelayCommand(p => this.CancelDialog());
   14.37 +                }
   14.38 +
   14.39 +                return this._CancelCommand;
   14.40 +            }
   14.41 +        }
   14.42 +
   14.43 +        /// <summary>
   14.44          /// Whether or not the wizard can move on to the next page.
   14.45          /// </summary>
   14.46          bool CanMoveToNextPage
   14.47 @@ -164,19 +181,6 @@
   14.48              }
   14.49          }
   14.50  
   14.51 -        /// <summary>
   14.52 -        /// The window title of the dialog.
   14.53 -        /// </summary>
   14.54 -        public string WindowTitle
   14.55 -        {
   14.56 -            get => this._WindowTitle;
   14.57 -            set
   14.58 -            {
   14.59 -                this._WindowTitle = value;
   14.60 -                this.OnPropertyChanged();
   14.61 -            }
   14.62 -        }
   14.63 -
   14.64          #endregion
   14.65  
   14.66          #region Constructors
   14.67 @@ -191,8 +195,7 @@
   14.68              this.Dialog = dialog;
   14.69              this.CloseWindowAction = closeWindow;
   14.70              this.CreatePages();
   14.71 -            this.CurrentPage = this.Pages[0];
   14.72 -            this.WindowTitle = Properties.Resources.Handshake_SyncFormText;
   14.73 +            this.CurrentPage = this.Pages[0];            
   14.74          }
   14.75  
   14.76          #endregion
   14.77 @@ -236,6 +239,15 @@
   14.78          }
   14.79  
   14.80          /// <summary>
   14.81 +        /// Cancels the dialog and closes the window.
   14.82 +        /// </summary>
   14.83 +        private void CancelDialog()
   14.84 +        {
   14.85 +            this.DialogResult = null;
   14.86 +            this.CloseWindowAction?.Invoke();
   14.87 +        }
   14.88 +
   14.89 +        /// <summary>
   14.90          /// Creates all pages that are displayed in the wizard.
   14.91          /// </summary>
   14.92          public abstract void CreatePages();       
    15.1 --- a/UI/Views/DialogWindow.xaml	Thu Aug 22 17:04:24 2019 +0200
    15.2 +++ b/UI/Views/DialogWindow.xaml	Fri Aug 23 14:51:16 2019 +0200
    15.3 @@ -15,7 +15,6 @@
    15.4          x:ClassModifier="internal"
    15.5          Topmost="True"
    15.6          Background="{x:Static SystemColors.MenuBarBrush}"
    15.7 -        Title="{Binding WindowTitle}"
    15.8          Icon="pack://application:,,,/pEp;component/Resources/ImageLogoIcon.png"
    15.9          WindowStartupLocation="CenterScreen"
   15.10          Closing="DialogWindow_Closing">
    16.1 --- a/UI/Views/DialogWindow.xaml.cs	Thu Aug 22 17:04:24 2019 +0200
    16.2 +++ b/UI/Views/DialogWindow.xaml.cs	Fri Aug 23 14:51:16 2019 +0200
    16.3 @@ -4,6 +4,7 @@
    16.4  using System;
    16.5  using System.ComponentModel;
    16.6  using System.Windows;
    16.7 +using static pEp.UI.Models.Dialog;
    16.8  
    16.9  namespace pEp.UI.Views
   16.10  {
   16.11 @@ -12,8 +13,6 @@
   16.12      /// </summary>
   16.13      internal partial class DialogWindow : Window
   16.14      {
   16.15 -        private bool isShownDialog = false;
   16.16 -
   16.17          /// <summary>
   16.18          /// Primary constructor.
   16.19          /// </summary>
   16.20 @@ -28,9 +27,11 @@
   16.21              switch (dialog.Type)
   16.22              {
   16.23                  case Dialog.DialogType.Handshake:
   16.24 +                    this.Title = Properties.Resources.Handshake_StandardFormText;
   16.25                      this.Content = new HandshakeViewModel(dialog, this.Close);
   16.26                      break;
   16.27                  case Dialog.DialogType.KeySync:
   16.28 +                    this.Title = Properties.Resources.Handshake_SyncFormText;
   16.29                      this.Content = new SyncWizardViewModel(dialog, this.Close);
   16.30                      break;
   16.31                  case Dialog.DialogType.KeyImportPEP:
   16.32 @@ -49,12 +50,18 @@
   16.33          /// </summary>
   16.34          private void DialogWindow_Closing(object sender, CancelEventArgs e)
   16.35          {
   16.36 -            if (this.isShownDialog &&
   16.37 -                (this.Content is SyncWizardViewModel viewModel))
   16.38 +            if (this.Content is SyncWizardViewModel viewModel)
   16.39              {
   16.40                  if (viewModel.DialogResult == null)
   16.41                  {
   16.42 -                    ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeCancel, null);
   16.43 +                    try
   16.44 +                    {
   16.45 +                        ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeCancel, null);
   16.46 +                    }
   16.47 +                    catch (Exception ex)
   16.48 +                    {
   16.49 +                        Log.Error("DialogWindow_Closing: Error delivering handshake result. " + ex.ToString());
   16.50 +                    }
   16.51                  }
   16.52              }
   16.53          }
   16.54 @@ -62,16 +69,6 @@
   16.55          #region Methods
   16.56  
   16.57          /// <summary>
   16.58 -        /// Overloads the ShowDialog method and sets a flag to signal that this dialog is modal.
   16.59 -        /// </summary>
   16.60 -        /// <returns>The DialogResult of the base's ShowDialog method.</returns>
   16.61 -        public new bool? ShowDialog()
   16.62 -        {
   16.63 -            this.isShownDialog = true;
   16.64 -            return base.ShowDialog();
   16.65 -        }
   16.66 -
   16.67 -        /// <summary>
   16.68          /// Notifies about a sync handshake signal.
   16.69          /// </summary>
   16.70          /// <param name="signal">The sync handshake signal.</param>
   16.71 @@ -87,5 +84,33 @@
   16.72          }
   16.73  
   16.74          #endregion
   16.75 +
   16.76 +        #region Static methods
   16.77 +
   16.78 +        /// <summary>
   16.79 +        /// Creates a Dialog window and shows it.
   16.80 +        /// Note: this starts a new STA task and shows the dialog on the respective thread.
   16.81 +        /// </summary>
   16.82 +        /// <param name="type">The dialog type.</param>
   16.83 +        /// <param name="myself">The own identity.</param>
   16.84 +        /// <param name="partner">The partner identity.</param>
   16.85 +        public static void CreateAndShow(DialogType type, PEPIdentity myself, PEPIdentity partner)
   16.86 +        {
   16.87 +            Extensions.TaskExtensions.StartSTATask(() =>
   16.88 +            {
   16.89 +                DialogWindow dialogWindow = new DialogWindow(new Dialog(type, myself, partner));
   16.90 +                
   16.91 +                if (type != DialogType.Handshake)
   16.92 +                {
   16.93 +                    dialogWindow.ShowDialog();
   16.94 +                }
   16.95 +                else
   16.96 +                {
   16.97 +                    dialogWindow.Show();
   16.98 +                }
   16.99 +            });
  16.100 +        }
  16.101 +
  16.102 +        #endregion
  16.103      }
  16.104  }
    17.1 --- a/UI/Views/HandshakeView.xaml	Thu Aug 22 17:04:24 2019 +0200
    17.2 +++ b/UI/Views/HandshakeView.xaml	Fri Aug 23 14:51:16 2019 +0200
    17.3 @@ -5,8 +5,7 @@
    17.4               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    17.5               xmlns:p="clr-namespace:pEp.Properties"
    17.6               xmlns:ui="clr-namespace:pEp.UI"
    17.7 -             mc:Ignorable="d" 
    17.8 -             d:DesignHeight="450" d:DesignWidth="800">
    17.9 +             mc:Ignorable="d">
   17.10      <UserControl.Resources>
   17.11          <ResourceDictionary>
   17.12              <!-- Converters -->
   17.13 @@ -41,9 +40,9 @@
   17.14              </ResourceDictionary.MergedDictionaries>
   17.15          </ResourceDictionary>
   17.16      </UserControl.Resources>
   17.17 +    
   17.18      <!--The window content-->
   17.19 -    <StackPanel Margin="10"
   17.20 -                Width="470">
   17.21 +    <StackPanel>
   17.22  
   17.23          <!--Information section-->
   17.24          <TextBlock Text="{Binding Path=ExplanationText, Mode=OneWay}"
    18.1 --- a/UI/Views/WizardView.xaml	Thu Aug 22 17:04:24 2019 +0200
    18.2 +++ b/UI/Views/WizardView.xaml	Fri Aug 23 14:51:16 2019 +0200
    18.3 @@ -7,10 +7,7 @@
    18.4          xmlns:vm="clr-namespace:pEp.UI.ViewModels"
    18.5          xmlns:p="clr-namespace:pEp.Properties"
    18.6          x:ClassModifier="internal"
    18.7 -        mc:Ignorable="d"
    18.8 -        MinHeight="5"
    18.9 -        Height="Auto"
   18.10 -        Width="Auto">
   18.11 +        mc:Ignorable="d">
   18.12      <UserControl.Resources>
   18.13          <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
   18.14          <DataTemplate DataType="{x:Type vm:WizardGenericPageViewModel}">
   18.15 @@ -22,11 +19,12 @@
   18.16      </UserControl.Resources>
   18.17  
   18.18      <StackPanel Margin="10"
   18.19 -                Width="500">
   18.20 +                Width="480">
   18.21          
   18.22 -    <!--Content section-->
   18.23 -    <UserControl x:Name="WizardContent"
   18.24 -                 Content="{Binding CurrentPage}"/>
   18.25 +        <!--Content section-->
   18.26 +        <UserControl x:Name="WizardContent"
   18.27 +                     Content="{Binding CurrentPage}"
   18.28 +                     Margin="0,0,0,10"/>
   18.29  
   18.30          <!--Buttons section-->
   18.31          <StackPanel Orientation="Horizontal"
   18.32 @@ -42,21 +40,21 @@
   18.33              <Button x:Name="NextButton"
   18.34                      MinHeight="28"
   18.35                      MinWidth="150"
   18.36 -                    Margin="5"
   18.37 +                    Margin="5,5,10,5"
   18.38                      Style="{Binding CurrentPage.ButtonNextStyle}"
   18.39                      Command="{Binding MoveNextCommand}"
   18.40                      Content="{x:Static p:Resources.KeySyncWizard_Next}"
   18.41                      Visibility="{Binding CurrentPage.IsButtonNextVisible, Converter={StaticResource BoolToVisibility}}" />
   18.42              <Button x:Name="CancelButton"
   18.43 -                    Margin="5,5,0,5"
   18.44 +                    Margin="0,5,5,5"
   18.45                      MinHeight="28"
   18.46                      MinWidth="150"
   18.47                      Style="{Binding CurrentPage.ButtonCancelStyle}"
   18.48 -                    Command="{Binding MoveNextCommand}"
   18.49 -                    Content="{x:Static p:Resources.Handshake_CancelText}"
   18.50 +                    Command="{Binding CancelCommand}"
   18.51 +                    Content="{Binding CurrentPage.ButtonCancelText}"
   18.52                      Visibility="{Binding CurrentPage.IsButtonCancelVisible, Converter={StaticResource BoolToVisibility}}" />
   18.53              <Button x:Name="AcceptHandshakeButton"
   18.54 -                    Margin="5,5,0,5"
   18.55 +                    Margin="10,5,5,5"
   18.56                      MinHeight="28"
   18.57                      MinWidth="150"
   18.58                      Style="{Binding CurrentPage.ButtonAcceptHandshakeStyle}"
   18.59 @@ -64,7 +62,7 @@
   18.60                      Content="{x:Static p:Resources.Handshake_Accept}"
   18.61                      Visibility="{Binding CurrentPage.IsButtonAcceptHandshakeVisible, Converter={StaticResource BoolToVisibility}}" />
   18.62              <Button x:Name="RejectHandshakeButton"
   18.63 -                    Margin="5,5,0,5"
   18.64 +                    Margin="10,5,0,5"
   18.65                      MinHeight="28"
   18.66                      MinWidth="150"
   18.67                      Style="{Binding CurrentPage.ButtonRejectHandshakeStyle}"
    19.1 --- a/Wrappers/WatchedWindow.cs	Thu Aug 22 17:04:24 2019 +0200
    19.2 +++ b/Wrappers/WatchedWindow.cs	Fri Aug 23 14:51:16 2019 +0200
    19.3 @@ -331,7 +331,8 @@
    19.4                      {
    19.5                          partner = message.To[0];
    19.6                      }
    19.7 -                    handshakeDialog = new DialogWindow(new Dialog(Dialog.DialogType.Handshake, myself, partner));
    19.8 +
    19.9 +                    handshakeDialog = new DialogWindow(new Dialog(Dialog.DialogType.KeySync, myself, partner));
   19.10                      handshakeDialog.Closed += HandshakeDialog_Closed;
   19.11                      handshakeDialog.Show();
   19.12                  }
   19.13 @@ -1477,6 +1478,9 @@
   19.14          /// </summary>
   19.15          protected void HandshakeDialog_Closed(object sender, EventArgs e)
   19.16          {
   19.17 +            this.RequestRatingAndUIUpdate();
   19.18 +            Globals.ThisAddIn.RecalculateAllWindows(this);
   19.19 +
   19.20              if (this.handshakeDialog != null)
   19.21              {
   19.22                  this.handshakeDialog.Closed -= HandshakeDialog_Closed;
    20.1 --- a/pEpForOutlook.csproj	Thu Aug 22 17:04:24 2019 +0200
    20.2 +++ b/pEpForOutlook.csproj	Fri Aug 23 14:51:16 2019 +0200
    20.3 @@ -410,7 +410,7 @@
    20.4        <DependentUpon>Resources.zh.resx</DependentUpon>
    20.5      </Compile>
    20.6      <Compile Include="SyncQueue.cs" />
    20.7 -    <Compile Include="UI\Dialog.cs" />
    20.8 +    <Compile Include="UI\Models\Dialog.cs" />
    20.9      <Compile Include="UI\FormControlCrashReport.xaml.cs">
   20.10        <DependentUpon>FormControlCrashReport.xaml</DependentUpon>
   20.11      </Compile>