WIP Split composite key user control

Some refactoring
This commit is contained in:
Geoffroy BONNEVILLE
2020-04-20 20:02:43 +02:00
parent 73670e8689
commit 310bd777b2
54 changed files with 849 additions and 1200 deletions

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Application.Group.Models;
@@ -13,19 +12,11 @@ namespace ModernKeePass.Interfaces
string Title { get; set; }
IEnumerable<GroupVm> BreadCrumb { get; }
bool IsEditMode { get; }
/// <summary>
/// Save changes to Model
/// </summary>
ICommand SaveCommand { get; }
/// <summary>
/// Move a entity to the destination group
/// </summary>
/// <param name="destination">The destination to move the entity to</param>
Task Move(GroupVm destination);
/// <summary>
/// Delete from ViewModel
/// </summary>
Task MarkForDelete(string recycleBinTitle);
}
}

View File

@@ -31,7 +31,7 @@ namespace ModernKeePass.ViewModels
set
{
SetProperty(ref _hasPassword, value);
OnPropertyChanged("IsValid");
OnPropertyChanged(nameof(IsValid));
}
}
@@ -41,21 +41,11 @@ namespace ModernKeePass.ViewModels
set
{
SetProperty(ref _hasKeyFile, value);
OnPropertyChanged("IsValid");
OnPropertyChanged(nameof(IsValid));
}
}
public bool HasUserAccount
{
get { return _hasUserAccount; }
set
{
SetProperty(ref _hasUserAccount, value);
OnPropertyChanged("IsValid");
}
}
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null || HasUserAccount);
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != null);
public string Status
{
@@ -103,7 +93,6 @@ namespace ModernKeePass.ViewModels
private bool _hasPassword;
private bool _hasKeyFile;
private bool _hasUserAccount;
private bool _isOpening;
private string _password = string.Empty;
private string _status;
@@ -160,7 +149,6 @@ namespace ModernKeePass.ViewModels
var errorMessage = new StringBuilder($"{_resource.GetResourceValue("CompositeKeyErrorOpen")}\n");
if (HasPassword) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
if (HasKeyFile) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
if (HasUserAccount) errorMessage.AppendLine(_resource.GetResourceValue("CompositeKeyErrorUserAccount"));
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
}
catch (Exception e)
@@ -171,7 +159,7 @@ namespace ModernKeePass.ViewModels
finally
{
_isOpening = false;
OnPropertyChanged("IsValid");
OnPropertyChanged(nameof(IsValid));
}
return false;
}

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using MediatR;
@@ -120,10 +119,10 @@ namespace ModernKeePass.ViewModels
public string Url
{
get { return SelectedItem.Url?.ToString(); }
get { return SelectedItem.Url; }
set
{
SelectedItem.Url = new Uri(value);
SelectedItem.Url = value;
SetFieldValue(nameof(Url), value).Wait();
}
}
@@ -216,10 +215,10 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isRevealPassword, value); }
}
public ICommand SaveCommand { get; }
public ICommand GeneratePasswordCommand { get; }
public ICommand MoveCommand { get; }
public ICommand RestoreCommand { get; }
public RelayCommand SaveCommand { get; }
public RelayCommand GeneratePasswordCommand { get; }
public RelayCommand MoveCommand { get; }
public RelayCommand RestoreCommand { get; }
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
@@ -286,7 +285,7 @@ namespace ModernKeePass.ViewModels
public async Task SetFieldValue(string fieldName, object value)
{
await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
_isDirty = true;
}
@@ -300,7 +299,7 @@ namespace ModernKeePass.ViewModels
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex });
History.Insert(0, SelectedItem);
SelectedIndex = 0;
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
public async Task DeleteHistory()
@@ -308,14 +307,14 @@ namespace ModernKeePass.ViewModels
await _mediator.Send(new DeleteHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex });
History.RemoveAt(SelectedIndex);
SelectedIndex = 0;
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
private async Task SaveChanges()
{
await AddHistory();
await _mediator.Send(new SaveDatabaseCommand());
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
_isDirty = false;
}
}

View File

