OUT-590: First sketch of sync wizard, WIP refactor_dialogs
authorThomas
Wed, 21 Aug 2019 08:49:32 +0200
branchrefactor_dialogs
changeset 2709e4a03c070079
parent 2708 dd213ba49cb1
child 2710 c88cebe389d7
OUT-590: First sketch of sync wizard, WIP
AdapterCallbacks.cs
Resources/Dictionary.xaml
UI/Dialog.cs
UI/ViewModels/DialogWindowViewModel.cs
UI/ViewModels/SyncWizardViewModel.cs
UI/ViewModels/WizardGenericPageViewModel.cs
UI/ViewModels/WizardHandshakePageViewModel.cs
UI/ViewModels/WizardPageViewModelBase.cs
UI/ViewModels/WizardViewModelBase.cs
UI/Views/DialogWindow.xaml
UI/Views/DialogWindow.xaml.cs
UI/Views/HandshakeDialog.xaml
UI/Views/WizardPageView.xaml
UI/Views/WizardPageView.xaml.cs
UI/Views/WizardView.xaml
UI/Views/WizardView.xaml.cs
pEpForOutlook.csproj
     1.1 --- a/AdapterCallbacks.cs	Mon Aug 19 09:31:13 2019 +0200
     1.2 +++ b/AdapterCallbacks.cs	Wed Aug 21 08:49:32 2019 +0200
     1.3 @@ -1,5 +1,6 @@
     1.4  using pEp.UI;
     1.5  using pEp.UI.Models;
     1.6 +using pEp.UI.ViewModels;
     1.7  using pEp.UI.Views;
     1.8  using pEpCOMServerAdapterLib;
     1.9  using System;
    1.10 @@ -147,6 +148,7 @@
    1.11          /// <param name="msg">The message to send.</param>
    1.12          public void MessageToSend(ref TextMessage msg)
    1.13          {
    1.14 +            return;
    1.15              Log.Verbose("MessageToSend: Started");
    1.16  
    1.17              if (PEPMessage.Create(msg, out PEPMessage newMessage) != Globals.ReturnStatus.Success)
    1.18 @@ -276,6 +278,7 @@
    1.19              // Create a new STA thread and show dialog on it
    1.20              return await Extensions.TaskExtensions.StartSTATask<bool?>(() =>
    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),
     2.1 --- a/Resources/Dictionary.xaml	Mon Aug 19 09:31:13 2019 +0200
     2.2 +++ b/Resources/Dictionary.xaml	Wed Aug 21 08:49:32 2019 +0200
     2.3 @@ -178,7 +178,7 @@
     2.4      </Style>
     2.5  
     2.6      <!-- Style for the handshake 'Cancel' button -->
     2.7 -    <Style x:Key="StyleCancelButton"
     2.8 +    <Style x:Key="StyleButtonCancel"
     2.9             TargetType="Button"
    2.10             BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
    2.11          <Setter Property="Background"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/UI/Dialog.cs	Wed Aug 21 08:49:32 2019 +0200
     3.3 @@ -0,0 +1,54 @@
     3.4 +using pEp.UI.Models;
     3.5 +using pEp.UI.Views;
     3.6 +using System.Threading.Tasks;
     3.7 +
     3.8 +namespace pEp.UI
     3.9 +{
    3.10 +    internal class Dialog
    3.11 +    {
    3.12 +        public enum Type
    3.13 +        {
    3.14 +            Handshake,
    3.15 +            KeySync,
    3.16 +            KeyImportPEP,
    3.17 +            KeyImportPGP
    3.18 +        }
    3.19 +
    3.20 +        public static async Task<bool?> Show(Type type, PEPIdentity myself, PEPIdentity partner)
    3.21 +        {
    3.22 +            bool? dialogResult = null;
    3.23 +            bool modal = false;
    3.24 +            DialogWindow dialog = null;
    3.25 +
    3.26 +
    3.27 +            switch (type)
    3.28 +            {
    3.29 +                case Type.Handshake:
    3.30 +                    break;
    3.31 +                case Type.KeySync:
    3.32 +                    {
    3.33 +                        modal = true;
    3.34 +                    }
    3.35 +                    break;
    3.36 +                case Type.KeyImportPEP:
    3.37 +                    break;
    3.38 +                case Type.KeyImportPGP:
    3.39 +                    break;
    3.40 +                default:
    3.41 +                    break;
    3.42 +            }
    3.43 +
    3.44 +            if (modal)
    3.45 +            {
    3.46 +                dialog = new DialogWindow(Type.KeySync, new Handshake(myself, partner, Handshake.HandshakeMode.SyncTypeA));
    3.47 +                dialogResult = dialog.ShowDialog();
    3.48 +            }
    3.49 +            else
    3.50 +            {
    3.51 +                dialog?.Show();
    3.52 +            }
    3.53 +
    3.54 +            return dialogResult;
    3.55 +        }
    3.56 +    }
    3.57 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/UI/ViewModels/DialogWindowViewModel.cs	Wed Aug 21 08:49:32 2019 +0200
     4.3 @@ -0,0 +1,71 @@
     4.4 +using pEp.UI.Models;
     4.5 +using pEp.UI.Views;
     4.6 +using System.Windows;
     4.7 +using System.Windows.Controls;
     4.8 +
     4.9 +namespace pEp.UI.ViewModels
    4.10 +{
    4.11 +    internal class DialogWindowViewModel : ViewModelBase
    4.12 +    {
    4.13 +        private RelayCommand<Interfaces.ICloseable>     _CloseWindowCommand = null;
    4.14 +        private ViewModelBase                           _Content = null;
    4.15 +        private string                                  _WindowTitle = null;
    4.16 +
    4.17 +        public RelayCommand<Interfaces.ICloseable> CloseWindowCommand
    4.18 +        {
    4.19 +            get
    4.20 +            {
    4.21 +                if (this._CloseWindowCommand == null)
    4.22 +                {
    4.23 +                    this._CloseWindowCommand = new RelayCommand<Interfaces.ICloseable>(this.CloseWindow);
    4.24 +                }
    4.25 +
    4.26 +                return this._CloseWindowCommand;
    4.27 +            }
    4.28 +        }
    4.29 +
    4.30 +        public ViewModelBase Content
    4.31 +        {
    4.32 +            get => this._Content;
    4.33 +            set
    4.34 +            {
    4.35 +                this._Content = value;
    4.36 +                this.OnPropertyChanged();
    4.37 +            }
    4.38 +        }
    4.39 +
    4.40 +        public string WindowTitle
    4.41 +        {
    4.42 +            get => this._WindowTitle;
    4.43 +            set
    4.44 +            {
    4.45 +                this._WindowTitle = value;
    4.46 +                this.OnPropertyChanged();
    4.47 +            }
    4.48 +        }
    4.49 +
    4.50 +        public DialogWindowViewModel(Dialog.Type type, Handshake handshake, Window window)
    4.51 +        {
    4.52 +            switch (type)
    4.53 +            {
    4.54 +                case Dialog.Type.Handshake:
    4.55 +                    break;
    4.56 +                case Dialog.Type.KeySync:
    4.57 +                    this.WindowTitle = Properties.Resources.Handshake_SyncFormText;
    4.58 +                    this.Content = new SyncWizardViewModel(handshake, window);
    4.59 +                    break;
    4.60 +                case Dialog.Type.KeyImportPEP:
    4.61 +                    break;
    4.62 +                case Dialog.Type.KeyImportPGP:
    4.63 +                    break;
    4.64 +                default:
    4.65 +                    break;
    4.66 +            }
    4.67 +        }
    4.68 +
    4.69 +        private void CloseWindow(Interfaces.ICloseable window)
    4.70 +        {
    4.71 +            window?.Close();
    4.72 +        }
    4.73 +    }
    4.74 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/UI/ViewModels/SyncWizardViewModel.cs	Wed Aug 21 08:49:32 2019 +0200
     5.3 @@ -0,0 +1,50 @@
     5.4 +using pEp.UI.Models;
     5.5 +using System.Collections.Generic;
     5.6 +using System.Collections.ObjectModel;
     5.7 +using System.Windows;
     5.8 +
     5.9 +namespace pEp.UI.ViewModels
    5.10 +{
    5.11 +    internal class SyncWizardViewModel : WizardViewModelBase
    5.12 +    {
    5.13 +        public SyncWizardViewModel(Handshake handshake, Window window) : base(handshake, window)
    5.14 +        {
    5.15 +
    5.16 +        }
    5.17 +
    5.18 +        public override void CreatePages()
    5.19 +        {
    5.20 +            // Create Sync Wizard Pages
    5.21 +            this._Pages = new ReadOnlyCollection<WizardPageViewModelBase>(new List<WizardPageViewModelBase>
    5.22 +            {
    5.23 +                // Welcome page
    5.24 +                new WizardGenericPageViewModel
    5.25 +                {
    5.26 +                    ExplanationText = "Welcome"
    5.27 +                },
    5.28 +                
    5.29 +                // Step 1 
    5.30 +                new WizardGenericPageViewModel
    5.31 +                {
    5.32 +                    ExplanationText = "Step 1"
    5.33 +                },
    5.34 +
    5.35 +                // Step 2 
    5.36 +                new WizardGenericPageViewModel
    5.37 +                {
    5.38 +                    ExplanationText = "Step 2"
    5.39 +                },
    5.40 +
    5.41 +                // Step 3 
    5.42 +                new WizardGenericPageViewModel
    5.43 +                {
    5.44 +                    ExplanationText = "Step 3"
    5.45 +                },
    5.46 +
    5.47 +                // Handshake
    5.48 +                new WizardHandshakePageViewModel()
    5.49 +
    5.50 +            });
    5.51 +        }
    5.52 +    }
    5.53 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/UI/ViewModels/WizardGenericPageViewModel.cs	Wed Aug 21 08:49:32 2019 +0200
     6.3 @@ -0,0 +1,27 @@
     6.4 +using System;
     6.5 +using System.Collections.Generic;
     6.6 +using System.Linq;
     6.7 +using System.Text;
     6.8 +using System.Threading.Tasks;
     6.9 +
    6.10 +namespace pEp.UI.ViewModels
    6.11 +{
    6.12 +    public class WizardGenericPageViewModel : WizardPageViewModelBase
    6.13 +    {
    6.14 +        private string _ExplanationText;
    6.15 +
    6.16 +        public string ExplanationText
    6.17 +        {
    6.18 +            get => this._ExplanationText;
    6.19 +            set
    6.20 +            {
    6.21 +                this._ExplanationText = value;
    6.22 +                this.OnPropertyChanged();
    6.23 +            }
    6.24 +        }
    6.25 +
    6.26 +        public WizardGenericPageViewModel()
    6.27 +        {
    6.28 +        }
    6.29 +    }
    6.30 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/UI/ViewModels/WizardHandshakePageViewModel.cs	Wed Aug 21 08:49:32 2019 +0200
     7.3 @@ -0,0 +1,16 @@
     7.4 +using System;
     7.5 +using System.Collections.Generic;
     7.6 +using System.Linq;
     7.7 +using System.Text;
     7.8 +using System.Threading.Tasks;
     7.9 +
    7.10 +namespace pEp.UI.ViewModels
    7.11 +{
    7.12 +    public class WizardHandshakePageViewModel : WizardPageViewModelBase
    7.13 +    {
    7.14 +        public WizardHandshakePageViewModel()
    7.15 +        {
    7.16 +            this.IsButtonCancelVisible = false;
    7.17 +        }
    7.18 +    }
    7.19 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/UI/ViewModels/WizardPageViewModelBase.cs	Wed Aug 21 08:49:32 2019 +0200
     8.3 @@ -0,0 +1,97 @@
     8.4 +using System;
     8.5 +using System.Collections.Generic;
     8.6 +using System.Collections.ObjectModel;
     8.7 +using System.Linq;
     8.8 +using System.Text;
     8.9 +using System.Threading.Tasks;
    8.10 +using System.Windows;
    8.11 +
    8.12 +namespace pEp.UI.ViewModels
    8.13 +{
    8.14 +    public abstract class WizardPageViewModelBase : ViewModelBase
    8.15 +    {
    8.16 +        private string      _ButtonAcceptHandshakeText          = Properties.Resources.Handshake_ConfirmTrustwords;
    8.17 +        private string      _ButtonDenyHandshakeText            = Properties.Resources.Handshake_WrongTrustwords;
    8.18 +        private bool        _IsButtonAcceptHandshakeVisible     = false;
    8.19 +        private bool        _IsButtonBackVisible                = true;
    8.20 +        private bool        _IsButtonCancelVisible              = true;
    8.21 +        private bool        _IsButtonDenyHandshakeVisible       = false;
    8.22 +        private bool        _IsButtonNextVisible                = true;
    8.23 +
    8.24 +        public string ButtonAcceptHandshakeText
    8.25 +        {
    8.26 +            get => this._ButtonAcceptHandshakeText;
    8.27 +            set
    8.28 +            {
    8.29 +                this._ButtonAcceptHandshakeText = value;
    8.30 +                this.OnPropertyChanged();
    8.31 +            }
    8.32 +        }
    8.33 +
    8.34 +        public string ButtonDenyHandshakeText
    8.35 +        {
    8.36 +            get => this._ButtonDenyHandshakeText;
    8.37 +            set
    8.38 +            {
    8.39 +                this._ButtonDenyHandshakeText = value;
    8.40 +                this.OnPropertyChanged();
    8.41 +            }
    8.42 +        }
    8.43 +
    8.44 +        public bool IsButtonAcceptHandshakeVisible
    8.45 +        {
    8.46 +            get => this._IsButtonAcceptHandshakeVisible;
    8.47 +            set
    8.48 +            {
    8.49 +                this._IsButtonAcceptHandshakeVisible = value;
    8.50 +                this.OnPropertyChanged();
    8.51 +            }
    8.52 +        }
    8.53 +
    8.54 +        public bool IsButtonBackVisible
    8.55 +        {
    8.56 +            get => this._IsButtonBackVisible;
    8.57 +            set
    8.58 +            {
    8.59 +                this._IsButtonBackVisible = value;
    8.60 +                this.OnPropertyChanged();
    8.61 +            }
    8.62 +        }
    8.63 +
    8.64 +        public bool IsButtonCancelVisible
    8.65 +        {
    8.66 +            get => this._IsButtonCancelVisible;
    8.67 +            set
    8.68 +            {
    8.69 +                this._IsButtonCancelVisible = value;
    8.70 +                this.OnPropertyChanged();
    8.71 +            }
    8.72 +        }
    8.73 +
    8.74 +        public bool IsButtonDenyHandshakeVisible
    8.75 +        {
    8.76 +            get => this._IsButtonDenyHandshakeVisible;
    8.77 +            set
    8.78 +            {
    8.79 +                this._IsButtonDenyHandshakeVisible = value;
    8.80 +                this.OnPropertyChanged();
    8.81 +            }
    8.82 +        }
    8.83 +
    8.84 +        public bool IsButtonNextVisible
    8.85 +        {
    8.86 +            get => this._IsButtonNextVisible;
    8.87 +            set
    8.88 +            {
    8.89 +                this._IsButtonNextVisible = value;
    8.90 +                this.OnPropertyChanged();
    8.91 +            }
    8.92 +        }
    8.93 +
    8.94 +
    8.95 +        public WizardPageViewModelBase()
    8.96 +        {
    8.97 +
    8.98 +        }
    8.99 +    }
   8.100 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/UI/ViewModels/WizardViewModelBase.cs	Wed Aug 21 08:49:32 2019 +0200
     9.3 @@ -0,0 +1,226 @@
     9.4 +using pEp.UI.Models;
     9.5 +using pEp.UI.Views;
     9.6 +using pEpCOMServerAdapterLib;
     9.7 +using System;
     9.8 +using System.Collections.ObjectModel;
     9.9 +using System.Windows;
    9.10 +
    9.11 +namespace pEp.UI.ViewModels
    9.12 +{
    9.13 +    internal abstract class WizardViewModelBase : ViewModelBase
    9.14 +    {
    9.15 +        #region Fields
    9.16 +
    9.17 +        protected           RelayCommand                                    _AcceptHandshakeCommand;
    9.18 +        private             WizardPageViewModelBase                         _CurrentPage;
    9.19 +        protected           RelayCommand                                    _DenyHandshakeCommand;
    9.20 +        protected           RelayCommand                                    _MoveBackCommand;
    9.21 +        protected           RelayCommand                                    _MoveNextCommand;
    9.22 +        protected           ReadOnlyCollection<WizardPageViewModelBase>     _Pages;
    9.23 +        protected           string                                          _WindowTitle;
    9.24 +
    9.25 +        #endregion
    9.26 +
    9.27 +        #region Properties 
    9.28 +
    9.29 +        public virtual RelayCommand AcceptHandshakeCommand
    9.30 +        {
    9.31 +            get
    9.32 +            {
    9.33 +                if (this._AcceptHandshakeCommand == null)
    9.34 +                {
    9.35 +                    this._AcceptHandshakeCommand = new RelayCommand(param => this.AcceptHandshakeAndMoveToNextPage());
    9.36 +                }
    9.37 +
    9.38 +                return this._AcceptHandshakeCommand;
    9.39 +            }
    9.40 +        }
    9.41 +
    9.42 +        bool CanMoveToNextPage
    9.43 +        {
    9.44 +            get => (this.CurrentPage != null);
    9.45 +        }
    9.46 +
    9.47 +        bool CanMoveToPreviousPage
    9.48 +        {
    9.49 +            get => (this.CurrentPage != null);
    9.50 +        }
    9.51 +
    9.52 +        public WizardPageViewModelBase CurrentPage
    9.53 +        {
    9.54 +            get => this._CurrentPage;
    9.55 +            set
    9.56 +            {
    9.57 +                if ((value != null) &&
    9.58 +                    (value != this._CurrentPage))
    9.59 +                {
    9.60 +                    this._CurrentPage = value;
    9.61 +                    this.OnPropertyChanged();
    9.62 +                }
    9.63 +            }
    9.64 +        }
    9.65 +
    9.66 +        public int CurrentPageIndex
    9.67 +        {
    9.68 +            get => this._Pages.IndexOf(this.CurrentPage);            
    9.69 +        }
    9.70 +
    9.71 +        public virtual RelayCommand DenyHandshakeCommand
    9.72 +        {
    9.73 +            get
    9.74 +            {
    9.75 +                if (this._DenyHandshakeCommand == null)
    9.76 +                {
    9.77 +                    this._DenyHandshakeCommand = new RelayCommand(param => this.DenyHandshakeAndMoveToNextPage());
    9.78 +                }
    9.79 +
    9.80 +                return this._DenyHandshakeCommand;
    9.81 +            }
    9.82 +        }
    9.83 +
    9.84 +        public Handshake Handshake { get; }
    9.85 +
    9.86 +        private bool IsLastPage
    9.87 +        {
    9.88 +            get => (this.CurrentPageIndex >= (this.Pages.Count - 1));
    9.89 +        }
    9.90 +
    9.91 +
    9.92 +        public virtual RelayCommand MoveBackCommand
    9.93 +        {
    9.94 +            get
    9.95 +            {
    9.96 +                if (this._MoveBackCommand == null)
    9.97 +                {
    9.98 +                    this._MoveBackCommand = new RelayCommand(param => this.MoveToPreviousPage(), param => this.CanMoveToPreviousPage);
    9.99 +                }
   9.100 +
   9.101 +                return this._MoveBackCommand;
   9.102 +            }
   9.103 +        }
   9.104 +
   9.105 +        public virtual RelayCommand MoveNextCommand
   9.106 +        {
   9.107 +            get
   9.108 +            {
   9.109 +                if (this._MoveNextCommand == null)
   9.110 +                {
   9.111 +                    this._MoveNextCommand = new RelayCommand(param => this.MoveToNextPage(), param => this.CanMoveToNextPage);
   9.112 +                }
   9.113 +
   9.114 +                return this._MoveNextCommand;
   9.115 +            }
   9.116 +        }
   9.117 +
   9.118 +        public ReadOnlyCollection<WizardPageViewModelBase> Pages
   9.119 +        {
   9.120 +            get
   9.121 +            {
   9.122 +                if (this._Pages == null)
   9.123 +                {
   9.124 +                    this.CreatePages();
   9.125 +                }
   9.126 +
   9.127 +                return _Pages;
   9.128 +            }
   9.129 +        }
   9.130 +
   9.131 +        public Window ParentWindow { get; private set; }
   9.132 +
   9.133 +        public string WindowTitle
   9.134 +        {
   9.135 +            get => this._WindowTitle;
   9.136 +            set
   9.137 +            {
   9.138 +                this._WindowTitle = value;
   9.139 +                this.OnPropertyChanged();
   9.140 +            }
   9.141 +        }
   9.142 +
   9.143 +        #endregion
   9.144 +
   9.145 +        #region Constructors
   9.146 +
   9.147 +        public WizardViewModelBase(Handshake handshake, Window parentWindow)
   9.148 +        {
   9.149 +            this.Handshake = handshake;
   9.150 +            this.ParentWindow = parentWindow;
   9.151 +            this.CreatePages();
   9.152 +            this.CurrentPage = this.Pages[0];
   9.153 +        }
   9.154 +
   9.155 +        #endregion
   9.156 +
   9.157 +        #region Methods
   9.158 +
   9.159 +        private void AcceptHandshakeAndMoveToNextPage()
   9.160 +        {
   9.161 +            // Trust Partner Key
   9.162 +            try
   9.163 +            {
   9.164 +                pEpIdentity partner = this.Handshake.Partner.ToCOMType();
   9.165 +                ThisAddIn.PEPEngine.TrustPersonalKey(partner);
   9.166 +            }
   9.167 +            catch (Exception ex)
   9.168 +            {
   9.169 +                Log.Error("AcceptHandshakeAndMoveToNextPage: Error occured. " + ex.ToString());
   9.170 +            }
   9.171 +
   9.172 +            this.MoveToNextPage();
   9.173 +        }
   9.174 +
   9.175 +        public void CloseWizard()
   9.176 +        {
   9.177 +            this.ParentWindow.Close();
   9.178 +        }
   9.179 +
   9.180 +        public abstract void CreatePages();
   9.181 +
   9.182 +        private void DenyHandshakeAndMoveToNextPage()
   9.183 +        {
   9.184 +            // Mistrust Partner Key
   9.185 +            try
   9.186 +            {
   9.187 +                pEpIdentity partner = this.Handshake.Partner.ToCOMType();
   9.188 +                ThisAddIn.PEPEngine.KeyMistrusted(partner);
   9.189 +            }
   9.190 +            catch (Exception ex)
   9.191 +            {
   9.192 +                Log.Error("DenyHandshakeAndMoveToNextPage: Error occured. " + ex.ToString());
   9.193 +            }
   9.194 +
   9.195 +            this.MoveToLastPage();
   9.196 +        }
   9.197 +
   9.198 +        protected void MoveToLastPage()
   9.199 +        {
   9.200 +            this.CurrentPage = this.Pages[this.Pages.Count - 1];
   9.201 +        }
   9.202 +
   9.203 +        protected void MoveToNextPage()
   9.204 +        {
   9.205 +            if (this.IsLastPage)
   9.206 +            {
   9.207 +                this.CloseWizard();
   9.208 +            }
   9.209 +            else
   9.210 +            {
   9.211 +                this.CurrentPage = this.Pages[this.CurrentPageIndex + 1];
   9.212 +            }
   9.213 +        }
   9.214 +
   9.215 +        protected void MoveToPreviousPage()
   9.216 +        {
   9.217 +            if (this.CurrentPageIndex > 0)
   9.218 +            {
   9.219 +                this.CurrentPage = this.Pages[this.CurrentPageIndex - 1];
   9.220 +            }
   9.221 +            else
   9.222 +            {
   9.223 +                Log.Error("MoveToPreviousPage: Cannot move to previous page. Index is already 0.");
   9.224 +            }
   9.225 +        }
   9.226 +
   9.227 +        #endregion
   9.228 +    }
   9.229 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/UI/Views/DialogWindow.xaml	Wed Aug 21 08:49:32 2019 +0200
    10.3 @@ -0,0 +1,32 @@
    10.4 +<Window x:Class="pEp.UI.Views.DialogWindow"
    10.5 +        x:Name="DlgWindow"
    10.6 +        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    10.7 +        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    10.8 +        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    10.9 +        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   10.10 +        xmlns:vm="clr-namespace:pEp.UI.ViewModels"
   10.11 +        xmlns:v="clr-namespace:pEp.UI.Views"
   10.12 +        mc:Ignorable="d"
   10.13 +        MinHeight="5"
   10.14 +        Height="Auto"
   10.15 +        Width="Auto"
   10.16 +        ResizeMode="NoResize"
   10.17 +        SizeToContent="WidthAndHeight"
   10.18 +        x:ClassModifier="internal"
   10.19 +        Topmost="True"
   10.20 +        Background="{x:Static SystemColors.MenuBarBrush}"
   10.21 +        Title="{Binding WindowTitle}"
   10.22 +        Icon="pack://application:,,,/pEp;component/Resources/ImageLogoIcon.png"
   10.23 +        WindowStartupLocation="CenterScreen"
   10.24 +        Closing="DialogWindow_Closing">
   10.25 +    <Window.Resources>
   10.26 +        <DataTemplate DataType="{x:Type vm:SyncWizardViewModel}">
   10.27 +            <v:WizardView />
   10.28 +        </DataTemplate>
   10.29 +    </Window.Resources>
   10.30 +
   10.31 +    <ContentControl x:Name="DialogWindowContent"                    
   10.32 +                    Content="{Binding Content}">
   10.33 +    </ContentControl>
   10.34 +    
   10.35 +</Window>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/UI/Views/DialogWindow.xaml.cs	Wed Aug 21 08:49:32 2019 +0200
    11.3 @@ -0,0 +1,35 @@
    11.4 +using pEp.UI.Models;
    11.5 +using pEp.UI.ViewModels;
    11.6 +using System.ComponentModel;
    11.7 +using System.Windows;
    11.8 +
    11.9 +namespace pEp.UI.Views
   11.10 +{
   11.11 +    /// <summary>
   11.12 +    /// Interaction logic for DialogWindow.xaml
   11.13 +    /// </summary>
   11.14 +    internal partial class DialogWindow : Window, Interfaces.ICloseable
   11.15 +    {
   11.16 +        public DialogWindow()
   11.17 +        {
   11.18 +            InitializeComponent();
   11.19 +        }
   11.20 +
   11.21 +        public DialogWindow(Dialog.Type type, Handshake handshake) : this()
   11.22 +        {
   11.23 +            this.DataContext = new DialogWindowViewModel(type, handshake, this);
   11.24 +        }
   11.25 +
   11.26 +        /// <summary>
   11.27 +        /// Event handler for when the Handshake dialog is being closed.
   11.28 +        /// </summary>
   11.29 +        private void DialogWindow_Closing(object sender, CancelEventArgs e)
   11.30 +        {
   11.31 +            //if (this.isShownDialog &&
   11.32 +            //    (this.DataContext is HandshakeViewModel handshakeViewModel))
   11.33 +            //{
   11.34 +            //    this.DialogResult = handshakeViewModel.DialogResult;
   11.35 +            //}
   11.36 +        }
   11.37 +    }
   11.38 +}
    12.1 --- a/UI/Views/HandshakeDialog.xaml	Mon Aug 19 09:31:13 2019 +0200
    12.2 +++ b/UI/Views/HandshakeDialog.xaml	Wed Aug 21 08:49:32 2019 +0200
    12.3 @@ -4,7 +4,6 @@
    12.4          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    12.5          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    12.6          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    12.7 -        xmlns:core="clr-namespace:System;assembly=mscorlib"
    12.8          xmlns:p="clr-namespace:pEp.Properties"
    12.9          xmlns:local="clr-namespace:pEp.UI"
   12.10          x:ClassModifier="internal"
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/UI/Views/WizardPageView.xaml	Wed Aug 21 08:49:32 2019 +0200
    13.3 @@ -0,0 +1,51 @@
    13.4 +<UserControl x:Class="pEp.UI.Views.WizardPageView"
    13.5 +             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    13.6 +             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    13.7 +             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    13.8 +             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    13.9 +             xmlns:local="clr-namespace:pEp.UI"
   13.10 +             xmlns:vm="clr-namespace:pEp.UI.ViewModels"
   13.11 +             xmlns:v="clr-namespace:pEp.UI.Views"
   13.12 +             xmlns:p="clr-namespace:pEp.Properties"
   13.13 +             mc:Ignorable="d">
   13.14 +    <UserControl.Resources>
   13.15 +        <ResourceDictionary>
   13.16 +            <!-- Converters -->
   13.17 +            <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
   13.18 +            <local:ValueConverterGroup x:Key="InvertBoolToVisibility">
   13.19 +                <local:InvertBoolConverter />
   13.20 +                <BooleanToVisibilityConverter />
   13.21 +            </local:ValueConverterGroup>
   13.22 +            <local:MultiBooleanToVisibilityConverter x:Key="MultiBooleanToVisibility" />
   13.23 +            <local:ValueConverterGroup x:Key="IsStringNotNullOrEmptyToVisibility">
   13.24 +                <local:IsStringEmptyConverter />
   13.25 +                <local:InvertBoolConverter />
   13.26 +                <BooleanToVisibilityConverter />
   13.27 +            </local:ValueConverterGroup>
   13.28 +            <local:IsWizardTypeConverter x:Key="IsWizardType" />
   13.29 +
   13.30 +            <!--Dictionary-->
   13.31 +            <ResourceDictionary.MergedDictionaries>
   13.32 +                <ResourceDictionary Source="pack://application:,,,/pEp;component/Resources/Dictionary.xaml" />
   13.33 +            </ResourceDictionary.MergedDictionaries>
   13.34 +        </ResourceDictionary>
   13.35 +    </UserControl.Resources>
   13.36 +    <StackPanel Margin="10"
   13.37 +                Width="470">
   13.38 +
   13.39 +        <!--Information section-->
   13.40 +        <TextBlock Text="{Binding ExplanationText}"
   13.41 +                   TextWrapping="Wrap"
   13.42 +                   Margin="5,5,5,15" />
   13.43 +
   13.44 +        <Image Height="80"
   13.45 +                       Stretch="Uniform"
   13.46 +                       VerticalAlignment="Stretch"
   13.47 +                       HorizontalAlignment="Center"
   13.48 +                       Margin="0,0,15,0"
   13.49 +                       Source="pack://application:,,,/pEp;component/Resources/ImageIconDeviceGroup.png">
   13.50 +        </Image>
   13.51 +
   13.52 +
   13.53 +    </StackPanel>
   13.54 +</UserControl>
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/UI/Views/WizardPageView.xaml.cs	Wed Aug 21 08:49:32 2019 +0200
    14.3 @@ -0,0 +1,21 @@
    14.4 +using pEp.UI.ViewModels;
    14.5 +using System.Windows.Controls;
    14.6 +
    14.7 +namespace pEp.UI.Views
    14.8 +{
    14.9 +    /// <summary>
   14.10 +    /// Interaction logic for WizardPageView.xaml
   14.11 +    /// </summary>
   14.12 +    public partial class WizardPageView : UserControl
   14.13 +    {
   14.14 +        public WizardPageView()
   14.15 +        {
   14.16 +            InitializeComponent();
   14.17 +        }
   14.18 +
   14.19 +        public WizardPageView(WizardPageViewModelBase viewModel) : this()
   14.20 +        {
   14.21 +            this.DataContext = viewModel;
   14.22 +        }
   14.23 +    }
   14.24 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/UI/Views/WizardView.xaml	Wed Aug 21 08:49:32 2019 +0200
    15.3 @@ -0,0 +1,60 @@
    15.4 +<UserControl x:Class="pEp.UI.Views.WizardView"
    15.5 +        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    15.6 +        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    15.7 +        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    15.8 +        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    15.9 +        xmlns:v="clr-namespace:pEp.UI.Views"
   15.10 +        xmlns:vm="clr-namespace:pEp.UI.ViewModels"
   15.11 +        xmlns:p="clr-namespace:pEp.Properties"
   15.12 +        x:ClassModifier="internal"
   15.13 +        mc:Ignorable="d"
   15.14 +        MinHeight="5"
   15.15 +        Height="Auto"
   15.16 +        Width="Auto">
   15.17 +    <UserControl.Resources>
   15.18 +        <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
   15.19 +        <DataTemplate DataType="{x:Type vm:WizardGenericPageViewModel}">
   15.20 +            <v:WizardPageView />
   15.21 +        </DataTemplate>
   15.22 +        <DataTemplate DataType="{x:Type vm:WizardHandshakePageViewModel}">
   15.23 +            <v:WizardPageView />
   15.24 +        </DataTemplate>
   15.25 +    </UserControl.Resources>
   15.26 +
   15.27 +    <StackPanel>
   15.28 +        
   15.29 +    <!--Content section-->
   15.30 +    <UserControl x:Name="WizardContent"
   15.31 +                 Content="{Binding CurrentPage}"/>
   15.32 +
   15.33 +        <!--Buttons section-->
   15.34 +        <StackPanel Margin="0,10"
   15.35 +                    Orientation="Horizontal"
   15.36 +                    HorizontalAlignment="Right">
   15.37 +            <Button x:Name="BackButton"
   15.38 +                    MinHeight="28"
   15.39 +                    MinWidth="150"
   15.40 +                    Margin="0,5,5,5"
   15.41 +                    Content="{x:Static p:Resources.KeySyncWizard_BackButtonText}"
   15.42 +                    Command="{Binding MoveBackCommand}"
   15.43 +                    Visibility="{Binding Path=CurrentPage.IsButtonBackVisible, Converter={StaticResource BoolToVisibility}}" />
   15.44 +            <Button x:Name="AcceptButton"
   15.45 +                    MinHeight="28"
   15.46 +                    MinWidth="150"
   15.47 +                    Margin="5"
   15.48 +                    Command="{Binding MoveNextCommand}"
   15.49 +                    Content="{x:Static p:Resources.KeySyncWizard_Next}"
   15.50 +                    Visibility="{Binding Path=CurrentPage.IsButtonNextVisible, Converter={StaticResource BoolToVisibility}}" />
   15.51 +            <Button x:Name="CancelButton"
   15.52 +                    Margin="5,5,0,5"
   15.53 +                    MinHeight="28"
   15.54 +                    MinWidth="150"
   15.55 +                    Command="{Binding MoveNextCommand}"
   15.56 +                    Content="{x:Static p:Resources.Handshake_CancelText}"
   15.57 +                    Visibility="{Binding Path=CurrentPage.IsButtonCancelVisible, Converter={StaticResource BoolToVisibility}}" />
   15.58 +        </StackPanel>
   15.59 +
   15.60 +    </StackPanel>
   15.61 +</UserControl>
   15.62 +
   15.63 +
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/UI/Views/WizardView.xaml.cs	Wed Aug 21 08:49:32 2019 +0200
    16.3 @@ -0,0 +1,42 @@
    16.4 +using pEp.UI.Models;
    16.5 +using pEp.UI.ViewModels;
    16.6 +using System;
    16.7 +using System.Windows;
    16.8 +using System.Windows.Controls;
    16.9 +
   16.10 +namespace pEp.UI.Views
   16.11 +{
   16.12 +    /// <summary>
   16.13 +    /// Interaction logic for WizardView.xaml
   16.14 +    /// </summary>
   16.15 +    internal partial class WizardView : UserControl
   16.16 +    {
   16.17 +        public WizardView()
   16.18 +        {
   16.19 +            InitializeComponent();
   16.20 +        }
   16.21 +
   16.22 +        public WizardView(Handshake handshake, Window parentWindow) : this()
   16.23 +        {
   16.24 +            switch (handshake.Mode)
   16.25 +            {
   16.26 +                case Handshake.HandshakeMode.SyncTypeA:
   16.27 +                case Handshake.HandshakeMode.SyncTypeB:
   16.28 +                case Handshake.HandshakeMode.SyncTypeC:
   16.29 +                    {
   16.30 +                        this.DataContext = new SyncWizardViewModel(handshake, parentWindow);
   16.31 +                    }
   16.32 +                    break;
   16.33 +                case Handshake.HandshakeMode.ForceProtectionSendKey:
   16.34 +                case Handshake.HandshakeMode.ForceProtectionImportKey:
   16.35 +                    {
   16.36 +                        //this.DataContext = new ForceProtectionWizardViewModel(handshake);
   16.37 +                    }
   16.38 +                    break;
   16.39 +                case Handshake.HandshakeMode.Standard:
   16.40 +                default:
   16.41 +                    throw new Exception();
   16.42 +            }
   16.43 +        }
   16.44 +    }
   16.45 +}
    17.1 --- a/pEpForOutlook.csproj	Mon Aug 19 09:31:13 2019 +0200
    17.2 +++ b/pEpForOutlook.csproj	Wed Aug 21 08:49:32 2019 +0200
    17.3 @@ -410,6 +410,8 @@
    17.4        <DependentUpon>Resources.zh.resx</DependentUpon>
    17.5      </Compile>
    17.6      <Compile Include="SyncQueue.cs" />
    17.7 +    <Compile Include="UI\Dialog.cs" />
    17.8 +    <Compile Include="UI\DialogCloser.cs" />
    17.9      <Compile Include="UI\FormControlCrashReport.xaml.cs">
   17.10        <DependentUpon>FormControlCrashReport.xaml</DependentUpon>
   17.11      </Compile>
   17.12 @@ -439,7 +441,16 @@
   17.13        <DependentUpon>FormReaderSplash.cs</DependentUpon>
   17.14      </Compile>
   17.15      <Compile Include="UI\Models\SyncIdentity.cs" />
   17.16 +    <Compile Include="UI\ViewModels\DialogWindowViewModel.cs" />
   17.17 +    <Compile Include="UI\ViewModels\WizardGenericPageViewModel.cs" />
   17.18      <Compile Include="UI\ViewModels\HandshakeViewModel.cs" />
   17.19 +    <Compile Include="UI\ViewModels\SyncWizardViewModel.cs" />
   17.20 +    <Compile Include="UI\ViewModels\WizardHandshakePageViewModel.cs" />
   17.21 +    <Compile Include="UI\ViewModels\WizardPageViewModelBase.cs" />
   17.22 +    <Compile Include="UI\ViewModels\WizardViewModelBase.cs" />
   17.23 +    <Compile Include="UI\Views\DialogWindow.xaml.cs">
   17.24 +      <DependentUpon>DialogWindow.xaml</DependentUpon>
   17.25 +    </Compile>
   17.26      <Compile Include="UI\Views\HandshakeDialog.xaml.cs">
   17.27        <DependentUpon>HandshakeDialog.xaml</DependentUpon>
   17.28      </Compile>
   17.29 @@ -480,6 +491,12 @@
   17.30      </Compile>
   17.31      <Compile Include="UI\ValueConverters.cs" />
   17.32      <Compile Include="UI\ViewModels\ViewModelBase.cs" />
   17.33 +    <Compile Include="UI\Views\WizardPageView.xaml.cs">
   17.34 +      <DependentUpon>WizardPageView.xaml</DependentUpon>
   17.35 +    </Compile>
   17.36 +    <Compile Include="UI\Views\WizardView.xaml.cs">
   17.37 +      <DependentUpon>WizardView.xaml</DependentUpon>
   17.38 +    </Compile>
   17.39      <Compile Include="Wrappers\WatchedExplorer.cs" />
   17.40      <Compile Include="Wrappers\WatchedInspector.cs" />
   17.41      <Compile Include="Wrappers\WatchedWindow.cs" />
   17.42 @@ -632,6 +649,18 @@
   17.43        <SubType>Designer</SubType>
   17.44        <Generator>MSBuild:Compile</Generator>
   17.45      </Page>
   17.46 +    <Page Include="UI\Views\DialogWindow.xaml">
   17.47 +      <SubType>Designer</SubType>
   17.48 +      <Generator>MSBuild:Compile</Generator>
   17.49 +    </Page>
   17.50 +    <Page Include="UI\Views\WizardPageView.xaml">
   17.51 +      <SubType>Designer</SubType>
   17.52 +      <Generator>MSBuild:Compile</Generator>
   17.53 +    </Page>
   17.54 +    <Page Include="UI\Views\WizardView.xaml">
   17.55 +      <SubType>Designer</SubType>
   17.56 +      <Generator>MSBuild:Compile</Generator>
   17.57 +    </Page>
   17.58      <Resource Include="Resources\Dictionary.xaml">
   17.59        <Generator>MSBuild:Compile</Generator>
   17.60        <SubType>Designer</SubType>