OUT-590: Some restructuring and documentation refactor_dialogs
authorThomas
Thu, 22 Aug 2019 16:15:16 +0200
branchrefactor_dialogs
changeset 271274ada4e88d29
parent 2711 89ea77c3b521
child 2714 9eaea1577fa4
OUT-590: Some restructuring and documentation
AdapterCallbacks.cs
UI/Dialog.cs
UI/ValueConverters.cs
UI/ViewModels/DialogWindowViewModel.cs
UI/ViewModels/HandshakeViewModel.cs
UI/ViewModels/IDialogWindowViewModel.cs
UI/ViewModels/SyncWizardViewModel.cs
UI/ViewModels/WizardHandshakePageViewModel.cs
UI/ViewModels/WizardPageViewModelBase.cs
UI/ViewModels/WizardViewModelBase.cs
UI/Views/DialogWindow.xaml
UI/Views/DialogWindow.xaml.cs
UI/Views/HandshakeView.xaml
UI/Views/WizardPageView.xaml
UI/Views/WizardView.xaml
Wrappers/WatchedWindow.cs
pEpForOutlook.csproj
     1.1 --- a/AdapterCallbacks.cs	Thu Aug 22 10:08:25 2019 +0200
     1.2 +++ b/AdapterCallbacks.cs	Thu Aug 22 16:15:16 2019 +0200
     1.3 @@ -15,7 +15,7 @@
     1.4      /// </summary>   
     1.5      internal class AdapterCallbacks : IpEpEngineCallbacks
     1.6      {
     1.7 -        private static  HandshakeDialog             handshakeDialog         = null;
     1.8 +        private static  DialogWindow             handshakeDialog         = null;
     1.9  
    1.10          #region Callbacks
    1.11          /// <summary>
    1.12 @@ -118,6 +118,7 @@
    1.13                  // Signal that a group is being formed
    1.14                  case SyncHandshakeSignal.SyncNotifyFormingGroup:
    1.15                      {
    1.16 +                        AdapterCallbacks.handshakeDialog.NotifySyncNotification(signal);
    1.17                          break;
    1.18                      }
    1.19                  // Signal to show that the device is in state sole
    1.20 @@ -280,9 +281,7 @@
    1.21              {
    1.22                  //return Dialog.Show(Dialog.Type.KeySync, new PEPIdentity(own), new PEPIdentity(partner));
    1.23                  // Create the handshake dialog
    1.24 -                AdapterCallbacks.handshakeDialog = new HandshakeDialog(new PEPIdentity(own),
    1.25 -                                                                       new PEPIdentity(partner),
    1.26 -                                                                       Handshake.HandshakeMode.SyncTypeA);
    1.27 +                AdapterCallbacks.handshakeDialog = new DialogWindow(new Dialog(Dialog.DialogType.KeySync, new PEPIdentity(own), new PEPIdentity(partner)));
    1.28  
    1.29  
    1.30                  return AdapterCallbacks.handshakeDialog.ShowDialog();
     2.1 --- a/UI/Dialog.cs	Thu Aug 22 10:08:25 2019 +0200
     2.2 +++ b/UI/Dialog.cs	Thu Aug 22 16:15:16 2019 +0200
     2.3 @@ -6,8 +6,9 @@
     2.4  {
     2.5      internal class Dialog
     2.6      {
     2.7 -        public enum Type
     2.8 +        public enum DialogType
     2.9          {
    2.10 +            Undefined,
    2.11              Handshake,
    2.12              KeySync,
    2.13              KeyImportPEP,
    2.14 @@ -15,7 +16,29 @@
    2.15              ForceProtection
    2.16          }
    2.17  
    2.18 -        public static async Task<bool?> Show(Type type, PEPIdentity myself, PEPIdentity partner)
    2.19 +        /// <summary>
    2.20 +        /// Gets the dialog's own identity.
    2.21 +        /// </summary>
    2.22 +        public PEPIdentity Myself { get; } = null;
    2.23 +
    2.24 +        /// <summary>
    2.25 +        /// Gets the sync partner identity.
    2.26 +        /// </summary>
    2.27 +        public PEPIdentity Partner { get; } = null;
    2.28 +
    2.29 +        /// <summary>
    2.30 +        /// Gets the dialog type.
    2.31 +        /// </summary>
    2.32 +        public DialogType Type { get; } = DialogType.Undefined;
    2.33 +
    2.34 +        public Dialog(DialogType type, PEPIdentity myself, PEPIdentity partner)
    2.35 +        {
    2.36 +            this.Myself = myself;
    2.37 +            this.Partner = partner;
    2.38 +            this.Type = type;
    2.39 +        }
    2.40 +
    2.41 +        public static async Task<bool?> Show(DialogType type, PEPIdentity myself, PEPIdentity partner)
    2.42          {
    2.43              bool? dialogResult = null;
    2.44              bool modal = false;
    2.45 @@ -24,16 +47,16 @@
    2.46  
    2.47              switch (type)
    2.48              {
    2.49 -                case Type.Handshake:
    2.50 +                case DialogType.Handshake:
    2.51                      break;
    2.52 -                case Type.KeySync:
    2.53 +                case DialogType.KeySync:
    2.54                      {
    2.55                          modal = true;
    2.56                      }
    2.57                      break;
    2.58 -                case Type.KeyImportPEP:
    2.59 +                case DialogType.KeyImportPEP:
    2.60                      break;
    2.61 -                case Type.KeyImportPGP:
    2.62 +                case DialogType.KeyImportPGP:
    2.63                      break;
    2.64                  default:
    2.65                      break;
    2.66 @@ -41,7 +64,7 @@
    2.67  
    2.68              if (modal)
    2.69              {
    2.70 -                dialog = new DialogWindow(Type.KeySync, new Handshake(myself, partner, Handshake.HandshakeMode.SyncTypeA));
    2.71 +                dialog = new DialogWindow(new Dialog(DialogType.KeySync, myself, partner));
    2.72                  dialogResult = dialog.ShowDialog();
    2.73              }
    2.74              else
     3.1 --- a/UI/ValueConverters.cs	Thu Aug 22 10:08:25 2019 +0200
     3.2 +++ b/UI/ValueConverters.cs	Thu Aug 22 16:15:16 2019 +0200
     3.3 @@ -267,6 +267,37 @@
     3.4          }
     3.5      }
     3.6  
     3.7 +    public class IsWizardModeToBoolConverter : IValueConverter
     3.8 +    {
     3.9 +        public object Convert(object value,
    3.10 +                             Type targetType,
    3.11 +                             object parameter,
    3.12 +                             CultureInfo culture)
    3.13 +        {
    3.14 +            try
    3.15 +            {
    3.16 +                if ((Enum.GetName(typeof(Dialog.DialogType), value) is string val) &&
    3.17 +                    ((val.Equals(Enum.GetName(typeof(Dialog.DialogType), Dialog.DialogType.KeySync))) ||
    3.18 +                     (val.Equals(Enum.GetName(typeof(Dialog.DialogType), Dialog.DialogType.KeyImportPEP))) ||
    3.19 +                     (val.Equals(Enum.GetName(typeof(Dialog.DialogType), Dialog.DialogType.KeyImportPGP)))))
    3.20 +                {
    3.21 +                    return true;
    3.22 +                }
    3.23 +            }
    3.24 +            catch (Exception ex)
    3.25 +            {
    3.26 +                Log.Error("IsWizardModeToBoolConverter: Error occured. " + ex.ToString());
    3.27 +            }
    3.28 +
    3.29 +            return false;
    3.30 +        }
    3.31 +
    3.32 +        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    3.33 +        {
    3.34 +            throw new NotImplementedException();
    3.35 +        }
    3.36 +    }
    3.37 +
    3.38      /// <summary>
    3.39      /// Returns a bool value indicating if the release mode matches the given parameter.
    3.40      /// </summary>
    3.41 @@ -397,27 +428,20 @@
    3.42                                object parameter,
    3.43                                CultureInfo culture)
    3.44          {
    3.45 -            bool result = false;
    3.46 -            string val = null;
    3.47 -
    3.48              try
    3.49              {
    3.50 -                val = Enum.GetName(typeof(Handshake.HandshakeMode), value);
    3.51 +                if ((Enum.GetName(typeof(Dialog.DialogType), value) is string val) &&
    3.52 +                    val.Equals(Enum.GetName(typeof(Dialog.DialogType), Dialog.DialogType.KeySync)))
    3.53 +                {
    3.54 +                    return true;
    3.55 +                }
    3.56              }
    3.57 -            catch
    3.58 +            catch (Exception ex)
    3.59              {
    3.60 -                val = null;
    3.61 +                Log.Error("IsSyncModeToBoolConverter: Error occured. " + ex.ToString());
    3.62              }
    3.63  
    3.64 -            if ((val != null) &&
    3.65 -                (val.Equals(Enum.GetName(typeof(Handshake.HandshakeMode), Handshake.HandshakeMode.SyncTypeA)) ||
    3.66 -                 val.Equals(Enum.GetName(typeof(Handshake.HandshakeMode), Handshake.HandshakeMode.SyncTypeB)) ||
    3.67 -                 val.Equals(Enum.GetName(typeof(Handshake.HandshakeMode), Handshake.HandshakeMode.SyncTypeC))))
    3.68 -            {
    3.69 -                result = true;
    3.70 -            }
    3.71 -
    3.72 -            return result;
    3.73 +            return false;
    3.74          }
    3.75  
    3.76          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     4.1 --- a/UI/ViewModels/DialogWindowViewModel.cs	Thu Aug 22 10:08:25 2019 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,47 +0,0 @@
     4.4 -using pEp.UI.Models;
     4.5 -using System;
     4.6 -
     4.7 -namespace pEp.UI.ViewModels
     4.8 -{
     4.9 -    internal class DialogWindowViewModel : ViewModelBase
    4.10 -    {
    4.11 -        private             ViewModelBase                   _Content            = null;
    4.12 -        private             string                          _WindowTitle        = null;
    4.13 -
    4.14 -        public Action CloseWindowAction { get; protected set; } = null;
    4.15 -
    4.16 -        public ViewModelBase Content
    4.17 -        {
    4.18 -            get => this._Content;
    4.19 -            set
    4.20 -            {
    4.21 -                this._Content = value;
    4.22 -                this.OnPropertyChanged();
    4.23 -            }
    4.24 -        }
    4.25 -
    4.26 -        /// <summary>
    4.27 -        /// Gets or sets the dialog result.
    4.28 -        /// Note: Needed to be able to return null as DialogResult.
    4.29 -        /// </summary>
    4.30 -        public bool? DialogResult { get; protected set; } = null;
    4.31 -
    4.32 -        public Handshake Handshake { get; protected set; } = null;
    4.33 -
    4.34 -        public string WindowTitle
    4.35 -        {
    4.36 -            get => this._WindowTitle;
    4.37 -            set
    4.38 -            {
    4.39 -                this._WindowTitle = value;
    4.40 -                this.OnPropertyChanged();
    4.41 -            }
    4.42 -        }
    4.43 -
    4.44 -        public DialogWindowViewModel(Handshake handshake, Action closeWindow)
    4.45 -        {
    4.46 -            this.Handshake = handshake;
    4.47 -            this.CloseWindowAction = closeWindow;
    4.48 -        }
    4.49 -    }
    4.50 -}
     5.1 --- a/UI/ViewModels/HandshakeViewModel.cs	Thu Aug 22 10:08:25 2019 +0200
     5.2 +++ b/UI/ViewModels/HandshakeViewModel.cs	Thu Aug 22 16:15:16 2019 +0200
     5.3 @@ -9,7 +9,7 @@
     5.4  
     5.5  namespace pEp.UI.ViewModels
     5.6  {
     5.7 -    class HandshakeViewModel : DialogWindowViewModel
     5.8 +    class HandshakeViewModel : ViewModelBase, IDialogWindowViewModel
     5.9      {
    5.10          public enum Tabs
    5.11          {
    5.12 @@ -38,6 +38,7 @@
    5.13          private string                              _TrustwordsShort            = null;
    5.14          private string                              _UIDMyself                  = null;
    5.15          private string                              _UIDPartner                 = null;
    5.16 +        private string                              _WindowTitle                = null;
    5.17  
    5.18          /// <summary>
    5.19          /// Gets or sets the active tab.
    5.20 @@ -109,6 +110,18 @@
    5.21          }
    5.22  
    5.23          /// <summary>
    5.24 +        /// Gets the action to close the dialog window.
    5.25 +        /// </summary>
    5.26 +        public Action CloseWindowAction { get; }
    5.27 +
    5.28 +        public Dialog Dialog { get; }
    5.29 +
    5.30 +        /// <summary>
    5.31 +        /// Gets the DialogResult of this window.
    5.32 +        /// </summary>
    5.33 +        public bool? DialogResult { get; private set; }
    5.34 +
    5.35 +        /// <summary>
    5.36          /// Gets or sets the text to display on the Expander tooltip.
    5.37          /// </summary>
    5.38          public string ExpanderToolTip
    5.39 @@ -187,22 +200,19 @@
    5.40          }
    5.41  
    5.42          /// <summary>
    5.43 -        /// Gets the mode of this handshake.
    5.44 +        /// Gets the type of dialog.
    5.45          /// </summary>
    5.46 -        public Handshake.HandshakeMode Mode
    5.47 -        {
    5.48 -            get => this.Handshake.Mode;
    5.49 -        }
    5.50 +        public Dialog.DialogType DialogType => this.Dialog.Type;
    5.51  
    5.52          /// <summary>
    5.53          /// Gets the myself identity.
    5.54          /// </summary>
    5.55 -        public PEPIdentity Myself { get; private set; }
    5.56 +        public PEPIdentity Myself { get; } = null;
    5.57  
    5.58          /// <summary>
    5.59          /// Gets the partner identity.
    5.60          /// </summary>
    5.61 -        public PEPIdentity Partner { get; private set; }
    5.62 +        public PEPIdentity Partner { get; } = null;
    5.63  
    5.64          /// <summary>
    5.65          /// Gets or sets the identities to synchronize.
    5.66 @@ -293,6 +303,19 @@
    5.67              }
    5.68          }
    5.69  
    5.70 +        /// <summary>
    5.71 +        /// Gets or sets the title of the dialog window.
    5.72 +        /// </summary>
    5.73 +        public string WindowTitle
    5.74 +        {
    5.75 +            get => this._WindowTitle;
    5.76 +            set
    5.77 +            {
    5.78 +                this._WindowTitle = value;
    5.79 +                this.OnPropertyChanged();
    5.80 +            }
    5.81 +        }
    5.82 +
    5.83          #endregion
    5.84  
    5.85          #region Constructors
    5.86 @@ -300,17 +323,17 @@
    5.87          /// <summary>
    5.88          /// Primary constructor.
    5.89          /// </summary>
    5.90 -        /// <param name="handshake">The handshake object for this dialog.</param>
    5.91 -        public HandshakeViewModel(Handshake handshake, Action closeWindow) : base(handshake, closeWindow)
    5.92 +        /// <param name="dialog">The dialog object for this dialog.</param>
    5.93 +        /// <param name="closeWindow">The action to close this dialog.</param>
    5.94 +        public HandshakeViewModel(Dialog dialog, Action closeWindow)
    5.95          {
    5.96 -            this.Content = this;
    5.97 -            this.Handshake = handshake;
    5.98 +            this.Dialog = dialog;
    5.99              this.CloseWindowAction = closeWindow;
   5.100  
   5.101              // Update myself and partner identities
   5.102              try
   5.103              {
   5.104 -                pEpIdentity _myself = handshake.Myself.ToCOMType();
   5.105 +                pEpIdentity _myself = dialog.Myself.ToCOMType();
   5.106                  _myself = ThisAddIn.PEPEngine.Myself(_myself);
   5.107                  this.Myself = new PEPIdentity(_myself);
   5.108  
   5.109 @@ -322,7 +345,7 @@
   5.110  
   5.111              try
   5.112              {
   5.113 -                pEpIdentity _partner = handshake.Partner.ToCOMType();
   5.114 +                pEpIdentity _partner = dialog.Partner.ToCOMType();
   5.115                  _partner = ThisAddIn.PEPEngine.UpdateIdentity(_partner);
   5.116                  this.Partner = new PEPIdentity(_partner);
   5.117  
   5.118 @@ -335,7 +358,7 @@
   5.119              catch (Exception ex)
   5.120              {
   5.121                  Log.Error("HandshakeViewModel.Ctr: Error updating partner. " + ex.ToString());
   5.122 -            }            
   5.123 +            }
   5.124  
   5.125              // Create User Ids
   5.126              this.UIDMyself = this.Myself?.UserName + " <" + this.Myself?.Address + ">";
   5.127 @@ -366,17 +389,13 @@
   5.128              this.SetButtonsText();
   5.129  
   5.130              // Get own identities to select whether to sync them or not
   5.131 -            if ((this.Mode == Handshake.HandshakeMode.SyncTypeA) ||
   5.132 -                (this.Mode == Handshake.HandshakeMode.SyncTypeB) ||
   5.133 -                (this.Mode == Handshake.HandshakeMode.SyncTypeC))
   5.134 +            if ((this.DialogType == Dialog.DialogType.KeySync) &&
   5.135 +                (ThisAddIn.PEPEngine.OwnIdentitiesRetrieve() is pEpIdentity[] ownIdentities))
   5.136              {
   5.137 -                if (ThisAddIn.PEPEngine.OwnIdentitiesRetrieve() is pEpIdentity[] ownIdentities)
   5.138 +                this._SyncIdentities = new ObservableCollection<SyncIdentity>();
   5.139 +                foreach (pEpIdentity ownIdentity in ownIdentities)
   5.140                  {
   5.141 -                    this._SyncIdentities = new ObservableCollection<SyncIdentity>();
   5.142 -                    foreach (pEpIdentity ownIdentity in ownIdentities)
   5.143 -                    {
   5.144 -                        this._SyncIdentities.Add(new SyncIdentity { Identity = ownIdentity, Synchronize = true });
   5.145 -                    }
   5.146 +                    this._SyncIdentities.Add(new SyncIdentity { Identity = ownIdentity, Synchronize = true });
   5.147                  }
   5.148              }
   5.149          }
   5.150 @@ -417,28 +436,7 @@
   5.151              {
   5.152                  if (this._ButtonConfirmOnClick == null)
   5.153                  {
   5.154 -                    switch (this.Mode)
   5.155 -                    {
   5.156 -                        case Handshake.HandshakeMode.SyncTypeA:
   5.157 -                        case Handshake.HandshakeMode.SyncTypeB:
   5.158 -                        case Handshake.HandshakeMode.SyncTypeC:
   5.159 -                            {
   5.160 -                                this._ButtonConfirmOnClick = new RelayCommand(p => this.ConfirmSyncHandshakeAndCloseDialog());
   5.161 -                            }
   5.162 -                            break;
   5.163 -                        case Handshake.HandshakeMode.ForceProtectionSendKey:
   5.164 -                        case Handshake.HandshakeMode.ForceProtectionImportKey:
   5.165 -                            {
   5.166 -                                this._ButtonConfirmOnClick = new RelayCommand(p => this.TrustKeyAndCloseDialog());
   5.167 -                            }
   5.168 -                            break;
   5.169 -                        case Handshake.HandshakeMode.Standard:
   5.170 -                        default:
   5.171 -                            {
   5.172 -                                this._ButtonConfirmOnClick = new RelayCommand(p => this.TrustKeyAndCloseDialog());
   5.173 -                            }
   5.174 -                            break;
   5.175 -                    }
   5.176 +                    this._ButtonConfirmOnClick = new RelayCommand(p => this.TrustKeyAndCloseDialog());
   5.177                  }
   5.178  
   5.179                  return this._ButtonConfirmOnClick;
   5.180 @@ -454,28 +452,7 @@
   5.181              {
   5.182                  if (this._ButtonWrongOnClick == null)
   5.183                  {
   5.184 -                    switch (this.Mode)
   5.185 -                    {
   5.186 -                        case Handshake.HandshakeMode.SyncTypeA:
   5.187 -                        case Handshake.HandshakeMode.SyncTypeB:
   5.188 -                        case Handshake.HandshakeMode.SyncTypeC:
   5.189 -                            {
   5.190 -                                this._ButtonWrongOnClick = new RelayCommand(p => this.DenySyncHandshakeAndCloseDialog());
   5.191 -                            }
   5.192 -                            break;
   5.193 -                        case Handshake.HandshakeMode.ForceProtectionSendKey:
   5.194 -                        case Handshake.HandshakeMode.ForceProtectionImportKey:
   5.195 -                            {
   5.196 -                                this._ButtonWrongOnClick = new RelayCommand(p => this.MistrustKeyAndCloseDialog());
   5.197 -                            }
   5.198 -                            break;
   5.199 -                        case Handshake.HandshakeMode.Standard:
   5.200 -                        default:
   5.201 -                            {
   5.202 -                                this._ButtonWrongOnClick = new RelayCommand(p => this.MistrustKeyAndCloseDialog());
   5.203 -                            }
   5.204 -                            break;
   5.205 -                    }
   5.206 +                    this._ButtonWrongOnClick = new RelayCommand(p => this.MistrustKeyAndCloseDialog());
   5.207                  }
   5.208  
   5.209                  return this._ButtonWrongOnClick;
   5.210 @@ -487,24 +464,6 @@
   5.211          #region Methods
   5.212  
   5.213          /// <summary>
   5.214 -        /// Confirms the sync handshake and closes the dialog.
   5.215 -        /// </summary>
   5.216 -        private void ConfirmSyncHandshakeAndCloseDialog()
   5.217 -        {
   5.218 -            this.DialogResult = true;
   5.219 -            this.CloseWindowAction?.Invoke();
   5.220 -        }
   5.221 -
   5.222 -        /// <summary>
   5.223 -        /// Denies the sync handshake and closes the dialog.
   5.224 -        /// </summary>
   5.225 -        private void DenySyncHandshakeAndCloseDialog()
   5.226 -        {
   5.227 -            this.DialogResult = false;
   5.228 -            this.CloseWindowAction?.Invoke();
   5.229 -        }
   5.230 -
   5.231 -        /// <summary>
   5.232          /// Mistrusts the partner's identity key and closes the dialog.
   5.233          /// </summary>
   5.234          private void MistrustKeyAndCloseDialog()
   5.235 @@ -563,20 +522,11 @@
   5.236          /// </summary>
   5.237          private void SetButtonsText()
   5.238          {
   5.239 -            switch (this.Mode)
   5.240 +            switch (this.DialogType)
   5.241              {
   5.242 -                case Handshake.HandshakeMode.SyncTypeA:
   5.243 -                case Handshake.HandshakeMode.SyncTypeB:
   5.244 -                case Handshake.HandshakeMode.SyncTypeC:
   5.245 -                    {
   5.246 -                        this.ButtonConfirmText = Properties.Resources.Handshake_JoinDeviceGroup;
   5.247 -                        this.ButtonWrongText = Properties.Resources.Handshake_DoNotJoinDeviceGroup;
   5.248 -                    }
   5.249 +                case Dialog.DialogType.Undefined:
   5.250                      break;
   5.251 -                case Handshake.HandshakeMode.ForceProtectionSendKey:
   5.252 -                case Handshake.HandshakeMode.ForceProtectionImportKey:
   5.253 -                case Handshake.HandshakeMode.Standard:
   5.254 -                default:
   5.255 +                case Dialog.DialogType.Handshake:
   5.256                      {
   5.257                          // Handshake mode button text depends on active tab
   5.258                          if (this.ActiveTab == Tabs.Fingerprint)
   5.259 @@ -591,6 +541,16 @@
   5.260                          }
   5.261                      }
   5.262                      break;
   5.263 +                case Dialog.DialogType.KeySync:
   5.264 +                    break;
   5.265 +                case Dialog.DialogType.KeyImportPEP:
   5.266 +                    break;
   5.267 +                case Dialog.DialogType.KeyImportPGP:
   5.268 +                    break;
   5.269 +                case Dialog.DialogType.ForceProtection:
   5.270 +                    break;
   5.271 +                default:
   5.272 +                    break;
   5.273              }
   5.274          }
   5.275  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/UI/ViewModels/IDialogWindowViewModel.cs	Thu Aug 22 16:15:16 2019 +0200
     6.3 @@ -0,0 +1,28 @@
     6.4 +using pEp.UI.Models;
     6.5 +using System;
     6.6 +
     6.7 +namespace pEp.UI.ViewModels
     6.8 +{
     6.9 +    internal interface IDialogWindowViewModel
    6.10 +    {
    6.11 +        /// <summary>
    6.12 +        /// The action to close the dialog window.
    6.13 +        /// </summary>
    6.14 +        Action CloseWindowAction { get; }
    6.15 +
    6.16 +        /// <summary>
    6.17 +        /// The dialog object.
    6.18 +        /// </summary>
    6.19 +        Dialog Dialog { get; }
    6.20 +
    6.21 +        /// <summary>
    6.22 +        /// The result of the dialog.
    6.23 +        /// </summary>
    6.24 +        bool? DialogResult { get; }
    6.25 +
    6.26 +        /// <summary>
    6.27 +        /// The title of the dialog window.
    6.28 +        /// </summary>
    6.29 +        string WindowTitle { get; set; }
    6.30 +    }
    6.31 +}
     7.1 --- a/UI/ViewModels/SyncWizardViewModel.cs	Thu Aug 22 10:08:25 2019 +0200
     7.2 +++ b/UI/ViewModels/SyncWizardViewModel.cs	Thu Aug 22 16:15:16 2019 +0200
     7.3 @@ -1,5 +1,4 @@
     7.4 -using pEp.UI.Models;
     7.5 -using System;
     7.6 +using System;
     7.7  using System.Collections.Generic;
     7.8  using System.Collections.ObjectModel;
     7.9  using System.Windows.Media.Imaging;
    7.10 @@ -8,12 +7,18 @@
    7.11  {
    7.12      internal class SyncWizardViewModel : WizardViewModelBase
    7.13      {
    7.14 -        public SyncWizardViewModel(Handshake handshake, Action closeWindow) : base(handshake, closeWindow)
    7.15 +        /// <summary>
    7.16 +        /// Primary constructor.
    7.17 +        /// </summary>
    7.18 +        /// <param name="dialog">The dialog object.</param>
    7.19 +        /// <param name="closeWindow">The Action to close the Dialog window.</param>
    7.20 +        public SyncWizardViewModel(Dialog dialog, Action closeWindow) : base(dialog, closeWindow)
    7.21          {
    7.22 -            this.Handshake = handshake;
    7.23 -            this.CloseWindowAction = closeWindow;
    7.24          }
    7.25  
    7.26 +        /// <summary>
    7.27 +        /// Creates the pages of the Sync wizard.
    7.28 +        /// </summary>
    7.29          public override void CreatePages()
    7.30          {
    7.31              // Create Sync Wizard Pages
    7.32 @@ -22,35 +27,23 @@
    7.33                  // Welcome page
    7.34                  new WizardGenericPageViewModel
    7.35                  {
    7.36 -                    ExplanationText = "Welcome",
    7.37 -                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute))
    7.38 +                    ExplanationText = Properties.Resources.Handshake_SyncTypeAExplanationText,
    7.39 +                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute)),
    7.40 +                    IsButtonBackVisible = false
    7.41                  },
    7.42 -                
    7.43 -                // Step 1 
    7.44 +                                
    7.45 +                // Handshake
    7.46 +                new WizardHandshakePageViewModel(this.Dialog, this.CloseWindowAction),
    7.47 +
    7.48 +                // Waiting for completion
    7.49                  new WizardGenericPageViewModel
    7.50                  {
    7.51 -                    ExplanationText = "Step 1",
    7.52 -                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute))
    7.53 -                },
    7.54 -
    7.55 -                // Step 2 
    7.56 -                new WizardGenericPageViewModel
    7.57 -                {
    7.58 -                    ExplanationText = "Step 2",
    7.59 -                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute))
    7.60 -                },
    7.61 -
    7.62 -                // Step 3 
    7.63 -                new WizardGenericPageViewModel
    7.64 -                {
    7.65 -                    ExplanationText = "Step 3",
    7.66 -                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute))
    7.67 -                },
    7.68 -
    7.69 -                // Handshake
    7.70 -                new WizardHandshakePageViewModel(this.Handshake, this.CloseWindowAction),
    7.71 -                new HandshakeViewModel(this.Handshake, this.CloseWindowAction)
    7.72 -
    7.73 +                    //ButtonCancelStyle = 
    7.74 +                    ExplanationText = Properties.Resources.KeySyncWizard_PEPStep3ExplanationText,
    7.75 +                    Image = new BitmapImage(new Uri("pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png", UriKind.RelativeOrAbsolute)),
    7.76 +                    IsButtonBackVisible = false,
    7.77 +                    IsButtonNextVisible = false,
    7.78 +                }
    7.79              });
    7.80          }
    7.81      }
     8.1 --- a/UI/ViewModels/WizardHandshakePageViewModel.cs	Thu Aug 22 10:08:25 2019 +0200
     8.2 +++ b/UI/ViewModels/WizardHandshakePageViewModel.cs	Thu Aug 22 16:15:16 2019 +0200
     8.3 @@ -1,24 +1,30 @@
     8.4  using pEp.UI.Models;
     8.5  using System;
     8.6 -using System.Collections.Generic;
     8.7 -using System.Linq;
     8.8 -using System.Text;
     8.9 -using System.Threading.Tasks;
    8.10  
    8.11  namespace pEp.UI.ViewModels
    8.12  {
    8.13      internal class WizardHandshakePageViewModel : WizardPageViewModelBase
    8.14      {
    8.15 +        /// <summary>
    8.16 +        /// Primary constructor.
    8.17 +        /// </summary>
    8.18          public WizardHandshakePageViewModel()
    8.19          {
    8.20 +            this.IsButtonAcceptHandshakeVisible = true;
    8.21              this.IsButtonBackVisible = false;
    8.22 -            this.IsButtonCancelVisible = false;
    8.23 +            this.IsButtonCancelVisible = true;
    8.24              this.IsButtonNextVisible = false;
    8.25 +            this.IsButtonRejectHandshakeVisible = true;
    8.26          }
    8.27  
    8.28 -        public WizardHandshakePageViewModel(Handshake handshake, Action closeWindow) : this()
    8.29 +        /// <summary>
    8.30 +        /// Secondary constructor
    8.31 +        /// </summary>
    8.32 +        /// <param name="dialog">The dialog object.</param>
    8.33 +        /// <param name="closeWindow">The Action to close the Dialog window.</param>
    8.34 +        public WizardHandshakePageViewModel(Dialog dialog, Action closeWindow) : this()
    8.35          {
    8.36 -            this.Content = new HandshakeViewModel(handshake, closeWindow);
    8.37 +            this.Content = new HandshakeViewModel(dialog, closeWindow);           
    8.38          }
    8.39      }
    8.40  }
     9.1 --- a/UI/ViewModels/WizardPageViewModelBase.cs	Thu Aug 22 10:08:25 2019 +0200
     9.2 +++ b/UI/ViewModels/WizardPageViewModelBase.cs	Thu Aug 22 16:15:16 2019 +0200
     9.3 @@ -1,20 +1,17 @@
     9.4 -using System;
     9.5 -using System.Collections.Generic;
     9.6 -using System.Collections.ObjectModel;
     9.7 -using System.Linq;
     9.8 -using System.Text;
     9.9 -using System.Threading.Tasks;
    9.10 -using System.Windows;
    9.11 -
    9.12 -namespace pEp.UI.ViewModels
    9.13 +namespace pEp.UI.ViewModels
    9.14  {
    9.15      public abstract class WizardPageViewModelBase : ViewModelBase
    9.16      {
    9.17          private ViewModelBase   _Content                            = null;
    9.18 +        private bool            _IsButtonAcceptHandshakeVisible     = false;
    9.19          private bool            _IsButtonBackVisible                = true;
    9.20          private bool            _IsButtonCancelVisible              = true;
    9.21          private bool            _IsButtonNextVisible                = true;
    9.22 +        private bool            _IsButtonRejectHandshakeVisible     = false;
    9.23  
    9.24 +        /// <summary>
    9.25 +        /// The content of the wizard page.
    9.26 +        /// </summary>
    9.27          public ViewModelBase Content
    9.28          {
    9.29              get => this._Content;
    9.30 @@ -25,6 +22,22 @@
    9.31              }
    9.32          }
    9.33  
    9.34 +        /// <summary>
    9.35 +        /// Gets or sets whether the Accept Handshake button is visible.
    9.36 +        /// </summary>
    9.37 +        public bool IsButtonAcceptHandshakeVisible
    9.38 +        {
    9.39 +            get => this._IsButtonAcceptHandshakeVisible;
    9.40 +            set
    9.41 +            {
    9.42 +                this._IsButtonAcceptHandshakeVisible = value;
    9.43 +                this.OnPropertyChanged();
    9.44 +            }
    9.45 +        }
    9.46 +
    9.47 +        /// <summary>
    9.48 +        /// Gets or sets whether the Back button is visible.
    9.49 +        /// </summary>
    9.50          public bool IsButtonBackVisible
    9.51          {
    9.52              get => this._IsButtonBackVisible;
    9.53 @@ -35,6 +48,9 @@
    9.54              }
    9.55          }
    9.56  
    9.57 +        /// <summary>
    9.58 +        /// Gets or sets whether the Cancel button is visible.
    9.59 +        /// </summary>
    9.60          public bool IsButtonCancelVisible
    9.61          {
    9.62              get => this._IsButtonCancelVisible;
    9.63 @@ -45,6 +61,9 @@
    9.64              }
    9.65          }
    9.66  
    9.67 +        /// <summary>
    9.68 +        /// Gets or sets whether the Next button is visible.
    9.69 +        /// </summary>
    9.70          public bool IsButtonNextVisible
    9.71          {
    9.72              get => this._IsButtonNextVisible;
    9.73 @@ -55,9 +74,24 @@
    9.74              }
    9.75          }
    9.76  
    9.77 +        /// <summary>
    9.78 +        /// Gets or sets whether the Reject handshake button is visible.
    9.79 +        /// </summary>
    9.80 +        public bool IsButtonRejectHandshakeVisible
    9.81 +        {
    9.82 +            get => this._IsButtonRejectHandshakeVisible;
    9.83 +            set
    9.84 +            {
    9.85 +                this._IsButtonRejectHandshakeVisible = value;
    9.86 +                this.OnPropertyChanged();
    9.87 +            }
    9.88 +        }
    9.89 +
    9.90 +        /// <summary>
    9.91 +        /// Primary constructor.
    9.92 +        /// </summary>
    9.93          public WizardPageViewModelBase()
    9.94          {
    9.95 -
    9.96          }
    9.97      }
    9.98  }
    10.1 --- a/UI/ViewModels/WizardViewModelBase.cs	Thu Aug 22 10:08:25 2019 +0200
    10.2 +++ b/UI/ViewModels/WizardViewModelBase.cs	Thu Aug 22 16:15:16 2019 +0200
    10.3 @@ -1,49 +1,65 @@
    10.4 -using pEp.UI.Models;
    10.5 -using pEpCOMServerAdapterLib;
    10.6 +using pEpCOMServerAdapterLib;
    10.7  using System;
    10.8  using System.Collections.ObjectModel;
    10.9  
   10.10  namespace pEp.UI.ViewModels
   10.11  {
   10.12 -    internal abstract class WizardViewModelBase : DialogWindowViewModel
   10.13 +    internal abstract class WizardViewModelBase : ViewModelBase, IDialogWindowViewModel
   10.14      {
   10.15          #region Fields
   10.16  
   10.17          protected           RelayCommand                                    _AcceptHandshakeCommand;
   10.18          private             ViewModelBase                                   _CurrentPage;
   10.19 -        protected           RelayCommand                                    _DenyHandshakeCommand;
   10.20          protected           RelayCommand                                    _MoveBackCommand;
   10.21          protected           RelayCommand                                    _MoveNextCommand;
   10.22          protected           ReadOnlyCollection<ViewModelBase>               _Pages;
   10.23 +        protected           RelayCommand                                    _RejectHandshakeCommand;
   10.24          protected           string                                          _WindowTitle;
   10.25  
   10.26          #endregion
   10.27  
   10.28          #region Properties 
   10.29  
   10.30 -        public virtual RelayCommand AcceptHandshakeCommand
   10.31 +        /// <summary>
   10.32 +        /// The command for when a handshake has been accepted.
   10.33 +        /// </summary>
   10.34 +        public RelayCommand AcceptHandshakeCommand
   10.35          {
   10.36              get
   10.37              {
   10.38                  if (this._AcceptHandshakeCommand == null)
   10.39                  {
   10.40 -                    this._AcceptHandshakeCommand = new RelayCommand(param => this.AcceptHandshakeAndMoveToNextPage());
   10.41 +                    this._AcceptHandshakeCommand = new RelayCommand(p => this.AcceptHandshake());
   10.42                  }
   10.43  
   10.44                  return this._AcceptHandshakeCommand;
   10.45              }
   10.46          }
   10.47  
   10.48 +        /// <summary>
   10.49 +        /// Whether or not the wizard can move on to the next page.
   10.50 +        /// </summary>
   10.51          bool CanMoveToNextPage
   10.52          {
   10.53              get => (this.CurrentPage != null);
   10.54          }
   10.55  
   10.56 +        /// <summary>
   10.57 +        /// Whether or not the wizard can move back to the previous page.
   10.58 +        /// </summary>
   10.59          bool CanMoveToPreviousPage
   10.60          {
   10.61              get => (this.CurrentPage != null);
   10.62          }
   10.63  
   10.64 +        /// <summary>
   10.65 +        /// The action to close the dialog window.
   10.66 +        /// </summary>
   10.67 +        public Action CloseWindowAction { get; }
   10.68 +
   10.69 +        /// <summary>
   10.70 +        /// The currently displayed page in the wizard.
   10.71 +        /// </summary>
   10.72          public ViewModelBase CurrentPage
   10.73          {
   10.74              get => this._CurrentPage;
   10.75 @@ -58,30 +74,35 @@
   10.76              }
   10.77          }
   10.78  
   10.79 +        /// <summary>
   10.80 +        /// The index of the currently displayed page.
   10.81 +        /// </summary>
   10.82          public int CurrentPageIndex
   10.83          {
   10.84 -            get => this._Pages.IndexOf(this.CurrentPage);            
   10.85 +            get => this._Pages.IndexOf(this.CurrentPage);
   10.86          }
   10.87  
   10.88 -        public virtual RelayCommand DenyHandshakeCommand
   10.89 -        {
   10.90 -            get
   10.91 -            {
   10.92 -                if (this._DenyHandshakeCommand == null)
   10.93 -                {
   10.94 -                    this._DenyHandshakeCommand = new RelayCommand(param => this.DenyHandshakeAndMoveToNextPage());
   10.95 -                }
   10.96 +        /// <summary>
   10.97 +        ///The dialog object.
   10.98 +        /// </summary>
   10.99 +        public Dialog Dialog { get; }
  10.100  
  10.101 -                return this._DenyHandshakeCommand;
  10.102 -            }
  10.103 -        }
  10.104 +        /// <summary>
  10.105 +        /// The result of the dialog.
  10.106 +        /// </summary>
  10.107 +        public bool? DialogResult { get; set; } = null;
  10.108  
  10.109 +        /// <summary>
  10.110 +        /// Whether or not the currently displayed page is the last one.
  10.111 +        /// </summary>
  10.112          private bool IsLastPage
  10.113          {
  10.114              get => (this.CurrentPageIndex >= (this.Pages.Count - 1));
  10.115          }
  10.116  
  10.117 -
  10.118 +        /// <summary>
  10.119 +        /// Command to move one step back in the wizard.
  10.120 +        /// </summary>
  10.121          public virtual RelayCommand MoveBackCommand
  10.122          {
  10.123              get
  10.124 @@ -95,6 +116,9 @@
  10.125              }
  10.126          }
  10.127  
  10.128 +        /// <summary>
  10.129 +        /// Command to move one step further in the wizard.
  10.130 +        /// </summary>
  10.131          public virtual RelayCommand MoveNextCommand
  10.132          {
  10.133              get
  10.134 @@ -108,6 +132,9 @@
  10.135              }
  10.136          }
  10.137  
  10.138 +        /// <summary>
  10.139 +        /// The pages that are shown in the wizard.
  10.140 +        /// </summary>
  10.141          public ReadOnlyCollection<ViewModelBase> Pages
  10.142          {
  10.143              get
  10.144 @@ -121,59 +148,110 @@
  10.145              }
  10.146          }
  10.147  
  10.148 +        /// <summary>
  10.149 +        /// The command for when a handshake has been rejected.
  10.150 +        /// </summary>
  10.151 +        public RelayCommand RejectHandshakeCommand
  10.152 +        {
  10.153 +            get
  10.154 +            {
  10.155 +                if (this._RejectHandshakeCommand == null)
  10.156 +                {
  10.157 +                    this._RejectHandshakeCommand = new RelayCommand(p => this.RejectHandshake());
  10.158 +                }
  10.159 +
  10.160 +                return this._RejectHandshakeCommand;
  10.161 +            }
  10.162 +        }
  10.163 +
  10.164 +        /// <summary>
  10.165 +        /// The window title of the dialog.
  10.166 +        /// </summary>
  10.167 +        public string WindowTitle
  10.168 +        {
  10.169 +            get => this._WindowTitle;
  10.170 +            set
  10.171 +            {
  10.172 +                this._WindowTitle = value;
  10.173 +                this.OnPropertyChanged();
  10.174 +            }
  10.175 +        }
  10.176 +
  10.177          #endregion
  10.178  
  10.179          #region Constructors
  10.180  
  10.181 -        public WizardViewModelBase(Handshake handshake, Action closeWindow) : base(handshake, closeWindow)
  10.182 +        /// <summary>
  10.183 +        /// Primary constructor.
  10.184 +        /// </summary>
  10.185 +        /// <param name="dialog">The dialog object to use.</param>
  10.186 +        /// <param name="closeWindow">The Action to close the dialog window.</param>
  10.187 +        public WizardViewModelBase(Dialog dialog, Action closeWindow)
  10.188          {
  10.189 +            this.Dialog = dialog;
  10.190 +            this.CloseWindowAction = closeWindow;
  10.191              this.CreatePages();
  10.192              this.CurrentPage = this.Pages[0];
  10.193 +            this.WindowTitle = Properties.Resources.Handshake_SyncFormText;
  10.194          }
  10.195  
  10.196          #endregion
  10.197  
  10.198          #region Methods
  10.199  
  10.200 -        private void AcceptHandshakeAndMoveToNextPage()
  10.201 +        /// <summary>
  10.202 +        /// Accepts a handshake.
  10.203 +        /// </summary>
  10.204 +        private void AcceptHandshake()
  10.205          {
  10.206 -            // Trust Partner Key
  10.207 -            try
  10.208 +            switch (this.Dialog.Type)
  10.209              {
  10.210 -                pEpIdentity partner = this.Handshake.Partner.ToCOMType();
  10.211 -                ThisAddIn.PEPEngine.TrustPersonalKey(partner);
  10.212 +                case Dialog.DialogType.Undefined:
  10.213 +                    break;
  10.214 +                case Dialog.DialogType.Handshake:
  10.215 +                    break;
  10.216 +                case Dialog.DialogType.KeySync:
  10.217 +                    {
  10.218 +                        try
  10.219 +                        {
  10.220 +                            ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeAccepted, null);
  10.221 +                        }
  10.222 +                        catch (Exception ex)
  10.223 +                        {
  10.224 +                            Log.Error("AcceptHandshake: Error delivering handshake result. " + ex.ToString());                            
  10.225 +                        }
  10.226 +                        this.DialogResult =true;
  10.227 +                        this.MoveToNextPage();
  10.228 +                    }
  10.229 +                    break;
  10.230 +                case Dialog.DialogType.KeyImportPEP:
  10.231 +                    break;
  10.232 +                case Dialog.DialogType.KeyImportPGP:
  10.233 +                    break;
  10.234 +                case Dialog.DialogType.ForceProtection:
  10.235 +                    break;
  10.236 +                default:
  10.237 +                    break;
  10.238              }
  10.239 -            catch (Exception ex)
  10.240 -            {
  10.241 -                Log.Error("AcceptHandshakeAndMoveToNextPage: Error occured. " + ex.ToString());
  10.242 -            }
  10.243 -
  10.244 -            this.MoveToNextPage();
  10.245          }
  10.246  
  10.247 -        public abstract void CreatePages();
  10.248 +        /// <summary>
  10.249 +        /// Creates all pages that are displayed in the wizard.
  10.250 +        /// </summary>
  10.251 +        public abstract void CreatePages();       
  10.252  
  10.253 -        private void DenyHandshakeAndMoveToNextPage()
  10.254 -        {
  10.255 -            // Mistrust Partner Key
  10.256 -            try
  10.257 -            {
  10.258 -                pEpIdentity partner = this.Handshake.Partner.ToCOMType();
  10.259 -                ThisAddIn.PEPEngine.KeyMistrusted(partner);
  10.260 -            }
  10.261 -            catch (Exception ex)
  10.262 -            {
  10.263 -                Log.Error("DenyHandshakeAndMoveToNextPage: Error occured. " + ex.ToString());
  10.264 -            }
  10.265 -
  10.266 -            this.MoveToLastPage();
  10.267 -        }
  10.268 -
  10.269 +        /// <summary>
  10.270 +        /// Moves to the last wizard page.
  10.271 +        /// </summary>
  10.272          protected void MoveToLastPage()
  10.273          {
  10.274              this.CurrentPage = this.Pages[this.Pages.Count - 1];
  10.275          }
  10.276  
  10.277 +        /// <summary>
  10.278 +        /// Moves the wizard to the next page or closes the dialog in case
  10.279 +        /// it is already on the last page.
  10.280 +        /// </summary>
  10.281          protected void MoveToNextPage()
  10.282          {
  10.283              if (this.IsLastPage)
  10.284 @@ -186,6 +264,9 @@
  10.285              }
  10.286          }
  10.287  
  10.288 +        /// <summary>
  10.289 +        /// Moves the wizard to the previous page if possible.
  10.290 +        /// </summary>
  10.291          protected void MoveToPreviousPage()
  10.292          {
  10.293              if (this.CurrentPageIndex > 0)
  10.294 @@ -198,6 +279,56 @@
  10.295              }
  10.296          }
  10.297  
  10.298 +        /// <summary>
  10.299 +        /// Receives a sync handshake signal and acts accordingly.
  10.300 +        /// </summary>
  10.301 +        /// <param name="signal">The sync handshake signal.</param>
  10.302 +        public void NotifySyncNotification(SyncHandshakeSignal signal)
  10.303 +        {
  10.304 +            // TODO: better way needed
  10.305 +            if ((this.CurrentPageIndex == 2) &&
  10.306 +                (signal == SyncHandshakeSignal.SyncNotifyFormingGroup))
  10.307 +            {
  10.308 +                this.MoveToNextPage();
  10.309 +            }
  10.310 +        }
  10.311 +
  10.312 +        /// <summary>
  10.313 +        /// Rejects a handshake.
  10.314 +        /// </summary>
  10.315 +        private void RejectHandshake()
  10.316 +        {
  10.317 +            switch (this.Dialog.Type)
  10.318 +            {
  10.319 +                case Dialog.DialogType.Undefined:
  10.320 +                    break;
  10.321 +                case Dialog.DialogType.Handshake:
  10.322 +                    break;
  10.323 +                case Dialog.DialogType.KeySync:
  10.324 +                    {
  10.325 +                        try
  10.326 +                        {
  10.327 +                            ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeRejected, null);
  10.328 +                        }
  10.329 +                        catch (Exception ex)
  10.330 +                        {
  10.331 +                            Log.Error("RejectHandshake: Error delivering handshake result. " + ex.ToString());
  10.332 +                        }
  10.333 +                        this.DialogResult = false;
  10.334 +                        this.MoveToNextPage();
  10.335 +                    }
  10.336 +                    break;
  10.337 +                case Dialog.DialogType.KeyImportPEP:
  10.338 +                    break;
  10.339 +                case Dialog.DialogType.KeyImportPGP:
  10.340 +                    break;
  10.341 +                case Dialog.DialogType.ForceProtection:
  10.342 +                    break;
  10.343 +                default:
  10.344 +                    break;
  10.345 +            }
  10.346 +        }
  10.347 +
  10.348          #endregion
  10.349      }
  10.350  }
    11.1 --- a/UI/Views/DialogWindow.xaml	Thu Aug 22 10:08:25 2019 +0200
    11.2 +++ b/UI/Views/DialogWindow.xaml	Thu Aug 22 16:15:16 2019 +0200
    11.3 @@ -27,9 +27,4 @@
    11.4              <v:HandshakeView />
    11.5          </DataTemplate>
    11.6      </Window.Resources>
    11.7 -
    11.8 -    <ContentControl x:Name="DialogWindowContent"                    
    11.9 -                    Content="{Binding Content}">
   11.10 -    </ContentControl>
   11.11 -    
   11.12  </Window>
    12.1 --- a/UI/Views/DialogWindow.xaml.cs	Thu Aug 22 10:08:25 2019 +0200
    12.2 +++ b/UI/Views/DialogWindow.xaml.cs	Thu Aug 22 16:15:16 2019 +0200
    12.3 @@ -1,5 +1,6 @@
    12.4  using pEp.UI.Models;
    12.5  using pEp.UI.ViewModels;
    12.6 +using pEpCOMServerAdapterLib;
    12.7  using System;
    12.8  using System.ComponentModel;
    12.9  using System.Windows;
   12.10 @@ -21,27 +22,25 @@
   12.11              InitializeComponent();
   12.12          }
   12.13  
   12.14 -        /// <summary>
   12.15 -        /// Constructor to build a dialog with a handshake.
   12.16 -        /// </summary>
   12.17 -        /// <param name="type">The type of the dialog.</param>
   12.18 -        /// <param name="handshake">The handshake to perform.</param>
   12.19 -        public DialogWindow(Dialog.Type type, Handshake handshake) : this()
   12.20 +        public DialogWindow(Dialog dialog) : this()
   12.21          {
   12.22              // Assign the necessary ViewModel according to the dialog type.
   12.23 -            switch (type)
   12.24 +            switch (dialog.Type)
   12.25              {
   12.26 -                case Dialog.Type.Handshake:
   12.27 -                    this.DataContext = new HandshakeViewModel(handshake, this.Close);
   12.28 +                case Dialog.DialogType.Handshake:
   12.29 +                    this.Content = new HandshakeViewModel(dialog, this.Close);
   12.30                      break;
   12.31 -                case Dialog.Type.KeySync:
   12.32 -                    this.Content = new SyncWizardViewModel(handshake, this.Close);
   12.33 +                case Dialog.DialogType.KeySync:
   12.34 +                    this.Content = new SyncWizardViewModel(dialog, this.Close);
   12.35                      break;
   12.36 -                case Dialog.Type.KeyImportPEP:
   12.37 -                case Dialog.Type.KeyImportPGP:
   12.38 -                case Dialog.Type.ForceProtection:
   12.39 +                case Dialog.DialogType.KeyImportPEP:
   12.40 +                    break;
   12.41 +                case Dialog.DialogType.KeyImportPGP:
   12.42 +                    break;
   12.43 +                case Dialog.DialogType.ForceProtection:
   12.44 +                    break;
   12.45                  default:
   12.46 -                    throw new NotImplementedException();
   12.47 +                    break;
   12.48              }
   12.49          }
   12.50  
   12.51 @@ -51,9 +50,12 @@
   12.52          private void DialogWindow_Closing(object sender, CancelEventArgs e)
   12.53          {
   12.54              if (this.isShownDialog &&
   12.55 -                (this.DataContext is DialogWindowViewModel viewModel))
   12.56 +                (this.Content is SyncWizardViewModel viewModel))
   12.57              {
   12.58 -                this.DialogResult = viewModel.DialogResult;
   12.59 +                if (viewModel.DialogResult == null)
   12.60 +                {
   12.61 +                    ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeCancel, null);
   12.62 +                }
   12.63              }
   12.64          }
   12.65  
   12.66 @@ -69,6 +71,21 @@
   12.67              return base.ShowDialog();
   12.68          }
   12.69  
   12.70 +        /// <summary>
   12.71 +        /// Notifies about a sync handshake signal.
   12.72 +        /// </summary>
   12.73 +        /// <param name="signal">The sync handshake signal.</param>
   12.74 +        public void NotifySyncNotification(SyncHandshakeSignal signal)
   12.75 +        {
   12.76 +            if (this.Content is SyncWizardViewModel viewModel)
   12.77 +            {
   12.78 +                this.Dispatcher.Invoke(() =>
   12.79 +                {
   12.80 +                    viewModel?.NotifySyncNotification(signal);
   12.81 +                });
   12.82 +            }
   12.83 +        }
   12.84 +
   12.85          #endregion
   12.86      }
   12.87  }
    13.1 --- a/UI/Views/HandshakeView.xaml	Thu Aug 22 10:08:25 2019 +0200
    13.2 +++ b/UI/Views/HandshakeView.xaml	Thu Aug 22 16:15:16 2019 +0200
    13.3 @@ -4,7 +4,6 @@
    13.4               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    13.5               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    13.6               xmlns:p="clr-namespace:pEp.Properties"
    13.7 -             xmlns:local="clr-namespace:pEp.UI.Views"
    13.8               xmlns:ui="clr-namespace:pEp.UI"
    13.9               mc:Ignorable="d" 
   13.10               d:DesignHeight="450" d:DesignWidth="800">
   13.11 @@ -26,6 +25,11 @@
   13.12                  <ui:IsActiveTabToBoolConverter />
   13.13                  <BooleanToVisibilityConverter />
   13.14              </ui:ValueConverterGroup>
   13.15 +            <ui:ValueConverterGroup x:Key="IsNotWizardModeToVisibility">
   13.16 +                <ui:IsWizardModeToBoolConverter />
   13.17 +                <ui:InvertBoolConverter/>
   13.18 +                <BooleanToVisibilityConverter/>
   13.19 +            </ui:ValueConverterGroup>
   13.20              <ui:ValueConverterGroup x:Key="IsSyncModeToVisibility">
   13.21                  <ui:IsSyncModeToBoolConverter />
   13.22                  <BooleanToVisibilityConverter />
   13.23 @@ -52,7 +56,7 @@
   13.24                    IsEditable="True"
   13.25                    IsReadOnly="True"
   13.26                    Focusable="False"
   13.27 -                  Visibility="{Binding Mode, Converter={StaticResource IsSyncModeToVisibility}}">
   13.28 +                  Visibility="{Binding DialogType, Converter={StaticResource IsSyncModeToVisibility}}">
   13.29              <ComboBox.ItemTemplate>
   13.30                  <DataTemplate>
   13.31                      <StackPanel Orientation="Horizontal">
   13.32 @@ -203,19 +207,18 @@
   13.33          <StackPanel Grid.Row="5"
   13.34                      Orientation="Horizontal"
   13.35                      HorizontalAlignment="Right"
   13.36 -                    Margin="0,5,0,0">
   13.37 +                    Margin="0,5,0,0"
   13.38 +                    Visibility="{Binding DialogType, Converter={StaticResource IsNotWizardModeToVisibility}}">
   13.39              <Button Style="{StaticResource StyleButtonWrong}"
   13.40                      HorizontalAlignment="Center"
   13.41                      Margin="0,5,5,5"
   13.42                      Content="{Binding Path=ButtonWrongText, FallbackValue=Wrong}"
   13.43 -                    Command="{Binding ButtonWrongOnClick}"
   13.44 -                    CommandParameter="{Binding ElementName=WindowHandshakeDialog}"/>
   13.45 +                    Command="{Binding ButtonWrongOnClick}"/>
   13.46              <Button Style="{StaticResource StyleButtonConfirm}"
   13.47                      HorizontalAlignment="Center"
   13.48                      Margin="5,5,0,5"
   13.49                      Content="{Binding Path=ButtonConfirmText, FallbackValue=Confirm}"
   13.50                      Command="{Binding ButtonConfirmOnClick}"
   13.51 -                    CommandParameter="{Binding ElementName=WindowHandshakeDialog}"
   13.52                      IsDefault="True"/>
   13.53          </StackPanel>
   13.54      </StackPanel>
    14.1 --- a/UI/Views/WizardPageView.xaml	Thu Aug 22 10:08:25 2019 +0200
    14.2 +++ b/UI/Views/WizardPageView.xaml	Thu Aug 22 16:15:16 2019 +0200
    14.3 @@ -3,10 +3,8 @@
    14.4               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    14.5               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    14.6               xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    14.7 -             xmlns:local="clr-namespace:pEp.UI"
    14.8               xmlns:vm="clr-namespace:pEp.UI.ViewModels"
    14.9               xmlns:v="clr-namespace:pEp.UI.Views"
   14.10 -             xmlns:p="clr-namespace:pEp.Properties"
   14.11               mc:Ignorable="d">
   14.12      <UserControl.Resources>
   14.13          <DataTemplate DataType="{x:Type vm:WizardGenericPageViewModel}">
    15.1 --- a/UI/Views/WizardView.xaml	Thu Aug 22 10:08:25 2019 +0200
    15.2 +++ b/UI/Views/WizardView.xaml	Thu Aug 22 16:15:16 2019 +0200
    15.3 @@ -22,7 +22,7 @@
    15.4      </UserControl.Resources>
    15.5  
    15.6      <StackPanel Margin="10"
    15.7 -                Width="470">
    15.8 +                Width="500">
    15.9          
   15.10      <!--Content section-->
   15.11      <UserControl x:Name="WizardContent"
   15.12 @@ -53,6 +53,20 @@
   15.13                      Command="{Binding MoveNextCommand}"
   15.14                      Content="{x:Static p:Resources.Handshake_CancelText}"
   15.15                      Visibility="{Binding Path=CurrentPage.IsButtonCancelVisible, Converter={StaticResource BoolToVisibility}}" />
   15.16 +            <Button x:Name="AcceptHandshakeButton"
   15.17 +                    Margin="5,5,0,5"
   15.18 +                    MinHeight="28"
   15.19 +                    MinWidth="150"
   15.20 +                    Command="{Binding AcceptHandshakeCommand}"
   15.21 +                    Content="{x:Static p:Resources.Handshake_Accept}"
   15.22 +                    Visibility="{Binding Path=CurrentPage.IsButtonAcceptHandshakeVisible, Converter={StaticResource BoolToVisibility}}" />
   15.23 +            <Button x:Name="RejectHandshakeButton"
   15.24 +                    Margin="5,5,0,5"
   15.25 +                    MinHeight="28"
   15.26 +                    MinWidth="150"
   15.27 +                    Command="{Binding RejectHandshakeCommand}"
   15.28 +                    Content="{x:Static p:Resources.Handshake_Reject}"
   15.29 +                    Visibility="{Binding Path=CurrentPage.IsButtonRejectHandshakeVisible, Converter={StaticResource BoolToVisibility}}" />
   15.30          </StackPanel>
   15.31  
   15.32      </StackPanel>
    16.1 --- a/Wrappers/WatchedWindow.cs	Thu Aug 22 10:08:25 2019 +0200
    16.2 +++ b/Wrappers/WatchedWindow.cs	Thu Aug 22 16:15:16 2019 +0200
    16.3 @@ -331,7 +331,7 @@
    16.4                      {
    16.5                          partner = message.To[0];
    16.6                      }
    16.7 -                    handshakeDialog = new DialogWindow(Dialog.Type.Handshake, new Handshake(myself, partner, Handshake.HandshakeMode.Standard));
    16.8 +                    handshakeDialog = new DialogWindow(new Dialog(Dialog.DialogType.Handshake, myself, partner));
    16.9                      handshakeDialog.Closed += HandshakeDialog_Closed;
   16.10                      handshakeDialog.Show();
   16.11                  }
    17.1 --- a/pEpForOutlook.csproj	Thu Aug 22 10:08:25 2019 +0200
    17.2 +++ b/pEpForOutlook.csproj	Thu Aug 22 16:15:16 2019 +0200
    17.3 @@ -440,7 +440,7 @@
    17.4        <DependentUpon>FormReaderSplash.cs</DependentUpon>
    17.5      </Compile>
    17.6      <Compile Include="UI\Models\SyncIdentity.cs" />
    17.7 -    <Compile Include="UI\ViewModels\DialogWindowViewModel.cs" />
    17.8 +    <Compile Include="UI\ViewModels\IDialogWindowViewModel.cs" />
    17.9      <Compile Include="UI\ViewModels\WizardGenericPageViewModel.cs" />
   17.10      <Compile Include="UI\ViewModels\HandshakeViewModel.cs" />
   17.11      <Compile Include="UI\ViewModels\SyncWizardViewModel.cs" />