mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 07:30:15 -04:00
Attachment Add and Delete commands implemented
This commit is contained in:
@@ -88,7 +88,9 @@
|
||||
<Compile Include="Common\Interfaces\ISettingsProxy.cs" />
|
||||
<Compile Include="Common\Mappings\IMapFrom.cs" />
|
||||
<Compile Include="Common\Mappings\MappingProfile.cs" />
|
||||
<Compile Include="Entry\Commands\AddAttachment\AddAttachmentCommand.cs" />
|
||||
<Compile Include="Entry\Commands\AddHistory\AddHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteAttachment\DeleteAttachmentCommand.cs" />
|
||||
<Compile Include="Entry\Commands\DeleteHistory\DeleteHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Commands\RestoreHistory\RestoreHistoryCommand.cs" />
|
||||
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
|
||||
|
@@ -44,6 +44,8 @@ namespace ModernKeePass.Application.Common.Interfaces
|
||||
GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false);
|
||||
void SortEntries(string groupId);
|
||||
void SortSubGroups(string groupId);
|
||||
void AddAttachment(string entryId, string attachmentName, byte[] attachmentContent);
|
||||
void DeleteAttachment(string entryId, string attachmentName);
|
||||
|
||||
EntryEntity AddHistory(string entryId);
|
||||
EntryEntity RestoreFromHistory(string entryId, int historyIndex);
|
||||
|
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Entry.Models;
|
||||
using ModernKeePass.Domain.Exceptions;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Commands.AddAttachment
|
||||
{
|
||||
public class AddAttachmentCommand : IRequest
|
||||
{
|
||||
public EntryVm Entry { get; set; }
|
||||
public string AttachmentName { get; set; }
|
||||
public byte[] AttachmentContent { get; set; }
|
||||
|
||||
public class AddAttachmentCommandHandler : IRequestHandler<AddAttachmentCommand>
|
||||
{
|
||||
private readonly IDatabaseProxy _database;
|
||||
|
||||
public AddAttachmentCommandHandler(IDatabaseProxy database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Handle(AddAttachmentCommand message)
|
||||
{
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
||||
if (message.Entry.Attachments.ContainsKey(message.AttachmentName)) throw new ArgumentException("AttachmentAlreadyExists", nameof(message.AttachmentName));
|
||||
_database.AddAttachment(message.Entry.Id, message.AttachmentName, message.AttachmentContent);
|
||||
message.Entry.Attachments.Add(message.AttachmentName, message.AttachmentContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using MediatR;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Entry.Models;
|
||||
using ModernKeePass.Domain.Exceptions;
|
||||
|
||||
namespace ModernKeePass.Application.Entry.Commands.DeleteAttachment
|
||||
{
|
||||
public class DeleteAttachmentCommand : IRequest
|
||||
{
|
||||
public EntryVm Entry { get; set; }
|
||||
public string AttachmentName { get; set; }
|
||||
|
||||
public class DeleteAttachmentCommandHandler : IRequestHandler<DeleteAttachmentCommand>
|
||||
{
|
||||
private readonly IDatabaseProxy _database;
|
||||
|
||||
public DeleteAttachmentCommandHandler(IDatabaseProxy database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Handle(DeleteAttachmentCommand message)
|
||||
{
|
||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||
|
||||
if (!message.Entry.Attachments.ContainsKey(message.AttachmentName)) throw new KeyNotFoundException("AttachmentDoesntExist");
|
||||
_database.DeleteAttachment(message.Entry.Id, message.AttachmentName);
|
||||
message.Entry.Attachments.Remove(message.AttachmentName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -244,7 +244,7 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public EntryEntity AddHistory(string entryId)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
@@ -307,6 +307,18 @@ namespace ModernKeePass.Infrastructure.KeePass
|
||||
pwGroup.SortSubGroups(false);
|
||||
}
|
||||
|
||||
public void AddAttachment(string entryId, string attachmentName, byte[] attachmentContent)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
pwEntry.Binaries.Set(attachmentName, new ProtectedBinary(true, attachmentContent));
|
||||
}
|
||||
|
||||
public void DeleteAttachment(string entryId, string attachmentName)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||
pwEntry.Binaries.Remove(attachmentName);
|
||||
}
|
||||
|
||||
public EntryEntity GetEntry(string id)
|
||||
{
|
||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(id), true);
|
||||
|
@@ -531,4 +531,7 @@
|
||||
<data name="EntryIcon.Text" xml:space="preserve">
|
||||
<value>Icon</value>
|
||||
</data>
|
||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||
<value>Add attachment</value>
|
||||
</data>
|
||||
</root>
|
@@ -531,4 +531,7 @@
|
||||
<data name="EntryIcon.Text" xml:space="preserve">
|
||||
<value>Icone</value>
|
||||
</data>
|
||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||
<value>Ajouter une pièce jointe</value>
|
||||
</data>
|
||||
</root>
|
@@ -13,7 +13,9 @@ using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||
using ModernKeePass.Application.Database.Models;
|
||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||
using ModernKeePass.Application.Entry.Commands.AddAttachment;
|
||||
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteAttachment;
|
||||
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
||||
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
|
||||
@@ -90,6 +92,11 @@ namespace ModernKeePass.ViewModels
|
||||
Name = f.Key,
|
||||
Content = f.Value
|
||||
}));
|
||||
Attachments.CollectionChanged += (sender, args) =>
|
||||
{
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
_isDirty = true;
|
||||
};
|
||||
RaisePropertyChanged(string.Empty);
|
||||
}
|
||||
}
|
||||
@@ -102,6 +109,7 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
Set(() => SelectedIndex, ref _selectedIndex, value);
|
||||
RaisePropertyChanged(nameof(IsCurrentEntry));
|
||||
AddAttachmentCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,6 +259,8 @@ namespace ModernKeePass.ViewModels
|
||||
public RelayCommand GoBackCommand { get; }
|
||||
public RelayCommand GoToParentCommand { get; set; }
|
||||
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
|
||||
public RelayCommand AddAttachmentCommand { get; set; }
|
||||
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
|
||||
|
||||
private DatabaseVm Database => _mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||
|
||||
@@ -285,13 +295,15 @@ namespace ModernKeePass.ViewModels
|
||||
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
|
||||
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
|
||||
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
||||
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
||||
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment));
|
||||
|
||||
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task Initialize(string entryId)
|
||||
{
|
||||
SelectedIndex = 0;
|
||||
SelectedItem = await _mediator.Send(new GetEntryQuery { Id = entryId });
|
||||
_parent = await _mediator.Send(new GetGroupQuery { Id = SelectedItem.ParentGroupId });
|
||||
History = new ObservableCollection<EntryVm> { SelectedItem };
|
||||
@@ -299,7 +311,7 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
History.Add(entry);
|
||||
}
|
||||
SelectedIndex = 0;
|
||||
History.CollectionChanged += (sender, args) => SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task AskForDelete()
|
||||
@@ -333,7 +345,6 @@ namespace ModernKeePass.ViewModels
|
||||
await _mediator.Send(new DeleteHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||
History.RemoveAt(SelectedIndex);
|
||||
SelectedIndex = 0;
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -385,7 +396,6 @@ namespace ModernKeePass.ViewModels
|
||||
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||
History.Insert(0, SelectedItem);
|
||||
SelectedIndex = 0;
|
||||
SaveCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private async Task SaveChanges()
|
||||
@@ -424,5 +434,21 @@ namespace ModernKeePass.ViewModels
|
||||
if (fileInfo == null) return;
|
||||
await _file.WriteBinaryContentsToFile(fileInfo.Id, attachment.Content);
|
||||
}
|
||||
|
||||
private async Task AddAttachment()
|
||||
{
|
||||
var fileInfo = await _file.OpenFile(string.Empty, Domain.Common.Constants.Extensions.Any, false);
|
||||
if (fileInfo == null) return;
|
||||
var contents = await _file.ReadBinaryFile(fileInfo.Id);
|
||||
await _mediator.Send(new AddAttachmentCommand { Entry = SelectedItem, AttachmentName = fileInfo.Name, AttachmentContent = contents });
|
||||
Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents });
|
||||
}
|
||||
|
||||
private async Task DeleteAttachment(Attachment attachment)
|
||||
{
|
||||
await _mediator.Send(new DeleteAttachmentCommand { Entry = SelectedItem, AttachmentName = attachment.Name });
|
||||
Attachments.Remove(attachment);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public MainVm Main => ServiceLocator.Current.GetInstance<MainVm>(Guid.NewGuid().ToString());
|
||||
public SettingsVm Settings => ServiceLocator.Current.GetInstance<SettingsVm>(Guid.NewGuid().ToString());
|
||||
public GroupDetailVm Group => ServiceLocator.Current.GetInstance<GroupDetailVm>();
|
||||
public EntryDetailVm Entry => ServiceLocator.Current.GetInstance<EntryDetailVm>();
|
||||
public GroupDetailVm Group => ServiceLocator.Current.GetInstance<GroupDetailVm>(Guid.NewGuid().ToString());
|
||||
public EntryDetailVm Entry => ServiceLocator.Current.GetInstance<EntryDetailVm>(Guid.NewGuid().ToString());
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
<Page
|
||||
<Page x:Name="Page"
|
||||
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"
|
||||
@@ -488,7 +488,7 @@
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock x:Uid="EntryIcon" Style="{StaticResource EntryTextBlockStyle}" />
|
||||
<userControls:SymbolPickerUserControl SelectedSymbol="{Binding Icon, Mode=TwoWay}" HorizontalAlignment="Left" />
|
||||
<userControls:SymbolPickerUserControl SelectedSymbol="{Binding Icon, Mode=TwoWay}" HorizontalAlignment="Left" IsEnabled="{Binding IsCurrentEntry}" />
|
||||
<TextBlock x:Uid="EntryBackgroundColor" Style="{StaticResource EntryTextBlockStyle}" />
|
||||
<userControls:ColorPickerUserControl SelectedColor="{Binding BackgroundColor, Mode=TwoWay}" IsEnabled="{Binding IsCurrentEntry}" Width="350" />
|
||||
<TextBlock x:Uid="EntryForegroundColor" Style="{StaticResource EntryTextBlockStyle}" />
|
||||
@@ -499,15 +499,31 @@
|
||||
<HubSection x:Uid="EntryHubAttachments" IsHeaderInteractive="True">
|
||||
<DataTemplate>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding Attachments}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<HyperlinkButton Content="{Binding Name}" Command="{Binding Source={StaticResource Locator}, Path=Entry.OpenAttachmentCommand}" CommandParameter="{Binding}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<HyperlinkButton Command="{Binding Path=DataContext.AddAttachmentCommand, ElementName=Page}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<SymbolIcon Symbol="Attach" />
|
||||
<TextBlock x:Uid="EntryAddAttachment" VerticalAlignment="Center" Margin="10,0,0,0" />
|
||||
</StackPanel>
|
||||
</HyperlinkButton>
|
||||
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
|
||||
<ItemsControl ItemsSource="{Binding Attachments}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<HyperlinkButton Content="{Binding Name}" Command="{Binding Path=DataContext.OpenAttachmentCommand, ElementName=Page}" CommandParameter="{Binding}" />
|
||||
<HyperlinkButton Grid.Column="1" Margin="10,0,0,0" HorizontalAlignment="Right" Command="{Binding Path=DataContext.DeleteAttachmentCommand, ElementName=Page}" CommandParameter="{Binding}">
|
||||
<SymbolIcon Symbol="Delete" />
|
||||
</HyperlinkButton>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</DataTemplate>
|
||||
</HubSection>
|
||||
|
Reference in New Issue
Block a user