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