@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.UI.Xaml.Controls;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
@@ -53,7 +52,7 @@ namespace ModernKeePass.ViewModels
set
{
_mediator.Send(new UpdateGroupCommand {Group = _group, Title = value, Icon = _group.Icon}).Wait();
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
}
@@ -63,7 +62,7 @@ namespace ModernKeePass.ViewModels
set
{
_mediator.Send(new UpdateGroupCommand { Group = _group, Title = _group.Title, Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString()) }).Wait();
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
}
@@ -73,8 +72,8 @@ namespace ModernKeePass.ViewModels
set
{
SetProperty(ref _isEditMode, value);
((RelayCommand)SortEntriesCommand).RaiseCanExecuteChanged();
((RelayCommand)SortGroupsCommand).RaiseCanExecuteChanged();
SortEntriesCommand.RaiseCanExecuteChanged();
SortGroupsCommand.RaiseCanExecuteChanged();
}
}
@@ -89,10 +88,10 @@ namespace ModernKeePass.ViewModels
public IEnumerable<GroupVm> BreadCrumb { get; }
public ICommand SaveCommand { get; }
public ICommand SortEntriesCommand { get; }
public ICommand SortGroupsCommand { get; }
public ICommand MoveCommand { get; }
public RelayCommand SaveCommand { get; }
public RelayCommand SortEntriesCommand { get; }
public RelayCommand SortGroupsCommand { get; }
public RelayCommand MoveCommand { get; }
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
@@ -156,7 +155,7 @@ namespace ModernKeePass.ViewModels
private async Task SaveChanges()
{
await _mediator.Send(new SaveDatabaseCommand());
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
private async void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -179,21 +178,21 @@ namespace ModernKeePass.ViewModels
}
break;
}
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
private async Task SortEntriesAsync()
{
await _mediator.Send(new SortEntriesCommand {Group = _group});
OnPropertyChanged(nameof(Entries));
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
private async Task SortGroupsAsync()
{
await _mediator.Send(new SortGroupsCommand {Group = _group});
OnPropertyChanged(nameof(Groups));
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
SaveCommand.RaiseCanExecuteChanged();
}
}
}

View File

@@ -1,30 +0,0 @@
using System;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
namespace ModernKeePass.ViewModels
{
public class ListMenuItemVm : NotifyPropertyChangedBase, IIsEnabled, ISelectableModel
{
private bool _isSelected;
public string Title { get; set; }
public string Group { get; set; } = "_";
public Type PageType { get; set; }
public Symbol SymbolIcon { get; set; }
public bool IsEnabled { get; set; } = true;
public bool IsSelected
{
get { return _isSelected; }
set { SetProperty(ref _isSelected, value); }
}
public override string ToString()
{
return Title;
}
}
}

View File

@@ -1,10 +0,0 @@
using Windows.UI.Xaml.Controls;
namespace ModernKeePass.ViewModels
{
public class MainMenuItemVm: ListMenuItemVm
{
public object Parameter { get; set; }
public Frame Destination { get; set; }
}
}

View File

@@ -1,56 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces;
namespace ModernKeePass.ViewModels
{
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel
{
private readonly IRecentProxy _recent;
private bool _isSelected;
private string _name;
private string _token;
private string _path;
public string Token
{
get { return _token; }
set { SetProperty(ref _token, value); }
}
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public string Path
{
get { return _path; }
set { SetProperty(ref _path, value); }
}
public bool IsSelected
{
get { return _isSelected; }
set { SetProperty(ref _isSelected, value); }
}
public RecentItemVm(FileInfo file): this(App.Services.GetRequiredService<IRecentProxy>(), file) {}
public RecentItemVm(IRecentProxy recent, FileInfo file)
{
_recent = recent;
Token = file.Id;
Name = file.Name;
Path = file.Path;
}
// Called from XAML
public void UpdateAccessTime()
{
_recent.Get(Token, true).Wait();
}
}
}

View File

