Commits (6)
using MimeKit;
using pEp.UI;
using pEp.UI.Views;
using pEp.UI.Models;
using pEpCOMServerAdapterLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Outlook = Microsoft.Office.Interop.Outlook;
......@@ -1253,22 +1252,16 @@ namespace pEp
(message.IsSecure == false) &&
(CryptableMailItem.mixedConfigWarning == null))
{
// Dialogs have to be opened from the UI thread
CryptableMailItem.mixedConfigWarning = new CustomMessageBox(Properties.Resources.Message_TitleWarning,
string.Format(Properties.Resources.MixedConfigWarning_MessageText, this.internalMailItem.GetMyselfIdentity().Address),
Properties.Resources.Options_OKText,
CustomMessageBox.CustomMessageBoxOptions.DoNotShowAgainCheckBox);
DialogHost.UIThreadDispatcher?.Invoke(() =>
{
// Create the message box and show it
CryptableMailItem.mixedConfigWarning = new CustomMessageBox
{
ButtonCancelText = null,
ButtonConfirmText = Properties.Resources.Options_OKText,
MessageBoxText = string.Format(Properties.Resources.MixedConfigWarning_MessageText, this.internalMailItem.GetMyselfIdentity().Address),
Title = Properties.Resources.Message_TitleWarning,
IsDoNotShowAgainVisible = true
};
CryptableMailItem.mixedConfigWarning.ShowDialog();
// Check if user selected the 'Do not show again' checkbox
Globals.ThisAddIn.Settings.ShowMixedConfigWarning = !CryptableMailItem.mixedConfigWarning.IsDoNotShowAgainChecked;
new DialogHost(CryptableMailItem.mixedConfigWarning).ShowAsOutlookChild(true);
Globals.ThisAddIn.Settings.ShowMixedConfigWarning = !CryptableMailItem.mixedConfigWarning.DoNotShowAgain;
if (Globals.ThisAddIn.Settings.ShowMixedConfigWarning)
{
// Even if 'Do not show again' hasn't been selected, wait 5 minutes for next dialog
......@@ -1301,7 +1294,7 @@ namespace pEp
if (processedMessage.Attachments.Count == hiddenAttachmentsCount)
{
// Note: The documented MAPI property PidLidSmartNoAttach (0x8514000B) doesn't work for some reason
result.PropertiesToSet.Add(MapiProperty.PidTagSmartNoAttach2, true);
result.PropertiesToSet.TryAdd(MapiProperty.PidTagSmartNoAttach2, true);
}
}
......
......@@ -132,6 +132,27 @@ namespace pEp
return added;
}
/// <summary>
/// Tries to add a given MAPI property value and logs any errors.
/// </summary>
/// <param name="mapiProperty">The MAPI property to add.</param>
/// <param name="value">The MAPI property value.</param>
/// <returns>True if the MAPI property was successfully added. Otherwise false.</returns>
internal bool TryAdd(MapiProperty.MapiProp mapiProperty, object value)
{
try
{
this.Add(mapiProperty, value);
}
catch (Exception ex)
{
Log.Error("TryAdd: Error adding property {0}. {1}", mapiProperty.Name, ex);
return false;
}
return true;
}
/// <summary>
/// Gets a PEPMessage property value from the dictionary.
/// </summary>
......
......@@ -75,6 +75,16 @@ namespace pEp.UI
this.Text = Properties.Resources.Options_FormText;
}
break;
case Dialog.Type.CustomMessageBox:
{
this.Text = (dialog as CustomMessageBox)?.Title;
}
break;
case Dialog.Type.InputMessageBox:
{
// this.Text = (dialog as InputMessageBox)?.Title;
}
break;
default:
{
Log.Error("DialogHost: Dialog type {0} not implemented. ", Enum.GetName(typeof(Dialog.Type), dialog.DialogType));
......
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System;
using System.Windows.Forms;
namespace pEp.UI
namespace pEp.UI.Models
{
/// <summary>
/// Interaction logic for CustomMessageBox.xaml
/// </summary>
internal partial class CustomMessageBox : Window, INotifyPropertyChanged
internal class CustomMessageBox : Dialog
{
private bool _IsDoNotShowAgainChecked = false;
[Flags]
public enum CustomMessageBoxOptions
{
None = 0,
NoCancelButton = 1,
RedAndGreenButtons = 2,
DoNotShowAgainCheckBox = 4
}
public event PropertyChangedEventHandler PropertyChanged;
public CustomMessageBox() : base(Dialog.Type.CustomMessageBox)
{
}
/// <summary>
/// Primary constructor
/// Constructor for informative message box with only a Confirm button.
/// </summary>
public CustomMessageBox()
/// <param name="title">The title of this message box.</param>
/// <param name="messageBoxText">The message box text.</param>
/// <param name="confirmButtonText">The Confirm button text.</param>
/// <param name="messageBoxOptions">Optional message box options.</param>
public CustomMessageBox(string title,
string messageBoxText,
string confirmButtonText,
CustomMessageBoxOptions messageBoxOptions = CustomMessageBoxOptions.NoCancelButton) :
this(title, messageBoxText, null, confirmButtonText, (messageBoxOptions |= CustomMessageBoxOptions.NoCancelButton))
{
InitializeComponent();
this.DataContext = this;
}
/// <summary>
/// Gets or sets the text of the Cancel button.
/// Complete constructor.
/// </summary>
public string ButtonCancelText { get; set; }
/// <param name="title">The title of this message box.</param>
/// <param name="messageBoxText">The message box text.</param>
/// <param name="cancelButtonText">The Cancel button text.</param>
/// <param name="confirmButtonText">The Confirm button text.</param>
/// <param name="messageBoxOptions">Optional message box options.</param>
public CustomMessageBox(string title,
string messageBoxText,
string cancelButtonText,
string confirmButtonText,
CustomMessageBoxOptions messageBoxOptions = CustomMessageBoxOptions.None) : this()
{
this.Title = title;
this.MessageBoxText = messageBoxText;
this.CancelButtonText = cancelButtonText;
this.ConfirmButtonText = confirmButtonText;
this.MessageBoxOptions = messageBoxOptions;
}
/// <summary>
/// Gets or sets the text of the Confirm button.
/// Gets or sets the text of the Cancel button.
/// </summary>
public string ButtonConfirmText { get; set; }
public string CancelButtonText { get; }
/// <summary>
/// The command to execute when the Cancel button is clicked.
/// Gets or sets the text of the Confirm button.
/// </summary>
public RelayCommand CommandButtonCancel
{
get
{
return new RelayCommand(p =>
{
this.DialogResult = false;
this.Close();
});
}
}
public string ConfirmButtonText { get; }
/// <summary>
/// The command to execute when the Confirm button is clicked.
/// Whether to show this custom message box again.
/// </summary>
public RelayCommand CommandButtonConfirm
{
get
{
return new RelayCommand(p =>
{
this.DialogResult = true;
this.Close();
});
}
}
public bool DoNotShowAgain { get; set; }
/// <summary>
/// Gets whether
/// Gets the message box text.
/// </summary>
public bool IsDoNotShowAgainChecked
{
get => this._IsDoNotShowAgainChecked;
set
{
this._IsDoNotShowAgainChecked = value;
this.OnPropertyChanged();
}
}
public string MessageBoxText { get; }
/// <summary>
/// Gets or sets whether the 'Do not show again' checkbox
/// is visible.
/// Gets the options of this message box.
/// </summary>
public bool IsDoNotShowAgainVisible { get; set; } = false;
public CustomMessageBoxOptions MessageBoxOptions { get; }
/// <summary>
/// Gets or sets the text in the input field.
/// Gehts the title of the MessageBox
/// </summary>
public string MessageBoxText { get; set; }
public string Title { get; }
/// <summary>
/// Event handler for when the given property changed.
/// </summary>
/// <param name="propertyName">The name of the property that changed its value.</param>
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#region Static methods
/// <summary>
/// Shows the message box as dialog.
......@@ -102,19 +95,15 @@ namespace pEp.UI
/// <param name="titleText">The text to display in the title of this message box.</param>
/// <param name="cancelButtonText">The text to display in the Cancel button.</param>
/// <param name="confirmButtonText">The text to display in the Confirm button.</param>
/// <param name="messageBoxOptions">Optional message box options.</param>
/// <returns>True if the dialog has been accepted (confirmed), otherwise false.</returns>
public static bool ShowDialog(string messageBoxText,
string titleText,
string cancelButtonText,
string confirmButtonText)
public static bool ShowDialog(string messageBoxText,
string titleText,
string cancelButtonText,
string confirmButtonText,
CustomMessageBox.CustomMessageBoxOptions messageBoxOptions = CustomMessageBox.CustomMessageBoxOptions.None)
{
return new CustomMessageBox
{
ButtonCancelText = cancelButtonText,
ButtonConfirmText = confirmButtonText,
MessageBoxText = messageBoxText,
Title = titleText
}.ShowDialog() ?? false;
return CustomMessageBox.ShowDialog(messageBoxText, titleText, cancelButtonText, confirmButtonText, out _, messageBoxOptions);
}
/// <summary>
......@@ -125,24 +114,22 @@ namespace pEp.UI
/// <param name="cancelButtonText">The text to display in the Cancel button.</param>
/// <param name="confirmButtonText">The text to display in the Confirm button.</param>
/// <param name="doNotShowAgain">Whether to show the message box again.</param>
/// <param name="messageBoxOptions">Optional message box options.</param>
/// <returns>True if the dialog has been accepted (confirmed), otherwise false.</returns>
public static bool ShowDialog(string messageBoxText,
public static bool ShowDialog(string messageBoxText,
string titleText,
string cancelButtonText,
string confirmButtonText,
out bool doNotShowAgain)
out bool doNotShowAgain,
CustomMessageBox.CustomMessageBoxOptions messageBoxOptions = CustomMessageBox.CustomMessageBoxOptions.DoNotShowAgainCheckBox)
{
CustomMessageBox messageBox = new CustomMessageBox
{
ButtonCancelText = cancelButtonText,
ButtonConfirmText = confirmButtonText,
MessageBoxText = messageBoxText,
Title = titleText,
IsDoNotShowAgainChecked = true
};
bool result = messageBox.ShowDialog() ?? false;
doNotShowAgain = messageBox.IsDoNotShowAgainChecked;
return result;
messageBoxOptions |= CustomMessageBox.CustomMessageBoxOptions.DoNotShowAgainCheckBox;
CustomMessageBox customMessageBox = new CustomMessageBox(titleText, messageBoxText, cancelButtonText, confirmButtonText, messageBoxOptions);
DialogResult dialogResult = new DialogHost(customMessageBox).ShowAsOutlookChild(true);
doNotShowAgain = customMessageBox.DoNotShowAgain;
return (dialogResult == DialogResult.OK);
}
#endregion
}
}
\ No newline at end of file
}
......@@ -13,7 +13,9 @@
IntroTutorial,
ForceProtection,
GroupInvite,
Options
Options,
CustomMessageBox,
InputMessageBox
}
/// <summary>
......
......@@ -3,20 +3,6 @@ using System.Collections.Generic;
namespace pEp.UI.Models
{
public struct pEpMember
{
public pEpCOMServerAdapterLib.pEpIdentity ident;
public bool joined;
}
public struct pEpGroup
{
public pEpCOMServerAdapterLib.pEpIdentity groupIdentity;
public pEpCOMServerAdapterLib.pEpIdentity manager;
public pEpMember[] members;
public bool active;
};
internal class MessageGroup
{
/// <summary>
......@@ -32,7 +18,7 @@ namespace pEp.UI.Models
/// <summary>
/// The group members.
/// </summary>
public List<pEpMember> GroupMembers { get; } = new List<pEpMember>();
public List<pEpIdentity> GroupMembers { get; } = new List<pEpIdentity>();
/// <summary>
/// Gets or sets the pEp rating of this group.
......@@ -52,17 +38,15 @@ namespace pEp.UI.Models
}
/// <summary>
/// Secondary constructor.
/// Constructor for message group with existing members.
/// </summary>
/// <param name="groupIdentity">The group identity.</param>
/// <param name="groupManager">The group manager.</param>
/// <param name="groupMembers">The group members.</param>
public MessageGroup(pEpGroup group) : this(group.groupIdentity, group.manager)
/// <param name="groupMembers">The group manager.</param>
public MessageGroup(pEpIdentity groupIdentity, pEpIdentity groupManager, List<pEpIdentity> groupMembers) :
this(groupIdentity, groupManager)
{
foreach (pEpMember groupMember in group.members)
{
this.GroupMembers.Add(groupMember);
}
this.GroupMembers = groupMembers;
}
/// <summary>
......@@ -71,9 +55,7 @@ namespace pEp.UI.Models
/// <returns>The group rating.</returns>
private pEpRating GetGroupRating()
{
pEpRating groupRating = pEpRating.pEpRatingUndefined;
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupRating(this.GroupIdentity, this.GroupManager, out groupRating));
return groupRating;
return AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupRating(this.GroupIdentity, this.GroupManager)) as pEpRating? ?? pEpRating.pEpRatingUndefined;
}
/// <summary>
......@@ -86,17 +68,5 @@ namespace pEp.UI.Models
groupIdentity.UserName = name;
this.GroupIdentity = groupIdentity;
}
/// <summary>
/// Creates a new message group.
/// </summary>
/// <param name="groupIdentity">The identity object representing the group.</param>
/// <param name="groupManager">The group manager.</param>
/// <param name="memberList">The list of members.</param>
/// <returns></returns>
public static void Create(pEpIdentity groupIdentity, pEpIdentity groupManager, List<pEpIdentity> memberList)
{
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupCreate(groupIdentity, groupManager, memberList.ToArray()));
}
}
}
......@@ -17,7 +17,6 @@ namespace pEp.UI.Models
public OptionsViewModel.OptionPages StartPage { get; }
/// <summary>
/// Primary constructor.
/// </summary>
......@@ -38,13 +37,13 @@ namespace pEp.UI.Models
}
// Get groups the user is subscribed to
if (this.GetSubscribedGroups() is List<MessageGroup> subscribedGroups)
{
foreach (var messageGroup in subscribedGroups)
{
this.SubscribedGroups.Add(new MessageGroupViewModel(messageGroup));
}
}
//if (this.GetSubscribedGroups() is List<MessageGroup> subscribedGroups)
//{
// foreach (var messageGroup in subscribedGroups)
// {
// this.SubscribedGroups.Add(new MessageGroupViewModel(messageGroup));
// }
//}
}
/// <summary>
......@@ -55,17 +54,30 @@ namespace pEp.UI.Models
{
var messageGroups = new List<MessageGroup>();
//if (AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupQueryGroups()) is pEpIdentity[] groups)
//{
// foreach (var group in groups)
// {
// pEpIdentity manager = AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupQueryManager(group));
// pEpIdentity[] members = AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupQueryMembers(group));
if (AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupQueryGroups()) is pEpIdentity[] groups)
{
foreach (var groupIdentity in groups)
{
try
{
// Get group manager
pEpIdentity groupManager = (pEpIdentity)AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupQueryManager(groupIdentity));
Log.Verbose("GetManagedGroupe: Retrieved group manager " + groupManager.Address);
// Get group members
pEpIdentity[] members = (pEpIdentity[])AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupQueryMembers(groupIdentity));
Log.Verbose("GetManagedGroupe: Retrieved group {0} group members" + members.Length);
// Add group
messageGroups.Add(new MessageGroup(groupIdentity, groupManager, members.ToList()));
}
catch (Exception ex)
{
Log.Error("GetManagedGroups: Error querying groups. " + ex.ToString());
}
// messageGroups.Add(new MessageGroup(group, manager, members));
// }
//}
messageGroups = this.CreateDummyList();
}
}
return messageGroups;
}
......@@ -74,10 +86,10 @@ namespace pEp.UI.Models
/// Gets a list of groups the user is part of from the adapter.
/// </summary>
/// <returns>The groups that the user is subscribed to.</returns>
private List<MessageGroup> GetSubscribedGroups()
{
return this.CreateDummyList();
}
//private List<MessageGroup> GetSubscribedGroups()
//{
// return this.CreateDummyList();
//}
/// <summary>
/// Updates the settings and synchronize changes.
......@@ -121,7 +133,7 @@ namespace pEp.UI.Models
{
if (this.ManagedGroups.Any(mg => mg.GroupIdentity.Address == group.GroupIdentity.Address) == false)
{
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupDissolve(group.GroupIdentity, group.GroupManager));
AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupDissolve(group.GroupIdentity, group.GroupManager));
}
});
......@@ -143,19 +155,19 @@ namespace pEp.UI.Models
// Remove members
group?.GroupMembers?.ForEach((member) =>
{
if (messageGroupViewModel.GroupMembers?.Any(a => a.PEPIdentity.Address.Equals(member.ident.Address)) == false)
if (messageGroupViewModel.GroupMembers?.Any(a => a.PEPIdentity.Address.Equals(member.Address)) == false)
{
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupRemoveMember(group.GroupIdentity, member.ident));
AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupRemoveMember(group.GroupIdentity, member));
}
});
// Invite new members
messageGroupViewModel.GroupMembers?.ToList()?.ForEach((member) =>
{
if (group.GroupMembers?.Any(a => a.ident.Address.Equals(member.PEPIdentity.Address)) == false)
if (group.GroupMembers?.Any(a => a.Address.Equals(member.PEPIdentity.Address)) == false)
{
pEpIdentity newGroupMember = member.PEPIdentity.ToCOMType();
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupInviteMember(group.GroupIdentity, newGroupMember));
AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupInviteMember(group.GroupIdentity, newGroupMember));
}
});
}
......@@ -176,12 +188,12 @@ namespace pEp.UI.Models
try
{
// First try to create the group
ThisAddIn.PEPEngine.GroupCreate(group.GroupIdentity, group.GroupManager, memberlist.ToArray());
AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupCreate(group.GroupIdentity, group.GroupManager, memberlist.ToArray()));
// Only invite members if group was created successfully
memberlist.ForEach((member) =>
{
AdapterExtensions.ExecuteAndLogError(() => ThisAddIn.PEPEngine.GroupInviteMember(group.GroupIdentity, member));
AdapterExtensions.ExecuteWithPassphraseCheck(() => ThisAddIn.PEPEngine.GroupInviteMember(group.GroupIdentity, member));
});
}
catch (Exception ex)
......@@ -191,46 +203,5 @@ namespace pEp.UI.Models
}
});
}
private List<MessageGroup> CreateDummyList()
{
return new List<MessageGroup>
{
new MessageGroup(new pEpIdentity { Address = "gi1@peptest.ch", UserName = "Test 1" }, new pEpIdentity { Address = "groupManager@peptest.ch" })
{
GroupMembers =
{
new pEpMember { ident = new pEpIdentity { Address = "test@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test2@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test3@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test4@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test5@peptest.ch" } }
}
},
new MessageGroup(new pEpIdentity { Address = "gi2@peptest.ch", UserName = "Test 2" }, new pEpIdentity { Address = "groupManager@peptest.ch" })
{
GroupMembers =
{
new pEpMember { ident = new pEpIdentity { Address = "test1@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test6@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test7@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test8@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test9@peptest.ch" } }
}
},
new MessageGroup(new pEpIdentity { Address = "gi3@peptest.ch", UserName = "Test 3" }, new pEpIdentity { Address = "groupManager@peptest.ch" })
{
GroupMembers =
{
new pEpMember { ident = new pEpIdentity { Address = "test1@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test2@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test5@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test8@peptest.ch" } },
new pEpMember { ident = new pEpIdentity { Address = "test9@peptest.ch" } }
}
}
};
}
}
}
using pEp.UI.Models;
using System;
using System.Windows;
namespace pEp.UI.ViewModels
{
internal class CustomMessageBoxViewModel : DialogHostViewModel
{
private CustomMessageBox customMessageBox;
public CustomMessageBoxViewModel(CustomMessageBox dialog, Action closeDialogAction) : base(dialog, closeDialogAction)
{
this.customMessageBox = dialog;
if (customMessageBox.MessageBoxOptions.HasFlag(CustomMessageBox.CustomMessageBoxOptions.RedAndGreenButtons))
{
this.CancelButtonStyle = Globals.ResourceDict["StyleButtonRed"] as Style;
this.ConfirmButtonStyle = Globals.ResourceDict["StyleButtonGreen"] as Style;
}
else
{
this.CancelButtonStyle = Globals.ResourceDict["StyleButtonGray"] as Style;
this.ConfirmButtonStyle = Globals.ResourceDict["StyleButtonGray"] as Style;
}
}
/// <summary>
/// Gets or sets the text of the Cancel button.
/// </summary>
public string CancelButtonText => this.customMessageBox.CancelButtonText;
/// <summary>
/// Gets the style of the Cancel button.
/// </summary>
public Style CancelButtonStyle { get; }
/// <summary>
/// Gets or sets the text of the Confirm button.
/// </summary>
public string ConfirmButtonText => this.customMessageBox.ConfirmButtonText;
/// <summary>
/// Gets the style of the Confirm button.
/// </summary>
public Style ConfirmButtonStyle { get; }
/// <summary>
/// The command to execute when the Cancel button is clicked.
/// </summary>
public RelayCommand CancelButtonCommand
{
get
{
return new RelayCommand(p => base.Close(false));
}
}
/// <summary>
/// The command to execute when the Confirm button is clicked.
/// </summary>
public RelayCommand ConfirmButtonCommand
{
get
{
return new RelayCommand(p => base.Close(true));
}
}
/// <summary>
/// Whether the Cancel button is visible.
/// </summary>
public bool IsCancelButtonVisible => (this.customMessageBox.MessageBoxOptions.HasFlag(CustomMessageBox.CustomMessageBoxOptions.NoCancelButton) == false);
/// <summary>
/// Gets or sets whether the 'Do not show again' checkbox is checked.
/// </summary>
public bool IsDoNotShowAgainChecked
{
get => this.customMessageBox.DoNotShowAgain;
set
{
this.customMessageBox.DoNotShowAgain = value;
this.OnPropertyChanged();
}
}
/// <summary>
/// Gets or sets whether the 'Do not show again' checkbox is visible.
/// </summary>
public bool IsDoNotShowAgainVisible => this.customMessageBox.MessageBoxOptions.HasFlag(CustomMessageBox.CustomMessageBoxOptions.DoNotShowAgainCheckBox);
/// <summary>
/// Gets the message box text.
/// </summary>
public string MessageBoxText => this.customMessageBox.MessageBoxText;
/// <summary>
/// Gehts the title of the MessageBox
/// </summary>
public string Title => this.customMessageBox.Title;
}
}
......@@ -10,7 +10,7 @@ namespace pEp.UI.ViewModels
/// <summary>
/// The action to close the dialog window.
/// </summary>
public Action CloseDialogAction { get; }
private readonly Action closeDialogAction = null;
/// <summary>
/// The dialog object.
......@@ -20,7 +20,7 @@ namespace pEp.UI.ViewModels
/// <summary>
/// The result of the dialog.
/// </summary>
public bool? DialogResult { get; set; }
public bool? DialogResult { get; private set; }
/// <summary>
/// Command for when the Close button is being clicked.
......@@ -31,7 +31,7 @@ namespace pEp.UI.ViewModels
{
if (this._CommandButtonClose == null)
{
this._CommandButtonClose = new RelayCommand(p => this.CloseDialogAction?.Invoke());
this._CommandButtonClose = new RelayCommand(p => this.closeDialogAction?.Invoke());
}
return this._CommandButtonClose;
......@@ -45,7 +45,16 @@ namespace pEp.UI.ViewModels
public DialogHostViewModel(Dialog dialog, Action closeDialogAction)
{
this.Dialog = dialog;
this.CloseDialogAction = closeDialogAction;
this.closeDialogAction = closeDialogAction;
}
/// <summary>
/// Invokes the Close action and closes the parent dialog.
/// </summary>
public void Close(bool? dialogResult)
{
this.DialogResult = dialogResult;
this.closeDialogAction?.Invoke();
}
}
}
......@@ -421,8 +421,7 @@ namespace pEp.UI.ViewModels
// Update the view
if (this.Parent.Dialog.DialogType == Dialog.Type.ForceProtection)
{
this.Parent.DialogResult = false;
this.Parent.CloseDialogAction.Invoke();
this.Parent.Close(false);
}
else
{
......@@ -456,8 +455,7 @@ namespace pEp.UI.ViewModels
// Update the view
if (this.Parent.Dialog.DialogType == Dialog.Type.ForceProtection)
{
this.Parent.DialogResult = true;
this.Parent.CloseDialogAction.Invoke();
this.Parent.Close(true);
}
else
{
......
......@@ -37,7 +37,7 @@ namespace pEp.UI.ViewModels
{
if (this._CancelCommand == null)
{
this._CancelCommand = new RelayCommand(p => this.CloseDialogAction?.Invoke());
this._CancelCommand = new RelayCommand(p => base.Close(false));
}
return this._CancelCommand;
......
......@@ -99,7 +99,7 @@ namespace pEp.UI.ViewModels
foreach (var member in messageGroup.GroupMembers)
{
this.GroupMembers.Add(new MessageGroupMemberViewModel(this, new PEPIdentity(member.ident.Address)));
this.GroupMembers.Add(new MessageGroupMemberViewModel(this, new PEPIdentity(member)));
}
}
......
......@@ -128,11 +128,7 @@ namespace pEp.UI.ViewModels
{
if (this._CommandButtonCancel == null)
{
this._CommandButtonCancel = new RelayCommand(p =>
{
this.DialogResult = null;
this.CloseDialogAction.Invoke();
});
this._CommandButtonCancel = new RelayCommand(p => base.Close(null));
}
return this._CommandButtonCancel;
......@@ -216,11 +212,7 @@ namespace pEp.UI.ViewModels
{
if (this._CommandButtonOK == null)
{
this._CommandButtonOK = new RelayCommand(p =>
{
this.DialogResult = true;
this.CloseDialogAction.Invoke();
});
this._CommandButtonOK = new RelayCommand(p => base.Close(true));
}
return this._CommandButtonOK;
......
......@@ -241,8 +241,7 @@ namespace pEp.UI.ViewModels
/// </summary>
private void CancelDialog()
{
this.DialogResult = null;
this.CloseDialogAction?.Invoke();
base.Close(null);
}
/// <summary>
......@@ -269,7 +268,7 @@ namespace pEp.UI.ViewModels
{
if (this.IsLastPage)
{
this.CloseDialogAction?.Invoke();
base.Close(true);
}
else
{
......@@ -311,8 +310,8 @@ namespace pEp.UI.ViewModels
{
Log.Error("RejectHandshake: Error delivering handshake result. " + ex.ToString());
}
this.DialogResult = false;
this.CloseDialogAction?.Invoke();
base.Close(false);
}
break;
case Dialog.Type.IntroTutorial:
......
<Window x:Class="pEp.UI.CustomMessageBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:pEp.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:p="clr-namespace:pEp.Properties"
x:ClassModifier="internal"
Icon="pack://application:,,,/pEp;component/Resources/ImageLogoIcon.png"
mc:Ignorable="d"
Width="480"
WindowStartupLocation="CenterScreen"
SizeToContent="Height"
Background="WhiteSmoke"
ResizeMode="NoResize">
<Window.Resources>
<UserControl x:Class="pEp.UI.Views.CustomMessageBoxView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:core="clr-namespace:System;assembly=mscorlib"
xmlns:p="clr-namespace:pEp.Properties"
xmlns:local="clr-namespace:pEp.UI"
x:ClassModifier="internal"
mc:Ignorable="d"
Width="480"
Background="WhiteSmoke">
<UserControl.Resources>
<ResourceDictionary>
<!-- Dictionary -->
<ResourceDictionary.MergedDictionaries>
......@@ -26,7 +23,7 @@
<BooleanToVisibilityConverter />
</local:ValueConverterGroup>
</ResourceDictionary>
</Window.Resources>
</UserControl.Resources>
<StackPanel Margin="10">
......@@ -39,17 +36,19 @@
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Style="{StaticResource StyleButtonGray}"
<Button Name="ConfirmButton"
Style="{Binding ConfirmButtonStyle}"
HorizontalAlignment="Center"
Margin="5,5,0,5"
Content="{Binding ButtonConfirmText}"
Command="{Binding CommandButtonConfirm}"/>
<Button Style="{StaticResource StyleButtonGray}"
Content="{Binding ConfirmButtonText}"
Command="{Binding ConfirmButtonCommand}"/>
<Button Name="CancelButton"
Style="{Binding CancelButtonStyle}"
HorizontalAlignment="Center"
Margin="5,5,0,5"
Content="{Binding ButtonCancelText}"
Command="{Binding CommandButtonCancel}"
Visibility="{Binding ButtonCancelText, Mode=OneWay, Converter={StaticResource IsStringNotEmptyToVisibility}}" />
Content="{Binding CancelButtonText}"
Command="{Binding CancelButtonCommand}"
Visibility="{Binding IsCancelButtonVisible, Mode=OneWay, Converter={StaticResource BoolToVisibility}}" />
</StackPanel>
<CheckBox Content="{x:Static p:Resources.CustomMessageBoxDoNotShowAgain}"
......@@ -59,4 +58,4 @@
Visibility="{Binding IsDoNotShowAgainVisible, Converter={StaticResource BoolToVisibility}}"/>
</StackPanel>
</Window>
</UserControl>
using System.Windows.Controls;
namespace pEp.UI.Views
{
/// <summary>
/// Interaction logic for CustomMessageBoxView.xaml
/// </summary>
internal partial class CustomMessageBoxView : UserControl
{
/// <summary>
/// Primary constructor.
/// </summary>
public CustomMessageBoxView()
{
InitializeComponent();
}
}
}
\ No newline at end of file
......@@ -25,5 +25,8 @@
<DataTemplate DataType="{x:Type vm:OptionsViewModel}">
<v:OptionsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:CustomMessageBoxViewModel}">
<v:CustomMessageBoxView />
</DataTemplate>
</UserControl.Resources>
</UserControl>
......@@ -31,6 +31,12 @@ namespace pEp.UI.Views
// Assign the necessary ViewModel according to the dialog type.
switch (dialog.DialogType)
{
case Dialog.Type.CustomMessageBox:
{
Debug.Assert(dialog is CustomMessageBox);
this.Content = new CustomMessageBoxViewModel(dialog as CustomMessageBox, closeDialogAction);
}
break;
case Dialog.Type.Handshake:
{
Debug.Assert(dialog is HandshakeDialog);
......
......@@ -406,8 +406,10 @@
<DependentUpon>Resources.tr.resx</DependentUpon>
</Compile>
<Compile Include="Sequoia.cs" />
<Compile Include="UI\CustomMessageBox.xaml.cs">
<DependentUpon>CustomMessageBox.xaml</DependentUpon>
<Compile Include="UI\Models\CustomMessageBox.cs" />
<Compile Include="UI\ViewModels\CustomMessageBoxViewModel.cs" />
<Compile Include="UI\Views\CustomMessageBoxView.xaml.cs">
<DependentUpon>CustomMessageBoxView.xaml</DependentUpon>
</Compile>
<Compile Include="UI\DialogHost.cs">
<SubType>Form</SubType>
......@@ -664,7 +666,7 @@
<Resource Include="Resources\ImagePrivacyStatusYellow.png" />
</ItemGroup>
<ItemGroup>
<Page Include="UI\CustomMessageBox.xaml">
<Page Include="UI\Views\CustomMessageBoxView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
......