mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Entry history delete and restore work
This commit is contained in:
@@ -258,4 +258,10 @@
|
||||
<data name="NewImportFormatHelpCSV" xml:space="preserve">
|
||||
<value>The CSV file needs to be formatted as such: Name of the account;Login;Password;URL;Comments</value>
|
||||
</data>
|
||||
<data name="HistoryDeleteDescription" xml:space="preserve">
|
||||
<value>Deleting this history entry will not delete current entry.</value>
|
||||
</data>
|
||||
<data name="HistoryDeleteTitle" xml:space="preserve">
|
||||
<value>Delete history entry ?</value>
|
||||
</data>
|
||||
</root>
|
@@ -258,4 +258,10 @@
|
||||
<data name="NewImportFormatHelpCSV" xml:space="preserve">
|
||||
<value>Le fichier CSV doit être formatté de la façon suivante: Nom du compte;Login;Mot de passe;URL;Commentaires</value>
|
||||
</data>
|
||||
<data name="HistoryDeleteDescription" xml:space="preserve">
|
||||
<value>Supprimer cet historique ne supprimera pas l'entrée en cours.</value>
|
||||
</data>
|
||||
<data name="HistoryDeleteTitle" xml:space="preserve">
|
||||
<value>Supprimer cet historique ?</value>
|
||||
</data>
|
||||
</root>
|
@@ -11,6 +11,7 @@ using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||
using ModernKeePass.Application.Database.Models;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
|
||||
using ModernKeePass.Application.Entry.Models;
|
||||
@@ -44,17 +45,42 @@ namespace ModernKeePass.ViewModels
|
||||
public bool SpecialPatternSelected { get; set; }
|
||||
public bool BracketsPatternSelected { get; set; }
|
||||
public string CustomChars { get; set; } = string.Empty;
|
||||
public string Id => _entry.Id;
|
||||
public string Id => SelectedItem.Id;
|
||||
|
||||
public bool IsRecycleOnDelete
|
||||
{
|
||||
get
|
||||
{
|
||||
var database = Database;
|
||||
return database.IsRecycleBinEnabled && _parent.Id != database.RecycleBinId;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<GroupVm> BreadCrumb => new List<GroupVm> { _parent };
|
||||
public ObservableCollection<EntryVm> History { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the Entry is current or from history
|
||||
/// </summary>
|
||||
public bool IsSelected
|
||||
public bool IsCurrentEntry => SelectedIndex == 0;
|
||||
|
||||
public EntryVm SelectedItem
|
||||
{
|
||||
get { return _isSelected; }
|
||||
set { SetProperty(ref _isSelected, value); }
|
||||
get { return _selectedItem; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _selectedItem, value);
|
||||
if (value != null) OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
public int SelectedIndex
|
||||
{
|
||||
get { return _selectedIndex; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _selectedIndex, value);
|
||||
OnPropertyChanged(nameof(IsCurrentEntry));
|
||||
}
|
||||
}
|
||||
|
||||
public double PasswordLength
|
||||
@@ -65,26 +91,26 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Title
|
||||
{
|
||||
get { return _entry.Title; }
|
||||
get { return SelectedItem.Title; }
|
||||
set
|
||||
{
|
||||
_entry.Title = value;
|
||||
SelectedItem.Title = value;
|
||||
SetFieldValue(nameof(Title), value).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get { return _entry.Username; }
|
||||
set { _entry.Username = value; }
|
||||
get { return SelectedItem.Username; }
|
||||
set { SelectedItem.Username = value; }
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get { return _entry.Password; }
|
||||
get { return SelectedItem.Password; }
|
||||
set
|
||||
{
|
||||
_entry.Password = value;
|
||||
SelectedItem.Password = value;
|
||||
SetFieldValue(nameof(Password), value).Wait();
|
||||
OnPropertyChanged(nameof(Password));
|
||||
OnPropertyChanged(nameof(PasswordComplexityIndicator));
|
||||
@@ -93,64 +119,64 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Url
|
||||
{
|
||||
get { return _entry.Url?.ToString(); }
|
||||
get { return SelectedItem.Url?.ToString(); }
|
||||
set
|
||||
{
|
||||
_entry.Url = new Uri(value);
|
||||
SelectedItem.Url = new Uri(value);
|
||||
SetFieldValue(nameof(Url), value).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get { return _entry.Notes; }
|
||||
get { return SelectedItem.Notes; }
|
||||
set
|
||||
{
|
||||
_entry.Notes = value;
|
||||
SelectedItem.Notes = value;
|
||||
SetFieldValue(nameof(Notes), value).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public Symbol Icon
|
||||
{
|
||||
get { return (Symbol)Enum.Parse(typeof(Symbol), _entry.Icon.ToString()); }
|
||||
get { return (Symbol)Enum.Parse(typeof(Symbol), SelectedItem.Icon.ToString()); }
|
||||
set
|
||||
{
|
||||
_entry.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString());
|
||||
SetFieldValue(nameof(Icon), _entry.Icon).Wait();
|
||||
SelectedItem.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString());
|
||||
SetFieldValue(nameof(Icon), SelectedItem.Icon).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset ExpiryDate
|
||||
{
|
||||
get { return _entry.ExpirationDate; }
|
||||
get { return SelectedItem.ExpirationDate; }
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
|
||||
_entry.ExpirationDate = value.Date;
|
||||
SetFieldValue("ExpirationDate", _entry.ExpirationDate).Wait();
|
||||
SelectedItem.ExpirationDate = value.Date;
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan ExpiryTime
|
||||
{
|
||||
get { return _entry.ExpirationDate.TimeOfDay; }
|
||||
get { return SelectedItem.ExpirationDate.TimeOfDay; }
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
|
||||
_entry.ExpirationDate = _entry.ExpirationDate.Date.Add(value);
|
||||
SetFieldValue("ExpirationDate", _entry.ExpirationDate).Wait();
|
||||
SelectedItem.ExpirationDate = SelectedItem.ExpirationDate.Date.Add(value);
|
||||
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasExpirationDate
|
||||
{
|
||||
get { return _entry.HasExpirationDate; }
|
||||
get { return SelectedItem.HasExpirationDate; }
|
||||
set
|
||||
{
|
||||
_entry.HasExpirationDate = value;
|
||||
SelectedItem.HasExpirationDate = value;
|
||||
SetFieldValue(nameof(HasExpirationDate), value).Wait();
|
||||
OnPropertyChanged(nameof(HasExpirationDate));
|
||||
}
|
||||
@@ -158,29 +184,28 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public SolidColorBrush BackgroundColor
|
||||
{
|
||||
get { return _entry?.BackgroundColor.ToSolidColorBrush(); }
|
||||
get { return SelectedItem?.BackgroundColor.ToSolidColorBrush(); }
|
||||
set
|
||||
{
|
||||
_entry.BackgroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(BackgroundColor), _entry.BackgroundColor).Wait();
|
||||
SelectedItem.BackgroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(BackgroundColor), SelectedItem.BackgroundColor).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public SolidColorBrush ForegroundColor
|
||||
{
|
||||
get { return _entry?.ForegroundColor.ToSolidColorBrush(); }
|
||||
get { return SelectedItem?.ForegroundColor.ToSolidColorBrush(); }
|
||||
set
|
||||
{
|
||||
_entry.ForegroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(ForegroundColor), _entry.ForegroundColor).Wait();
|
||||
SelectedItem.ForegroundColor = value.ToColor();
|
||||
SetFieldValue(nameof(ForegroundColor), SelectedItem.ForegroundColor).Wait();
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<EntryVm> History { get; }
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get { return IsSelected && _isEditMode; }
|
||||
get { return IsCurrentEntry && _isEditMode; }
|
||||
set { SetProperty(ref _isEditMode, value); }
|
||||
}
|
||||
|
||||
@@ -199,11 +224,12 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
private readonly IMediator _mediator;
|
||||
private readonly GroupVm _parent;
|
||||
private EntryVm _entry;
|
||||
private EntryVm _selectedItem;
|
||||
private int _selectedIndex;
|
||||
private bool _isEditMode;
|
||||
private bool _isRevealPassword;
|
||||
private double _passwordLength = 25;
|
||||
private bool _isSelected;
|
||||
private bool _isDirty;
|
||||
|
||||
public EntryDetailVm() { }
|
||||
|
||||
@@ -212,14 +238,14 @@ namespace ModernKeePass.ViewModels
|
||||
public EntryDetailVm(string entryId, IMediator mediator)
|
||||
{
|
||||
_mediator = mediator;
|
||||
_entry = _mediator.Send(new GetEntryQuery { Id = entryId }).GetAwaiter().GetResult();
|
||||
_parent = _mediator.Send(new GetGroupQuery { Id = _entry.ParentGroupId }).GetAwaiter().GetResult();
|
||||
History = new ObservableCollection<EntryVm> {_entry};
|
||||
foreach (var entry in _entry.History)
|
||||
SelectedItem = _mediator.Send(new GetEntryQuery { Id = entryId }).GetAwaiter().GetResult();
|
||||
_parent = _mediator.Send(new GetGroupQuery { Id = SelectedItem.ParentGroupId }).GetAwaiter().GetResult();
|
||||
History = new ObservableCollection<EntryVm> { SelectedItem };
|
||||
foreach (var entry in SelectedItem.History)
|
||||
{
|
||||
History.Add(entry);
|
||||
}
|
||||
IsSelected = true;
|
||||
SelectedIndex = 0;
|
||||
|
||||
SaveCommand = new RelayCommand(async () => await SaveChanges(), () => Database.IsDirty);
|
||||
GeneratePasswordCommand = new RelayCommand(async () => await GeneratePassword());
|
||||
@@ -247,41 +273,41 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public async Task MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
await _mediator.Send(new DeleteEntryCommand {EntryId = Id, ParentGroupId = _entry.ParentGroupId, RecycleBinName = recycleBinTitle});
|
||||
await _mediator.Send(new DeleteEntryCommand {EntryId = Id, ParentGroupId = SelectedItem.ParentGroupId, RecycleBinName = recycleBinTitle});
|
||||
}
|
||||
|
||||
public async Task Move(GroupVm destination)
|
||||
{
|
||||
await _mediator.Send(new AddEntryCommand { ParentGroup = destination, Entry = _entry });
|
||||
await _mediator.Send(new RemoveEntryCommand { ParentGroup = _parent, Entry = _entry });
|
||||
await _mediator.Send(new AddEntryCommand { ParentGroup = destination, Entry = SelectedItem });
|
||||
await _mediator.Send(new RemoveEntryCommand { ParentGroup = _parent, Entry = SelectedItem });
|
||||
}
|
||||
|
||||
public async Task SetFieldValue(string fieldName, object value)
|
||||
{
|
||||
await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
_entry.IsDirty = true;
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
public async Task AddHistory()
|
||||
{
|
||||
if (_entry.IsDirty) await _mediator.Send(new AddHistoryCommand { EntryId = Id });
|
||||
if (_isDirty) await _mediator.Send(new AddHistoryCommand { EntryId = Id });
|
||||
}
|
||||
|
||||
internal void SetEntry(EntryVm entry, int index)
|
||||
{
|
||||
_entry = entry;
|
||||
IsSelected = index == 0;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
|
||||
|
||||
private async Task RestoreHistory()
|
||||
{
|
||||
var index = History.IndexOf(_entry);
|
||||
var entryToRestore = History[index];
|
||||
SetEntry(entryToRestore, 0);
|
||||
await _mediator.Send(new RestoreHistoryCommand { EntryId = Id, HistoryIndex = index });
|
||||
History.Insert(0, entryToRestore);
|
||||
await _mediator.Send(new RestoreHistoryCommand { EntryId = Id, HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||
History.Insert(0, SelectedItem);
|
||||
SelectedIndex = 0;
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
public async Task DeleteHistory()
|
||||
{
|
||||
await _mediator.Send(new DeleteHistoryCommand { EntryId = Id, HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||
History.RemoveAt(SelectedIndex);
|
||||
SelectedIndex = 0;
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task SaveChanges()
|
||||
@@ -289,7 +315,7 @@ namespace ModernKeePass.ViewModels
|
||||
await AddHistory();
|
||||
await _mediator.Send(new SaveDatabaseCommand());
|
||||
((RelayCommand)SaveCommand).RaiseCanExecuteChanged();
|
||||
_entry.IsDirty = false;
|
||||
_isDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
|
@@ -388,7 +388,11 @@
|
||||
<ColumnDefinition Width="{StaticResource MenuGridLength}" x:Name="LeftListViewColumn" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<userControls:HamburgerMenuUserControl x:Uid="HistoryLeftListView" ItemsSource="{Binding History}" ResizeTarget="{Binding ElementName=LeftListViewColumn}" SelectionChanged="HamburgerMenuUserControl_OnSelectionChanged" />
|
||||
<userControls:HamburgerMenuUserControl x:Uid="HistoryLeftListView"
|
||||
ItemsSource="{Binding History}"
|
||||
ResizeTarget="{Binding ElementName=LeftListViewColumn}"
|
||||
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
|
||||
SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
|
||||
<Grid Grid.Column="1">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Margin="20,0,0,20">
|
||||
@@ -409,7 +413,7 @@
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
<TextBlock x:Uid="EntryLogin" />
|
||||
<local:TextBoxWithButton x:Uid="LoginTextBox" Text="{Binding UserName, Mode=TwoWay}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsSelected}">
|
||||
<local:TextBoxWithButton x:Uid="LoginTextBox" Text="{Binding UserName, Mode=TwoWay}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsCurrentEntry}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="ButtonClick">
|
||||
<actions:ClipboardAction Text="{Binding UserName}" />
|
||||
@@ -418,8 +422,8 @@
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</local:TextBoxWithButton>
|
||||
<TextBlock x:Uid="EntryPassword" />
|
||||
<PasswordBox HorizontalAlignment="Left" Password="{Binding Password, Mode=TwoWay}" Width="350" Height="32" IsPasswordRevealButtonEnabled="True" Visibility="{Binding IsRevealPassword, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource PasswordBoxWithButtonStyle}" IsEnabled="{Binding IsSelected}" />
|
||||
<local:TextBoxWithButton x:Uid="PasswordTextBox" Text="{Binding Password, Mode=TwoWay}" Visibility="{Binding IsRevealPassword, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsSelected}">
|
||||
<PasswordBox HorizontalAlignment="Left" Password="{Binding Password, Mode=TwoWay}" Width="350" Height="32" IsPasswordRevealButtonEnabled="True" Visibility="{Binding IsRevealPassword, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource PasswordBoxWithButtonStyle}" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
<local:TextBoxWithButton x:Uid="PasswordTextBox" Text="{Binding Password, Mode=TwoWay}" Visibility="{Binding IsRevealPassword, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsCurrentEntry}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="ButtonClick">
|
||||
<actions:ClipboardAction Text="{Binding Password}" />
|
||||
@@ -430,7 +434,7 @@
|
||||
<ProgressBar Value="{Binding PasswordComplexityIndicator, ConverterParameter=0\,128, Converter={StaticResource ProgressBarLegalValuesConverter}}" Maximum="128" Width="350" HorizontalAlignment="Left" Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroundBrushComplexityConverter}}" />
|
||||
<CheckBox x:Uid="EntryShowPassword" HorizontalAlignment="Left" Margin="-3,0,0,0" IsChecked="{Binding IsRevealPassword, Mode=TwoWay}" IsEnabled="{Binding IsRevealPasswordEnabled}" />
|
||||
<TextBlock TextWrapping="Wrap" Text="URL" FontSize="18"/>
|
||||
<local:TextBoxWithButton x:Uid="UrlTextBox" Text="{Binding Url, Mode=TwoWay}" MaxLength="256" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsSelected}">
|
||||
<local:TextBoxWithButton x:Uid="UrlTextBox" Text="{Binding Url, Mode=TwoWay}" MaxLength="256" Style="{StaticResource EntryTextBoxWithButtonStyle}" ButtonSymbol="" IsEnabled="{Binding IsCurrentEntry}">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="ButtonClick">
|
||||
<actions:NavigateToUrlAction Url="{Binding Url}" />
|
||||
@@ -438,8 +442,8 @@
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</local:TextBoxWithButton>
|
||||
<TextBlock x:Uid="EntryNotes" />
|
||||
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" IsEnabled="{Binding IsSelected}" />
|
||||
<CheckBox x:Uid="EntryExpirationDate" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
|
||||
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Notes, Mode=TwoWay}" Width="350" Height="200" AcceptsReturn="True" IsSpellCheckEnabled="True" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
<CheckBox x:Uid="EntryExpirationDate" IsChecked="{Binding HasExpirationDate, Mode=TwoWay}" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -458,11 +462,11 @@
|
||||
<StackPanel x:Name="EditDesign" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}" Orientation="Horizontal">
|
||||
<StackPanel Width="250" HorizontalAlignment="Left">
|
||||
<TextBlock x:Uid="EntryBackgroundColor" />
|
||||
<userControls:ColorPickerUserControl SelectedColor="{Binding BackgroundColor, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
|
||||
<userControls:ColorPickerUserControl SelectedColor="{Binding BackgroundColor, Mode=TwoWay}" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
</StackPanel>
|
||||
<StackPanel Width="250" HorizontalAlignment="Left">
|
||||
<TextBlock x:Uid="EntryForegroundColor" />
|
||||
<userControls:ColorPickerUserControl SelectedColor="{Binding ForegroundColor, Mode=TwoWay}" IsEnabled="{Binding IsSelected}" />
|
||||
<userControls:ColorPickerUserControl SelectedColor="{Binding ForegroundColor, Mode=TwoWay}" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
@@ -529,21 +533,16 @@
|
||||
<userControls:TopMenuUserControl
|
||||
x:Name="TopMenu" Grid.Column="2"
|
||||
IsEditButtonChecked="{Binding IsEditMode, Mode=TwoWay}"
|
||||
MoveButtonVisibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
RestoreButtonVisibility="{Binding IsSelected, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
|
||||
MoveButtonVisibility="{Binding IsCurrentEntry, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
RestoreButtonVisibility="{Binding IsCurrentEntry, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
|
||||
SaveCommand="{Binding SaveCommand}"
|
||||
MoveCommand="{Binding MoveCommand}"
|
||||
RestoreCommand="{Binding RestoreCommand}">
|
||||
RestoreCommand="{Binding RestoreCommand}"
|
||||
DeleteButtonClick="TopMenu_OnDeleteButtonClick">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="EditButtonClick">
|
||||
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="RestoreButtonClick">
|
||||
<core:ChangePropertyAction TargetObject="" />
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="DeleteButtonClick">
|
||||
<actions:DeleteEntityAction Entity="{Binding}" Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
|
||||
</core:EventTriggerBehavior>
|
||||
<core:EventTriggerBehavior EventName="MoveButtonClick">
|
||||
<core:InvokeCommandAction Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}" />
|
||||
<!--<actions:ToastAction x:Uid="RestoreEntryCommand" Title="{Binding Title}" />-->
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Models;
|
||||
@@ -22,7 +21,7 @@ namespace ModernKeePass.Views
|
||||
/// gestion de la durée de vie des processus
|
||||
/// </summary>
|
||||
public NavigationHelper NavigationHelper { get; }
|
||||
|
||||
|
||||
public EntryDetailPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -65,19 +64,35 @@ namespace ModernKeePass.Views
|
||||
VisualStateManager.GoToState(TopMenu, e.NewSize.Width < 800 ? "Collapsed" : "Overflowed", true);
|
||||
}
|
||||
|
||||
private void HamburgerMenuUserControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var listView = sender as ListView;
|
||||
if (listView == null) return;
|
||||
var index = listView.SelectedIndex;
|
||||
switch (index)
|
||||
var resource = new ResourceHelper();
|
||||
if (Model.IsCurrentEntry)
|
||||
{
|
||||
case -1:
|
||||
return;
|
||||
default:
|
||||
var entry = listView.SelectedItem as Application.Entry.Models.EntryVm;
|
||||
Model.SetEntry(entry, index);
|
||||
break;
|
||||
var isRecycleOnDelete = Model.IsRecycleOnDelete;
|
||||
|
||||
var message = isRecycleOnDelete
|
||||
? resource.GetResourceValue("EntryRecyclingConfirmation")
|
||||
: resource.GetResourceValue("EntryDeletingConfirmation");
|
||||
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
|
||||
resource.GetResourceValue("EntityDeleteActionButton"),
|
||||
resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
||||
{
|
||||
var text = isRecycleOnDelete ? resource.GetResourceValue("EntryRecycled") : resource.GetResourceValue("EntryDeleted");
|
||||
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
||||
await Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
||||
NavigationHelper.GoBack();
|
||||
}, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("HistoryDeleteTitle"), resource.GetResourceValue("HistoryDeleteDescription"),
|
||||
resource.GetResourceValue("EntityDeleteActionButton"),
|
||||
resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
||||
{
|
||||
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
||||
await Model.DeleteHistory();
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,8 @@
|
||||
<ListView
|
||||
ItemsSource="{Binding ItemsSource, ElementName=UserControl}"
|
||||
SelectionChanged="Selector_OnSelectionChanged"
|
||||
SelectedItem="{Binding SelectedItem, ElementName=UserControl}"
|
||||
SelectedItem="{Binding SelectedItem, ElementName=UserControl, Mode=TwoWay}"
|
||||
SelectedIndex="{Binding SelectedIndex, ElementName=UserControl, Mode=TwoWay}"
|
||||
IsSwipeEnabled="false"
|
||||
IsSynchronizedWithCurrentItem="False"
|
||||
RequestedTheme="Dark"
|
||||
|
@@ -100,6 +100,18 @@ namespace ModernKeePass.Views.UserControls
|
||||
typeof(HamburgerMenuUserControl),
|
||||
new PropertyMetadata(null, (o, args) => { }));
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
get { return (int)GetValue(SelectedIndexProperty); }
|
||||
set { SetValue(SelectedIndexProperty, value); }
|
||||
}
|
||||
public static readonly DependencyProperty SelectedIndexProperty =
|
||||
DependencyProperty.Register(
|
||||
nameof(SelectedIndex),
|
||||
typeof(int),
|
||||
typeof(HamburgerMenuUserControl),
|
||||
new PropertyMetadata(-1, (o, args) => { }));
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return (bool)GetValue(IsOpenProperty); }
|
||||
|
@@ -1,4 +1,5 @@
|
||||
Database corruption issues should now be a thing of the past !
|
||||
Added the ability to move entries and groups
|
||||
Edits are now in a popup instead of inline
|
||||
Allows restoring and deleting from entry history
|
||||
Updated KeePass lib to version 2.44
|
Reference in New Issue
Block a user