@@ -1,94 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Models;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Application.Group.Queries.GetGroup;
using ModernKeePass.Application.Parameters.Commands.SetCipher;
using ModernKeePass.Application.Parameters.Commands.SetCompression;
using ModernKeePass.Application.Parameters.Commands.SetHasRecycleBin;
using ModernKeePass.Application.Parameters.Commands.SetKeyDerivation;
using ModernKeePass.Application.Parameters.Commands.SetRecycleBin;
using ModernKeePass.Application.Parameters.Models;
using ModernKeePass.Application.Parameters.Queries.GetCiphers;
using ModernKeePass.Application.Parameters.Queries.GetCompressions;
using ModernKeePass.Application.Parameters.Queries.GetKeyDerivations;
using ModernKeePass.Domain.AOP;
namespace ModernKeePass.ViewModels
{
// TODO: implement Kdf settings
public class SettingsDatabaseVm: NotifyPropertyChangedBase
{
private readonly IMediator _mediator;
private readonly DatabaseVm _database;
public bool HasRecycleBin
{
get { return _database.IsRecycleBinEnabled; }
set
{
_mediator.Send(new SetHasRecycleBinCommand {HasRecycleBin = value}).Wait();
OnPropertyChanged(nameof(HasRecycleBin));
}
}
public bool IsNewRecycleBin
{
get { return string.IsNullOrEmpty(_database.RecycleBinId); }
set
{
if (value) _mediator.Send(new SetRecycleBinCommand { RecycleBinId = null }).Wait();
}
}
public ObservableCollection<IEntityVm> Groups { get; }
public ObservableCollection<CipherVm> Ciphers { get; }
public IEnumerable<string> Compressions => _mediator.Send(new GetCompressionsQuery()).GetAwaiter().GetResult();
public ObservableCollection<KeyDerivationVm> KeyDerivations { get; }
public CipherVm SelectedCipher
{
get { return Ciphers.FirstOrDefault(c => c.Id == _database.CipherId); }
set { _mediator.Send(new SetCipherCommand {CipherId = value.Id}).Wait(); }
}
public string SelectedCompression
{
get { return Compressions.FirstOrDefault(c => c == _database.Compression); }
set { _mediator.Send(new SetCompressionCommand {Compression = value}).Wait(); }
}
public KeyDerivationVm SelectedKeyDerivation
{
get { return KeyDerivations.FirstOrDefault(c => c.Id == _database.KeyDerivationId); }
set { _mediator.Send(new SetKeyDerivationCommand {KeyDerivationId = value.Id}).Wait(); }
}
public IEntityVm SelectedRecycleBin
{
get { return Groups.FirstOrDefault(g => g.Id == _database.RecycleBinId); }
set
{
if (!IsNewRecycleBin) _mediator.Send(new SetRecycleBinCommand { RecycleBinId = value.Id}).Wait();
}
}
public SettingsDatabaseVm() : this(App.Services.GetRequiredService<IMediator>()) { }
public SettingsDatabaseVm(IMediator mediator)
{
_mediator = mediator;
_database = _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
var rootGroup = _mediator.Send(new GetGroupQuery { Id = _database.RootGroupId }).GetAwaiter().GetResult();
Groups = new ObservableCollection<IEntityVm>(rootGroup.SubGroups);
var ciphers = _mediator.Send(new GetCiphersQuery()).GetAwaiter().GetResult();
Ciphers = new ObservableCollection<CipherVm>(ciphers);
var keyDerivations = _mediator.Send(new GetKeyDerivationsQuery()).GetAwaiter().GetResult();
KeyDerivations = new ObservableCollection<KeyDerivationVm>(keyDerivations);
}
}
}

View File

@@ -1,33 +0,0 @@
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
namespace ModernKeePass.ViewModels
{
public class SettingsNewVm
{
private readonly ISettingsProxy _settings;
public SettingsNewVm() : this(App.Services.GetRequiredService<ISettingsProxy>())
{ }
public SettingsNewVm(ISettingsProxy settings)
{
_settings = settings;
}
public bool IsCreateSample
{
get { return _settings.GetSetting<bool>("Sample"); }
set { _settings.PutSetting("Sample", value); }
}
public IEnumerable<string> FileFormats => new []{"2", "4"};
public string FileFormatVersion
{
get { return _settings.GetSetting<string>("DefaultFileFormat"); }
set { _settings.PutSetting("DefaultFileFormat", value); }
}
}
}

View File

