UI/Views/DialogWindow.xaml.cs
author Thomas
Tue, 08 Oct 2019 10:13:58 +0200
branchsync
changeset 2798 484bde7d2e9b
parent 2797 9dadc302b32b
child 2823 74c8e317d52b
permissions -rw-r--r--
Use Show() instead of ShowDialog() to not block UI thread
Thomas@2709
     1
´╗┐using pEp.UI.Models;
Thomas@2709
     2
using pEp.UI.ViewModels;
Thomas@2712
     3
using pEpCOMServerAdapterLib;
Thomas@2711
     4
using System;
Thomas@2780
     5
using System.Collections.Generic;
Thomas@2735
     6
using System.ComponentModel;
Thomas@2709
     7
using System.Windows;
Thomas@2797
     8
using System.Windows.Threading;
Thomas@2709
     9
Thomas@2709
    10
namespace pEp.UI.Views
Thomas@2709
    11
{
Thomas@2709
    12
    /// <summary>
Thomas@2709
    13
    /// Interaction logic for DialogWindow.xaml
Thomas@2709
    14
    /// </summary>
Thomas@2711
    15
    internal partial class DialogWindow : Window
Thomas@2709
    16
    {
Thomas@2797
    17
        /* In order to always open this window on the UI thread,
Thomas@2797
    18
         * we store a reference to a window's dispatcher. Invoking
Thomas@2797
    19
         * this dispatcher marshals the call to the UI thread.
Thomas@2797
    20
         */ 
Thomas@2797
    21
        public static Dispatcher UIThreadDispatcher = null;
Thomas@2797
    22
Thomas@2711
    23
        /// <summary>
Thomas@2711
    24
        /// Primary constructor.
Thomas@2711
    25
        /// </summary>
Thomas@2709
    26
        public DialogWindow()
Thomas@2709
    27
        {
Thomas@2709
    28
            InitializeComponent();
Thomas@2709
    29
        }
Thomas@2709
    30
Thomas@2728
    31
        /// <summary>
Thomas@2728
    32
        /// Secondary constructor.
Thomas@2728
    33
        /// </summary>
Thomas@2728
    34
        /// <param name="dialog">The dialog to use to build this dialog window.</param>
Thomas@2783
    35
        public DialogWindow(Dialog dialog) : this()
Thomas@2709
    36
        {
Thomas@2711
    37
            // Assign the necessary ViewModel according to the dialog type.
Thomas@2780
    38
            switch (dialog.DialogType)
Thomas@2711
    39
            {
Thomas@2780
    40
                case Dialog.Type.Handshake:
Thomas@2731
    41
                    {
Thomas@2731
    42
                        this.Title = Properties.Resources.Handshake_StandardFormText;
Thomas@2783
    43
                        this.Content = new HandshakeDialogViewModel(dialog, this.Close);
Thomas@2731
    44
                    }
Thomas@2711
    45
                    break;
Thomas@2780
    46
                case Dialog.Type.KeySync:
Thomas@2731
    47
                    {
Thomas@2731
    48
                        this.Title = Properties.Resources.Handshake_SyncFormText;
Thomas@2731
    49
                        this.Content = new SyncWizardViewModel(dialog, this.Close);
Thomas@2731
    50
                    }
Thomas@2711
    51
                    break;
Thomas@2780
    52
                case Dialog.Type.KeyImportPGP:
Thomas@2780
    53
                case Dialog.Type.ForceProtection:
Thomas@2711
    54
                default:
Thomas@2731
    55
                    {
Thomas@2780
    56
                        Log.Error("DialogWindow: Dialog type {0} not implemented. ", Enum.GetName(typeof(Dialog.Type), dialog.DialogType));
Thomas@2731
    57
                    }
Thomas@2712
    58
                    break;
Thomas@2711
    59
            }
Thomas@2709
    60
        }
Thomas@2709
    61
Thomas@2735
    62
        #region Event handling
Thomas@2735
    63
Thomas@2735
    64
        /// <summary>
Thomas@2735
    65
        /// Event handler for when the window is being closed.
Thomas@2735
    66
        /// </summary>
Thomas@2735
    67
        private void DialogWindow_Closing(object sender, CancelEventArgs e)
Thomas@2735
    68
        {
Thomas@2735
    69
            /* If the window is a Key Sync wizard and is being closed using the Cancel or 'x' buttons,
Thomas@2791
    70
             * we have to notify the engine that the sync process is to be canceled.
Thomas@2735
    71
             */ 
Thomas@2735
    72
            if ((this.Content is SyncWizardViewModel viewModel) &&
Thomas@2735
    73
                (viewModel.DialogResult == null))
Thomas@2735
    74
            {
Thomas@2735
    75
                try
Thomas@2735
    76
                {
Thomas@2735
    77
                    ThisAddIn.PEPEngine.DeliverHandshakeResult(SyncHandshakeResult.SyncHandshakeCancel, null);
Thomas@2735
    78
                }
Thomas@2735
    79
                catch (Exception ex)
Thomas@2735
    80
                {
Thomas@2735
    81
                    Log.Error("DialogWindow_Closing: Error delivering handshake result. " + ex.ToString());
Thomas@2735
    82
                }
Thomas@2735
    83
            }
Thomas@2735
    84
        }
Thomas@2735
    85
Thomas@2735
    86
        #endregion
Thomas@2735
    87
Thomas@2728
    88
        #region Methods
Thomas@2728
    89
Thomas@2709
    90
        /// <summary>
Thomas@2728
    91
        /// Closes the dialog on the dialog window's thread.
Thomas@2709
    92
        /// </summary>
Thomas@2792
    93
        /// <param name="dialogResult">The dialog result fo this dialog.</param>
Thomas@2792
    94
        private void InvokeClosing(bool? dialogResult)
Thomas@2709
    95
        {
Thomas@2728
    96
            this.Dispatcher.Invoke(() =>
Thomas@2711
    97
            {
Thomas@2792
    98
                /* Set dialog result to the view model.
Thomas@2792
    99
                 * Note: Setting it directly in the DialogWindow caused issues,
Thomas@2792
   100
                 * so this is the workaround for that.
Thomas@2792
   101
                 */ 
Thomas@2792
   102
                if (this.Content is SyncWizardViewModel viewModel)
Thomas@2792
   103
                {
Thomas@2792
   104
                    viewModel.DialogResult = dialogResult;
Thomas@2792
   105
                }
Thomas@2792
   106
Thomas@2728
   107
                this.Close();
Thomas@2728
   108
            });
Thomas@2709
   109
        }
Thomas@2711
   110
Thomas@2792
   111
        /// <summary>
Thomas@2792
   112
        /// Action to perform when a sync handshake signal is received.
Thomas@2792
   113
        /// </summary>
Thomas@2792
   114
        /// <param name="signal">The received sync handshake signal.</param>
Thomas@2792
   115
        private void SyncHandshakeSignalReceivedAction(SyncHandshakeSignal signal)
Thomas@2792
   116
        {
Thomas@2792
   117
            /* Close handshake dialog if the signal type is not "Undefined" 
Thomas@2792
   118
             * or "Forming Group", in which case the status quo should be preserved.
Thomas@2792
   119
             */
Thomas@2792
   120
            if ((signal != SyncHandshakeSignal.SyncNotifyUndefined) &&
Thomas@2792
   121
                (signal != SyncHandshakeSignal.SyncNotifyFormingGroup))
Thomas@2792
   122
            {
Thomas@2792
   123
                this.InvokeClosing(true);
Thomas@2792
   124
            }
Thomas@2792
   125
        }
Thomas@2792
   126
Thomas@2728
   127
        #endregion
Thomas@2728
   128
Thomas@2715
   129
        #region Static methods
Thomas@2715
   130
Thomas@2791
   131
        /// <summary>
Thomas@2791
   132
        /// Creates a Dialog window and shows it.
Thomas@2791
   133
        /// Note: this starts a new STA task and shows the dialog on the respective thread.
Thomas@2791
   134
        /// </summary>
Thomas@2791
   135
        /// <param name="type">The dialog type.</param>
Thomas@2791
   136
        /// <param name="myself">The own identity.</param>
Thomas@2791
   137
        /// <param name="partnerIdentities">The partner identities.</param>
Thomas@2780
   138
        public static void CreateAndShow(Dialog.Type type, PEPIdentity myself, List<PEPIdentity> partnerIdentities)
Thomas@2715
   139
        {
Thomas@2797
   140
            DialogWindow.UIThreadDispatcher?.Invoke(() =>
Thomas@2715
   141
            {
Thomas@2797
   142
                if (type == Dialog.Type.KeySync)
Thomas@2797
   143
                {
Thomas@2797
   144
                    // Create the dialog
Thomas@2797
   145
                    DialogWindow dialogWindow = new DialogWindow(new Dialog(type, myself, partnerIdentities));
Thomas@2728
   146
Thomas@2792
   147
                    // Connect the action to handle sync handshake signals
Thomas@2792
   148
                    AdapterCallbacks.SyncHandshakeSignalAction = dialogWindow.SyncHandshakeSignalReceivedAction;
Thomas@2728
   149
Thomas@2728
   150
                    // Show the dialog
Thomas@2798
   151
                    dialogWindow.Show();
Thomas@2715
   152
                }
Thomas@2715
   153
                else
Thomas@2715
   154
                {
Thomas@2797
   155
                    Log.Error("CreateAndShow: Dialog type {0} not implemented.", Enum.GetName(typeof(Dialog.Type), type));
Thomas@2715
   156
                }
Thomas@2715
   157
            });
Thomas@2715
   158
        }
Thomas@2715
   159
Thomas@2728
   160
        /// <summary>
Thomas@2728
   161
        /// Creates a Dialog window and shows it.
Thomas@2728
   162
        /// Note: this starts a new STA task and shows the dialog on the respective thread.
Thomas@2728
   163
        /// </summary>
Thomas@2728
   164
        /// <param name="type">The dialog type.</param>
Thomas@2728
   165
        /// <param name="myself">The own identity.</param>
Thomas@2728
   166
        /// <param name="partner">The partner identity.</param>
Thomas@2780
   167
        public static void CreateAndShow(Dialog.Type type, PEPIdentity myself, PEPIdentity partner)
Thomas@2780
   168
        {
Thomas@2780
   169
            DialogWindow.CreateAndShow(type, myself, new List<PEPIdentity> { partner });
Thomas@2780
   170
        }
Thomas@2780
   171
Thomas@2780
   172
        /// <summary>
Thomas@2780
   173
        /// Creates a Dialog window and shows it.
Thomas@2780
   174
        /// Note: this starts a new STA task and shows the dialog on the respective thread.
Thomas@2780
   175
        /// </summary>
Thomas@2780
   176
        /// <param name="type">The dialog type.</param>
Thomas@2780
   177
        /// <param name="myself">The own identity.</param>
Thomas@2780
   178
        /// <param name="partner">The partner identity.</param>
Thomas@2780
   179
        public static void CreateAndShow(Dialog.Type type, pEpIdentity myself, pEpIdentity partner)
Thomas@2728
   180
        {
Thomas@2728
   181
            DialogWindow.CreateAndShow(type, new PEPIdentity(myself), new PEPIdentity(partner));
Thomas@2728
   182
        }
Thomas@2728
   183
Thomas@2735
   184
        #endregion        
Thomas@2709
   185
    }
Thomas@2709
   186
}