@@ -1,25 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Common;
namespace ModernKeePass.ViewModels
{
public class SettingsSaveVm
{
private readonly ISettingsProxy _settings;
public SettingsSaveVm() : this(App.Services.GetRequiredService<ISettingsProxy>())
{ }
public SettingsSaveVm(ISettingsProxy settings)
{
_settings = settings;
}
public bool IsSaveSuspend
{
get { return _settings.GetSetting(Constants.Settings.SaveSuspend, true); }
set { _settings.PutSetting(Constants.Settings.SaveSuspend, value); }
}
}
}

View File

@@ -10,6 +10,7 @@ using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.Models;
using ModernKeePass.ViewModels.ListItems;
using ModernKeePass.Views;
namespace ModernKeePass.ViewModels

View File

@@ -6,6 +6,7 @@ using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Common;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.ViewModels.ListItems;
namespace ModernKeePass.ViewModels
{

View File

@@ -7,6 +7,7 @@ using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Domain.AOP;
using ModernKeePass.Domain.Interfaces;
using ModernKeePass.ViewModels.ListItems;
using ModernKeePass.Views;
namespace ModernKeePass.ViewModels

View File

@@ -133,11 +133,10 @@
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>
<MenuFlyoutItem x:Uid="EntryItemCopyUrl">
<MenuFlyoutItem x:Uid="EntryItemCopyUrl" IsEnabled="{Binding HasUrl}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
<actions:NavigateToUrlAction Url="{Binding Url}" />
<actions:ToastAction x:Uid="ToastCopyUrl" Title="{Binding Title}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</MenuFlyoutItem>

View File

@@ -2,6 +2,7 @@
using Windows.UI.Xaml.Navigation;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.ViewModels;
using ModernKeePass.ViewModels.ListItems;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

View File

@@ -25,13 +25,13 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton" DatabaseFilePath="{Binding Token}">
<userControls:OpenDatabaseUserControl x:Uid="CompositeKeyOpenButton" DatabaseFilePath="{Binding Token}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:EventTriggerBehavior EventName="DatabaseOpened">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:CompositeKeyUserControl>
</userControls:OpenDatabaseUserControl>
</StackPanel>
</Border>
</StackPanel>

View File

@@ -43,16 +43,16 @@
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}" Padding="5,0,0,0" />
<TextBlock Grid.Row="1" Text="{Binding Path}" Padding="5,0,0,0" FontSize="10" />
<userControls:CompositeKeyUserControl Grid.Row="2" x:Name="DatabaseUserControl" x:Uid="CompositeKeyOpenButton" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}">
<userControls:OpenDatabaseUserControl Grid.Row="2" x:Uid="CompositeKeyOpenButton" HorizontalAlignment="Stretch" MinWidth="400" Margin="0,10,0,0" Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" DatabaseFilePath="{Binding Token}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecking">
<core:EventTriggerBehavior EventName="DatabaseOpening">
<core:CallMethodAction TargetObject="{Binding}" MethodName="UpdateAccessTime" />
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:EventTriggerBehavior EventName="DatabaseOpened">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</userControls:CompositeKeyUserControl>
</userControls:OpenDatabaseUserControl>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>

View File

@@ -1,5 +1,6 @@
using Windows.UI.Xaml.Controls;
using ModernKeePass.ViewModels;
using ModernKeePass.ViewModels.ListItems;
// The Split Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234234

View File

@@ -4,8 +4,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:converters="using:ModernKeePass.Converters"
xmlns:listItems="using:ModernKeePass.ViewModels.ListItems"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="RecycleBinGroups" Source="{Binding Groups}" />
@@ -16,7 +16,7 @@
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
</Page.Resources>
<Page.DataContext>
<viewModels:SettingsDatabaseVm />
<listItems:SettingsDatabaseVm />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

View File

@@ -4,13 +4,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:listItems="using:ModernKeePass.ViewModels.ListItems"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="KeyDerivations" Source="{Binding FileFormats}" />
</Page.Resources>
<Page.DataContext>
<viewModels:SettingsNewVm />
<listItems:SettingsNewVm />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Uid="SettingsNewDatabaseDesc" Style="{StaticResource TextBlockSettingsHeaderStyle}" Margin="5,0,0,10"/>

View File

@@ -4,10 +4,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="using:ModernKeePass.ViewModels"
xmlns:listItems="using:ModernKeePass.ViewModels.ListItems"
mc:Ignorable="d">
<Page.DataContext>
<viewModels:SettingsSaveVm />
<listItems:SettingsSaveVm />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

View File

@@ -0,0 +1,55 @@
<UserControl
x:Class="ModernKeePass.Views.UserControls.OpenDatabaseUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:converters="using:ModernKeePass.Converters"
xmlns:viewModels="using:ModernKeePass.ViewModels"
mc:Ignorable="d" >
<UserControl.Resources>
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
</UserControl.Resources>
<Grid x:Name="Grid">
<!-- DataContext is not set at the root of the control because of issues happening when displaying it -->
<Grid.DataContext>
<viewModels:OpenDatabaseControlVm />
</Grid.DataContext>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" KeyDown="PasswordBox_KeyDown" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" >
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="GotFocus">
<core:ChangePropertyAction TargetObject="{Binding}" PropertyName="HasPassword" Value="True" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</PasswordBox>
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0"
Content="{Binding KeyFileText, Mode=OneWay}"
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
Click="KeyFileButton_Click"
Style="{StaticResource MainColorHyperlinkButton}" />
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
Content="{Binding ButtonLabel, ElementName=UserControl}"
Click="OpenButton_OnClick"
IsEnabled="{Binding IsValid}"
Style="{StaticResource MainColorButton}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light"
Text="{Binding Status, Mode=OneWay}"
Foreground="{Binding StatusType, Mode=OneWay, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}"
Visibility="{Binding Status, Mode=OneWay, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,134 @@
using System;
using System.Threading.Tasks;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using MediatR;
using Microsoft.Extensions.DependencyInjection;
using ModernKeePass.Application.Common.Interfaces;
using ModernKeePass.Application.Database.Commands.CloseDatabase;
using ModernKeePass.Application.Database.Commands.SaveDatabase;
using ModernKeePass.Application.Database.Queries.GetDatabase;
using ModernKeePass.Common;
using ModernKeePass.Events;
using ModernKeePass.Extensions;
using ModernKeePass.ViewModels;
// Pour en savoir plus sur le modèle d'élément Contrôle utilisateur, consultez la page http://go.microsoft.com/fwlink/?LinkId=234236
namespace ModernKeePass.Views.UserControls
{
public sealed partial class OpenDatabaseUserControl
{
private readonly IMediator _mediator;
private readonly IResourceProxy _resource;
public OpenDatabaseControlVm Model => Grid.DataContext as OpenDatabaseControlVm;
public string ButtonLabel
{
get { return (string)GetValue(ButtonLabelProperty); }
set { SetValue(ButtonLabelProperty, value); }
}
public static readonly DependencyProperty ButtonLabelProperty =
DependencyProperty.Register(
nameof(ButtonLabel),
typeof(string),
typeof(OpenDatabaseUserControl),
new PropertyMetadata("OK", (o, args) => { }));
public string DatabaseFilePath
{
get { return (string)GetValue(DatabaseFilePathProperty); }
set { SetValue(DatabaseFilePathProperty, value); }
}
public static readonly DependencyProperty DatabaseFilePathProperty =
DependencyProperty.Register(
nameof(DatabaseFilePath),
typeof(string),
typeof(OpenDatabaseUserControl),
new PropertyMetadata(null, (o, args) => { }));
public OpenDatabaseUserControl() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IResourceProxy>()) { }
public OpenDatabaseUserControl(IMediator mediator, IResourceProxy resource)
{
_mediator = mediator;
_resource = resource;
InitializeComponent();
}
public event EventHandler DatabaseOpening;
public event EventHandler<PasswordEventArgs> DatabaseOpened;
private async void OpenButton_OnClick(object sender, RoutedEventArgs e)
{
DatabaseOpening?.Invoke(this, new EventArgs());
var database = await _mediator.Send(new GetDatabaseQuery());
if (database.IsOpen)
{
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("MessageDialogDBOpenTitle"),
string.Format(_resource.GetResourceValue("MessageDialogDBOpenDesc"), database.Name),
_resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
_resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
async command =>
{
await _mediator.Send(new SaveDatabaseCommand());
ToastNotificationHelper.ShowGenericToast(
database.Name,
_resource.GetResourceValue("ToastSavedMessage"));
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase();
},
async command =>
{
await _mediator.Send(new CloseDatabaseCommand());
await OpenDatabase();
});
}
else
{
await OpenDatabase();
}
}
private void PasswordBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key != VirtualKey.Enter || !Model.IsValid) return;
OpenButton_OnClick(sender, e);
// Stop the event from triggering twice
e.Handled = true;
}
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
{
var picker = new FileOpenPicker
{
ViewMode = PickerViewMode.List,
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
};
picker.FileTypeFilter.Add("*");
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
if (file == null) return;
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
Model.KeyFilePath = token;
}
private async Task OpenDatabase()
{
var oldLabel = ButtonLabel;
ButtonLabel = _resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFilePath)))
{
DatabaseOpened?.Invoke(this, new PasswordEventArgs(Model.RootGroupId));
}
ButtonLabel = oldLabel;
}
}
}

View File

@@ -0,0 +1,72 @@
<UserControl
x:Class="ModernKeePass.Views.UserControls.UpdateCredentialsUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:converters="using:ModernKeePass.Converters"
xmlns:viewModels="using:ModernKeePass.ViewModels"
mc:Ignorable="d" >
<UserControl.Resources>
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToSolidColorBrushConverter"/>
<converters:DiscreteIntToSolidColorBrushConverter x:Key="DiscreteIntToSolidColorBrushConverter"/>
<converters:EmptyStringToVisibilityConverter x:Key="EmptyStringToVisibilityConverter"/>
</UserControl.Resources>
<Grid x:Name="Grid">
<!-- DataContext is not set at the root of the control because of issues happening when displaying it -->
<Grid.DataContext>
<viewModels:UpdateCredentialsViewModel />
</Grid.DataContext>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="45" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox Grid.Row="0" Grid.Column="0" IsChecked="{Binding HasPassword, Mode=TwoWay}" />
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" >
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="GotFocus">
<core:ChangePropertyAction TargetObject="{Binding}" PropertyName="HasPassword" Value="True" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</PasswordBox>
<PasswordBox Grid.Row="0" Grid.Column="1" x:Uid="CompositeKeyPassword" Password="{Binding Password, Mode=TwoWay}" Height="30" IsPasswordRevealButtonEnabled="True" BorderBrush="{Binding StatusType, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}" SelectionHighlightColor="{StaticResource MainColor}" />
<ProgressBar Grid.Row="0" Grid.Column="1"
Maximum="128" VerticalAlignment="Bottom"
Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}, Mode=OneWay}"
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToSolidColorBrushConverter}, Mode=OneWay}"/>
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0"
Content="{Binding KeyFileText, Mode=OneWay}"
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
Click="KeyFileButton_Click"
Style="{StaticResource MainColorHyperlinkButton}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right"
IsEnabled="{Binding HasKeyFile, Mode=OneWay}"
Style="{StaticResource MainColorHyperlinkButton}"
Click="CreateKeyFileButton_Click">
<SymbolIcon Symbol="Add">
<ToolTipService.ToolTip>
<ToolTip x:Uid="CompositeKeyNewKeyFileTooltip" />
</ToolTipService.ToolTip>
</SymbolIcon>
</HyperlinkButton>
<Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2"
x:Uid="UpdateCredentialsOkButton"
Click="UpdateButton_OnClick"
Style="{StaticResource MainColorButton}"
IsEnabled="{Binding IsValid, Mode=OneWay}" />
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="Auto" FontSize="14" FontWeight="Light"
Text="{Binding Status, Mode=OneWay}"
Foreground="{Binding StatusType, Mode=OneWay, Converter={StaticResource DiscreteIntToSolidColorBrushConverter}}"
Visibility="{Binding Status, Mode=OneWay, Converter={StaticResource EmptyStringToVisibilityConverter}}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using ModernKeePass.Domain.Dtos;
using ModernKeePass.ViewModels;
using ModernKeePass.Extensions;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace ModernKeePass.Views.UserControls
{
public sealed partial class UpdateCredentialsUserControl
{
public UpdateCredentialsViewModel ViewModel => Grid.DataContext as UpdateCredentialsViewModel;
public string DatabaseFilePath
{
get { return (string) GetValue(DatabaseFilePathProperty); }
set { SetValue(DatabaseFilePathProperty, value); }
}
public static readonly DependencyProperty DatabaseFilePathProperty =
DependencyProperty.Register(
"DatabaseFilePath",
typeof(string),
typeof(UpdateCredentialsUserControl),
new PropertyMetadata(null, (o, args) => { }));
public event EventHandler CredentialsUpdated;
public UpdateCredentialsUserControl()
{
InitializeComponent();
}
private async void KeyFileButton_Click(object sender, RoutedEventArgs e)
{
var picker =
new FileOpenPicker
{
ViewMode = PickerViewMode.List,
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
};
picker.FileTypeFilter.Add(".key");
// Application now has read/write access to the picked file
var file = await picker.PickSingleFileAsync();
if (file == null) return;
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
ViewModel.KeyFilePath = token;
}
private async void CreateKeyFileButton_Click(object sender, RoutedEventArgs e)
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = "Key"
};
savePicker.FileTypeChoices.Add("Key file", new List<string> { ".key" });
var file = await savePicker.PickSaveFileAsync();
if (file == null) return;
var token = StorageApplicationPermissions.FutureAccessList.Add(file);
ViewModel.KeyFilePath = token;
}
private async void UpdateButton_OnClick(object sender, RoutedEventArgs e)
{
//throw new NotImplementedException();
if (await Dispatcher.RunTaskAsync(async () =>
{
var fileInfo = new FileInfo
{
Path = DatabaseFilePath
};
await ViewModel.CreateDatabase(fileInfo);
return true;
}))
{
CredentialsUpdated?.Invoke(this, new EventArgs());
}
}
}
}

View File

@@ -94,7 +94,6 @@
</Compile>
<Compile Include="DependencyInjection.cs" />
<Compile Include="Models\NavigationItem.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
<DependentUpon>DonatePage.xaml</DependentUpon>
</Compile>
@@ -144,9 +143,6 @@
</Compile>
<Compile Include="ViewModels\AboutVm.cs" />
<Compile Include="ViewModels\CompositeKeyVm.cs" />
<Compile Include="ViewModels\Items\ListMenuItemVm.cs" />
<Compile Include="ViewModels\Items\MainMenuItemVm.cs" />
<Compile Include="ViewModels\Items\RecentItemVm.cs" />
<Compile Include="Views\EntryDetailPage.xaml.cs">
<DependentUpon>EntryDetailPage.xaml</DependentUpon>
</Compile>
@@ -165,14 +161,15 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ViewModels\EntryDetailVm.cs" />
<Compile Include="ViewModels\GroupDetailVm.cs" />
<Compile Include="ViewModels\Items\SettingsNewVm.cs" />
<Compile Include="ViewModels\SettingsVm.cs" />
<Compile Include="ViewModels\MainVm.cs" />
<Compile Include="ViewModels\NewVm.cs" />
<Compile Include="ViewModels\OpenVm.cs" />
<Compile Include="ViewModels\RecentVm.cs" />
<Compile Include="ViewModels\SaveVm.cs" />
<Compile Include="ViewModels\Items\SettingsDatabaseVm.cs" />
<Compile Include="Views\UserControls\OpenDatabaseUserControl.xaml.cs">
<DependentUpon>OpenDatabaseUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\HamburgerMenuUserControl.xaml.cs">
<DependentUpon>HamburgerMenuUserControl.xaml</DependentUpon>
</Compile>
@@ -182,6 +179,9 @@
<Compile Include="Views\UserControls\TopMenuUserControl.xaml.cs">
<DependentUpon>TopMenuUserControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\UserControls\UpdateCredentialsUserControl.xaml.cs">
<DependentUpon>UpdateCredentialsUserControl.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
@@ -314,6 +314,10 @@
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Views\UserControls\OpenDatabaseUserControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\UserControls\HamburgerMenuUserControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -326,6 +330,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\UserControls\UpdateCredentialsUserControl.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Reference Include="AutoMapper, Version=5.2.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">