mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Additional fields Add, Update and Delete work (too well)
SelectableListView works when programmatically setting selection
This commit is contained in:
@@ -91,6 +91,7 @@
|
|||||||
<Compile Include="Entry\Commands\AddAttachment\AddAttachmentCommand.cs" />
|
<Compile Include="Entry\Commands\AddAttachment\AddAttachmentCommand.cs" />
|
||||||
<Compile Include="Entry\Commands\AddHistory\AddHistoryCommand.cs" />
|
<Compile Include="Entry\Commands\AddHistory\AddHistoryCommand.cs" />
|
||||||
<Compile Include="Entry\Commands\DeleteAttachment\DeleteAttachmentCommand.cs" />
|
<Compile Include="Entry\Commands\DeleteAttachment\DeleteAttachmentCommand.cs" />
|
||||||
|
<Compile Include="Entry\Commands\DeleteField\DeleteFieldCommand.cs" />
|
||||||
<Compile Include="Entry\Commands\DeleteHistory\DeleteHistoryCommand.cs" />
|
<Compile Include="Entry\Commands\DeleteHistory\DeleteHistoryCommand.cs" />
|
||||||
<Compile Include="Entry\Commands\RestoreHistory\RestoreHistoryCommand.cs" />
|
<Compile Include="Entry\Commands\RestoreHistory\RestoreHistoryCommand.cs" />
|
||||||
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
|
<Compile Include="Entry\Queries\GetEntry\GetEntryQuery.cs" />
|
||||||
@@ -121,8 +122,8 @@
|
|||||||
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQueryValidator.cs" />
|
<Compile Include="Database\Queries\OpenDatabase\OpenDatabaseQueryValidator.cs" />
|
||||||
<Compile Include="Database\Queries\ReOpenDatabase\ReOpenDatabaseQuery.cs" />
|
<Compile Include="Database\Queries\ReOpenDatabase\ReOpenDatabaseQuery.cs" />
|
||||||
<Compile Include="DependencyInjection.cs" />
|
<Compile Include="DependencyInjection.cs" />
|
||||||
<Compile Include="Entry\Commands\SetFieldValue\SetFieldValueCommand.cs" />
|
<Compile Include="Entry\Commands\UpsertField\UpsertFieldCommand.cs" />
|
||||||
<Compile Include="Entry\Commands\SetFieldValue\SetFieldValueCommandValidator.cs" />
|
<Compile Include="Entry\Commands\UpsertField\UpsertFieldCommandValidator.cs" />
|
||||||
<Compile Include="Entry\Models\EntryVm.cs" />
|
<Compile Include="Entry\Models\EntryVm.cs" />
|
||||||
<Compile Include="Group\Commands\AddEntry\AddEntryCommand.cs" />
|
<Compile Include="Group\Commands\AddEntry\AddEntryCommand.cs" />
|
||||||
<Compile Include="Group\Commands\AddGroup\AddGroupCommand.cs" />
|
<Compile Include="Group\Commands\AddGroup\AddGroupCommand.cs" />
|
||||||
|
@@ -31,19 +31,22 @@ namespace ModernKeePass.Application.Common.Interfaces
|
|||||||
void CloseDatabase();
|
void CloseDatabase();
|
||||||
|
|
||||||
EntryEntity GetEntry(string id);
|
EntryEntity GetEntry(string id);
|
||||||
GroupEntity GetGroup(string id);
|
|
||||||
Task AddEntry(string parentGroupId, string entryId);
|
Task AddEntry(string parentGroupId, string entryId);
|
||||||
Task MoveEntry(string parentGroupId, string entryId, int index);
|
Task MoveEntry(string parentGroupId, string entryId, int index);
|
||||||
Task AddGroup(string parentGroupId, string groupId);
|
|
||||||
void UpdateEntry(string entryId, string fieldName, object fieldValue);
|
void UpdateEntry(string entryId, string fieldName, object fieldValue);
|
||||||
void UpdateGroup(GroupEntity group);
|
void DeleteField(string entryId, string fieldName);
|
||||||
Task RemoveEntry(string parentGroupId, string entryId);
|
Task RemoveEntry(string parentGroupId, string entryId);
|
||||||
|
EntryEntity CreateEntry(string parentGroupId);
|
||||||
|
void SortEntries(string groupId);
|
||||||
|
|
||||||
|
GroupEntity GetGroup(string id);
|
||||||
|
Task AddGroup(string parentGroupId, string groupId);
|
||||||
|
void UpdateGroup(GroupEntity group);
|
||||||
Task RemoveGroup(string parentGroupId, string groupId);
|
Task RemoveGroup(string parentGroupId, string groupId);
|
||||||
void DeleteEntity(string entityId);
|
void DeleteEntity(string entityId);
|
||||||
EntryEntity CreateEntry(string parentGroupId);
|
|
||||||
GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false);
|
GroupEntity CreateGroup(string parentGroupId, string name, bool isRecycleBin = false);
|
||||||
void SortEntries(string groupId);
|
|
||||||
void SortSubGroups(string groupId);
|
void SortSubGroups(string groupId);
|
||||||
|
|
||||||
void AddAttachment(string entryId, string attachmentName, byte[] attachmentContent);
|
void AddAttachment(string entryId, string attachmentName, byte[] attachmentContent);
|
||||||
void DeleteAttachment(string entryId, string attachmentName);
|
void DeleteAttachment(string entryId, string attachmentName);
|
||||||
|
|
||||||
|
@@ -0,0 +1,29 @@
|
|||||||
|
using MediatR;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
|
using ModernKeePass.Domain.Exceptions;
|
||||||
|
|
||||||
|
namespace ModernKeePass.Application.Entry.Commands.DeleteField
|
||||||
|
{
|
||||||
|
public class DeleteFieldCommand: IRequest
|
||||||
|
{
|
||||||
|
public string EntryId { get; set; }
|
||||||
|
public string FieldName { get; set; }
|
||||||
|
|
||||||
|
public class DeleteFieldCommandHandler : IRequestHandler<DeleteFieldCommand>
|
||||||
|
{
|
||||||
|
private readonly IDatabaseProxy _database;
|
||||||
|
|
||||||
|
public DeleteFieldCommandHandler(IDatabaseProxy database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(DeleteFieldCommand message)
|
||||||
|
{
|
||||||
|
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||||
|
|
||||||
|
_database.DeleteField(message.EntryId, message.FieldName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -2,24 +2,24 @@
|
|||||||
using ModernKeePass.Application.Common.Interfaces;
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Domain.Exceptions;
|
using ModernKeePass.Domain.Exceptions;
|
||||||
|
|
||||||
namespace ModernKeePass.Application.Entry.Commands.SetFieldValue
|
namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||||
{
|
{
|
||||||
public class SetFieldValueCommand : IRequest
|
public class UpsertFieldCommand : IRequest
|
||||||
{
|
{
|
||||||
public string EntryId { get; set; }
|
public string EntryId { get; set; }
|
||||||
public string FieldName { get; set; }
|
public string FieldName { get; set; }
|
||||||
public object FieldValue { get; set; }
|
public object FieldValue { get; set; }
|
||||||
|
|
||||||
public class SetFieldValueCommandHandler : IRequestHandler<SetFieldValueCommand>
|
public class UpsertFieldCommandHandler : IRequestHandler<UpsertFieldCommand>
|
||||||
{
|
{
|
||||||
private readonly IDatabaseProxy _database;
|
private readonly IDatabaseProxy _database;
|
||||||
|
|
||||||
public SetFieldValueCommandHandler(IDatabaseProxy database)
|
public UpsertFieldCommandHandler(IDatabaseProxy database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(SetFieldValueCommand message)
|
public void Handle(UpsertFieldCommand message)
|
||||||
{
|
{
|
||||||
if (!_database.IsOpen) throw new DatabaseClosedException();
|
if (!_database.IsOpen) throw new DatabaseClosedException();
|
||||||
|
|
@@ -1,10 +1,10 @@
|
|||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
|
||||||
namespace ModernKeePass.Application.Entry.Commands.SetFieldValue
|
namespace ModernKeePass.Application.Entry.Commands.UpsertField
|
||||||
{
|
{
|
||||||
public class SetFieldValueCommandValidator: AbstractValidator<SetFieldValueCommand>
|
public class UpsertFieldCommandValidator: AbstractValidator<UpsertFieldCommand>
|
||||||
{
|
{
|
||||||
public SetFieldValueCommandValidator()
|
public UpsertFieldCommandValidator()
|
||||||
{
|
{
|
||||||
RuleFor(v => v.EntryId)
|
RuleFor(v => v.EntryId)
|
||||||
.NotNull()
|
.NotNull()
|
@@ -78,7 +78,6 @@
|
|||||||
<Compile Include="Common\Constants.cs" />
|
<Compile Include="Common\Constants.cs" />
|
||||||
<Compile Include="Dtos\Attachment.cs" />
|
<Compile Include="Dtos\Attachment.cs" />
|
||||||
<Compile Include="Dtos\Credentials.cs" />
|
<Compile Include="Dtos\Credentials.cs" />
|
||||||
<Compile Include="Dtos\Field.cs" />
|
|
||||||
<Compile Include="Dtos\FileInfo.cs" />
|
<Compile Include="Dtos\FileInfo.cs" />
|
||||||
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
<Compile Include="Dtos\PasswordGenerationOptions.cs" />
|
||||||
<Compile Include="Entities\BaseEntity.cs" />
|
<Compile Include="Entities\BaseEntity.cs" />
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
namespace ModernKeePass.Domain.Dtos
|
|
||||||
{
|
|
||||||
public class Field
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string Value { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@@ -242,9 +242,18 @@ namespace ModernKeePass.Infrastructure.KeePass
|
|||||||
case EntryFieldName.ForegroundColor:
|
case EntryFieldName.ForegroundColor:
|
||||||
pwEntry.ForegroundColor = (Color)fieldValue;
|
pwEntry.ForegroundColor = (Color)fieldValue;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
pwEntry.Strings.Set(fieldName, new ProtectedString(true, fieldValue.ToString()));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteField(string entryId, string fieldName)
|
||||||
|
{
|
||||||
|
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||||
|
pwEntry.Strings.Remove(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
public EntryEntity AddHistory(string entryId)
|
public EntryEntity AddHistory(string entryId)
|
||||||
{
|
{
|
||||||
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
var pwEntry = _pwDatabase.RootGroup.FindEntry(BuildIdFromString(entryId), true);
|
||||||
|
@@ -534,4 +534,10 @@
|
|||||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||||
<value>Add attachment</value>
|
<value>Add attachment</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
|
||||||
|
<value>Add field</value>
|
||||||
|
</data>
|
||||||
|
<data name="EntryDeleteAdditionalField.Content" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@@ -276,4 +276,7 @@
|
|||||||
<data name="CompositeKeyFileNameSuggestion" xml:space="preserve">
|
<data name="CompositeKeyFileNameSuggestion" xml:space="preserve">
|
||||||
<value>Clé</value>
|
<value>Clé</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
|
||||||
|
<value>Ajouter un champ</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@@ -534,4 +534,7 @@
|
|||||||
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
<data name="EntryAddAttachment.Text" xml:space="preserve">
|
||||||
<value>Ajouter une pièce jointe</value>
|
<value>Ajouter une pièce jointe</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EntryDeleteAdditionalField.Content" xml:space="preserve">
|
||||||
|
<value>Supprimer</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@@ -16,9 +16,10 @@ using ModernKeePass.Application.Database.Queries.GetDatabase;
|
|||||||
using ModernKeePass.Application.Entry.Commands.AddAttachment;
|
using ModernKeePass.Application.Entry.Commands.AddAttachment;
|
||||||
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
using ModernKeePass.Application.Entry.Commands.AddHistory;
|
||||||
using ModernKeePass.Application.Entry.Commands.DeleteAttachment;
|
using ModernKeePass.Application.Entry.Commands.DeleteAttachment;
|
||||||
|
using ModernKeePass.Application.Entry.Commands.DeleteField;
|
||||||
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
using ModernKeePass.Application.Entry.Commands.DeleteHistory;
|
||||||
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
using ModernKeePass.Application.Entry.Commands.RestoreHistory;
|
||||||
using ModernKeePass.Application.Entry.Commands.SetFieldValue;
|
using ModernKeePass.Application.Entry.Commands.UpsertField;
|
||||||
using ModernKeePass.Application.Entry.Models;
|
using ModernKeePass.Application.Entry.Models;
|
||||||
using ModernKeePass.Application.Entry.Queries.GetEntry;
|
using ModernKeePass.Application.Entry.Queries.GetEntry;
|
||||||
using ModernKeePass.Application.Group.Commands.AddEntry;
|
using ModernKeePass.Application.Group.Commands.AddEntry;
|
||||||
@@ -34,6 +35,7 @@ using ModernKeePass.Domain.Dtos;
|
|||||||
using ModernKeePass.Domain.Exceptions;
|
using ModernKeePass.Domain.Exceptions;
|
||||||
using ModernKeePass.Extensions;
|
using ModernKeePass.Extensions;
|
||||||
using ModernKeePass.Models;
|
using ModernKeePass.Models;
|
||||||
|
using ModernKeePass.ViewModels.ListItems;
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
@@ -66,7 +68,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ObservableCollection<EntryVm> History { get; private set; }
|
public ObservableCollection<EntryVm> History { get; private set; }
|
||||||
public ObservableCollection<Field> AdditionalFields { get; private set; }
|
public ObservableCollection<FieldVm> AdditionalFields { get; private set; }
|
||||||
public ObservableCollection<Attachment> Attachments { get; private set; }
|
public ObservableCollection<Attachment> Attachments { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -82,11 +84,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
Set(() => SelectedItem, ref _selectedItem, value, true);
|
Set(() => SelectedItem, ref _selectedItem, value, true);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
AdditionalFields = new ObservableCollection<Field>(SelectedItem.AdditionalFields.Select(f => new Field
|
AdditionalFields =
|
||||||
{
|
new ObservableCollection<FieldVm>(
|
||||||
Name = f.Key,
|
SelectedItem.AdditionalFields.Select(f => new FieldVm(f.Key, f.Value)));
|
||||||
Value = f.Value
|
|
||||||
}));
|
|
||||||
Attachments = new ObservableCollection<Attachment>(SelectedItem.Attachments.Select(f => new Attachment
|
Attachments = new ObservableCollection<Attachment>(SelectedItem.Attachments.Select(f => new Attachment
|
||||||
{
|
{
|
||||||
Name = f.Key,
|
Name = f.Key,
|
||||||
@@ -113,6 +113,16 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int AdditionalFieldSelectedIndex
|
||||||
|
{
|
||||||
|
get { return _additionalFieldSelectedIndex; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Set(() => AdditionalFieldSelectedIndex, ref _additionalFieldSelectedIndex, value);
|
||||||
|
DeleteAdditionalField.RaiseCanExecuteChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public double PasswordLength
|
public double PasswordLength
|
||||||
{
|
{
|
||||||
get { return _passwordLength; }
|
get { return _passwordLength; }
|
||||||
@@ -258,6 +268,8 @@ namespace ModernKeePass.ViewModels
|
|||||||
public RelayCommand DeleteCommand { get; }
|
public RelayCommand DeleteCommand { get; }
|
||||||
public RelayCommand GoBackCommand { get; }
|
public RelayCommand GoBackCommand { get; }
|
||||||
public RelayCommand GoToParentCommand { get; set; }
|
public RelayCommand GoToParentCommand { get; set; }
|
||||||
|
public RelayCommand AddAdditionalField { get; set; }
|
||||||
|
public RelayCommand<FieldVm> DeleteAdditionalField { get; set; }
|
||||||
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
|
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
|
||||||
public RelayCommand AddAttachmentCommand { get; set; }
|
public RelayCommand AddAttachmentCommand { get; set; }
|
||||||
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
|
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
|
||||||
@@ -273,6 +285,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
private GroupVm _parent;
|
private GroupVm _parent;
|
||||||
private EntryVm _selectedItem;
|
private EntryVm _selectedItem;
|
||||||
private int _selectedIndex;
|
private int _selectedIndex;
|
||||||
|
private int _additionalFieldSelectedIndex;
|
||||||
private bool _isEditMode;
|
private bool _isEditMode;
|
||||||
private bool _isRevealPassword;
|
private bool _isRevealPassword;
|
||||||
private double _passwordLength = 25;
|
private double _passwordLength = 25;
|
||||||
@@ -294,11 +307,15 @@ namespace ModernKeePass.ViewModels
|
|||||||
DeleteCommand = new RelayCommand(async () => await AskForDelete());
|
DeleteCommand = new RelayCommand(async () => await AskForDelete());
|
||||||
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
|
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
|
||||||
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
|
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
|
||||||
|
AddAdditionalField = new RelayCommand(AddField);
|
||||||
|
DeleteAdditionalField = new RelayCommand<FieldVm>(async field => await DeleteField(field), field => field != null);
|
||||||
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
|
||||||
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
|
||||||
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment));
|
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment));
|
||||||
|
|
||||||
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
|
||||||
|
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue));
|
||||||
|
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Initialize(string entryId)
|
public async Task Initialize(string entryId)
|
||||||
@@ -314,6 +331,70 @@ namespace ModernKeePass.ViewModels
|
|||||||
History.CollectionChanged += (sender, args) => SaveCommand.RaiseCanExecuteChanged();
|
History.CollectionChanged += (sender, args) => SaveCommand.RaiseCanExecuteChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task GeneratePassword()
|
||||||
|
{
|
||||||
|
Password = await _mediator.Send(new GeneratePasswordCommand
|
||||||
|
{
|
||||||
|
BracketsPatternSelected = BracketsPatternSelected,
|
||||||
|
CustomChars = CustomChars,
|
||||||
|
DigitsPatternSelected = DigitsPatternSelected,
|
||||||
|
LowerCasePatternSelected = LowerCasePatternSelected,
|
||||||
|
MinusPatternSelected = MinusPatternSelected,
|
||||||
|
PasswordLength = (int)PasswordLength,
|
||||||
|
SpacePatternSelected = SpacePatternSelected,
|
||||||
|
SpecialPatternSelected = SpecialPatternSelected,
|
||||||
|
UnderscorePatternSelected = UnderscorePatternSelected,
|
||||||
|
UpperCasePatternSelected = UpperCasePatternSelected
|
||||||
|
});
|
||||||
|
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
|
||||||
|
}
|
||||||
|
public async Task AddHistory()
|
||||||
|
{
|
||||||
|
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GoToGroup(string groupId)
|
||||||
|
{
|
||||||
|
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = groupId });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Move(string destination)
|
||||||
|
{
|
||||||
|
await _mediator.Send(new AddEntryCommand { ParentGroupId = destination, EntryId = Id });
|
||||||
|
await _mediator.Send(new RemoveEntryCommand { ParentGroupId = _parent.Id, EntryId = Id });
|
||||||
|
GoToGroup(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SetFieldValue(string fieldName, object value)
|
||||||
|
{
|
||||||
|
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
_isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateFieldName(string oldName, string newName, string value)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(oldName)) await _mediator.Send(new DeleteFieldCommand { EntryId = Id, FieldName = oldName });
|
||||||
|
await SetFieldValue(newName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddField()
|
||||||
|
{
|
||||||
|
AdditionalFields.Add(new FieldVm(string.Empty, string.Empty));
|
||||||
|
AdditionalFieldSelectedIndex = AdditionalFields.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteField(FieldVm field)
|
||||||
|
{
|
||||||
|
AdditionalFields.Remove(field);
|
||||||
|
if (!string.IsNullOrEmpty(field.Name))
|
||||||
|
{
|
||||||
|
await _mediator.Send(new DeleteFieldCommand {EntryId = Id, FieldName = field.Name});
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
_isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task AskForDelete()
|
private async Task AskForDelete()
|
||||||
{
|
{
|
||||||
if (IsCurrentEntry)
|
if (IsCurrentEntry)
|
||||||
@@ -349,48 +430,6 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task GeneratePassword()
|
|
||||||
{
|
|
||||||
Password = await _mediator.Send(new GeneratePasswordCommand
|
|
||||||
{
|
|
||||||
BracketsPatternSelected = BracketsPatternSelected,
|
|
||||||
CustomChars = CustomChars,
|
|
||||||
DigitsPatternSelected = DigitsPatternSelected,
|
|
||||||
LowerCasePatternSelected = LowerCasePatternSelected,
|
|
||||||
MinusPatternSelected = MinusPatternSelected,
|
|
||||||
PasswordLength = (int)PasswordLength,
|
|
||||||
SpacePatternSelected = SpacePatternSelected,
|
|
||||||
SpecialPatternSelected = SpecialPatternSelected,
|
|
||||||
UnderscorePatternSelected = UnderscorePatternSelected,
|
|
||||||
UpperCasePatternSelected = UpperCasePatternSelected
|
|
||||||
});
|
|
||||||
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Move(string destination)
|
|
||||||
{
|
|
||||||
await _mediator.Send(new AddEntryCommand { ParentGroupId = destination, EntryId = Id });
|
|
||||||
await _mediator.Send(new RemoveEntryCommand { ParentGroupId = _parent.Id, EntryId = Id });
|
|
||||||
GoToGroup(destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SetFieldValue(string fieldName, object value)
|
|
||||||
{
|
|
||||||
await _mediator.Send(new SetFieldValueCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
|
|
||||||
SaveCommand.RaiseCanExecuteChanged();
|
|
||||||
_isDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddHistory()
|
|
||||||
{
|
|
||||||
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GoToGroup(string groupId)
|
|
||||||
{
|
|
||||||
_navigation.NavigateTo(Constants.Navigation.GroupPage, new NavigationItem { Id = groupId });
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task RestoreHistory()
|
private async Task RestoreHistory()
|
||||||
{
|
{
|
||||||
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 });
|
await _mediator.Send(new RestoreHistoryCommand { Entry = History[0], HistoryIndex = History.Count - SelectedIndex - 1 });
|
||||||
@@ -442,12 +481,16 @@ namespace ModernKeePass.ViewModels
|
|||||||
var contents = await _file.ReadBinaryFile(fileInfo.Id);
|
var contents = await _file.ReadBinaryFile(fileInfo.Id);
|
||||||
await _mediator.Send(new AddAttachmentCommand { Entry = SelectedItem, AttachmentName = fileInfo.Name, AttachmentContent = contents });
|
await _mediator.Send(new AddAttachmentCommand { Entry = SelectedItem, AttachmentName = fileInfo.Name, AttachmentContent = contents });
|
||||||
Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents });
|
Attachments.Add(new Attachment { Name = fileInfo.Name, Content = contents });
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
_isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteAttachment(Attachment attachment)
|
private async Task DeleteAttachment(Attachment attachment)
|
||||||
{
|
{
|
||||||
await _mediator.Send(new DeleteAttachmentCommand { Entry = SelectedItem, AttachmentName = attachment.Name });
|
await _mediator.Send(new DeleteAttachmentCommand { Entry = SelectedItem, AttachmentName = attachment.Name });
|
||||||
Attachments.Remove(attachment);
|
Attachments.Remove(attachment);
|
||||||
|
SaveCommand.RaiseCanExecuteChanged();
|
||||||
|
_isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -482,8 +482,17 @@
|
|||||||
</HubSection>
|
</HubSection>
|
||||||
<HubSection x:Uid="EntryHubAdditional">
|
<HubSection x:Uid="EntryHubAdditional">
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<SymbolIcon Symbol="Add" />
|
||||||
|
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
|
||||||
|
</StackPanel>
|
||||||
|
</HyperlinkButton>
|
||||||
|
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
|
||||||
<local:SelectableTemplateListView
|
<local:SelectableTemplateListView
|
||||||
ItemsSource="{Binding AdditionalFields}"
|
ItemsSource="{Binding AdditionalFields}"
|
||||||
|
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
|
||||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||||
<local:SelectableTemplateListView.SelectedItemTemplate>
|
<local:SelectableTemplateListView.SelectedItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
@@ -493,6 +502,7 @@
|
|||||||
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350"
|
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350"
|
||||||
Text="{Binding Value, Mode=TwoWay}"
|
Text="{Binding Value, Mode=TwoWay}"
|
||||||
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
|
||||||
|
<Button x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</local:SelectableTemplateListView.SelectedItemTemplate>
|
</local:SelectableTemplateListView.SelectedItemTemplate>
|
||||||
@@ -505,6 +515,7 @@
|
|||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</local:SelectableTemplateListView.ItemTemplate>
|
</local:SelectableTemplateListView.ItemTemplate>
|
||||||
</local:SelectableTemplateListView>
|
</local:SelectableTemplateListView>
|
||||||
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</HubSection>
|
</HubSection>
|
||||||
<HubSection x:Uid="EntryHubAttachments" Foreground="{StaticResource HubSectionBrush}">
|
<HubSection x:Uid="EntryHubAttachments" Foreground="{StaticResource HubSectionBrush}">
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</HyperlinkButton>
|
</HyperlinkButton>
|
||||||
<controls:SelectableTemplateListView Grid.Row="1"
|
<controls:SelectableTemplateListView Grid.Row="1"
|
||||||
|
SelectedIndex="{Binding SelectedIndex}"
|
||||||
ItemsSource="{Binding RecentItems}"
|
ItemsSource="{Binding RecentItems}"
|
||||||
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
|
||||||
<controls:SelectableTemplateListView.SelectedItemTemplate>
|
<controls:SelectableTemplateListView.SelectedItemTemplate>
|
||||||
|
@@ -19,9 +19,17 @@ namespace ModernKeePass.Controls
|
|||||||
|
|
||||||
public SelectableTemplateListView()
|
public SelectableTemplateListView()
|
||||||
{
|
{
|
||||||
|
ContainerContentChanging += SelectableTemplateListView_ContainerContentChanging;
|
||||||
SelectionChanged += SelectableTemplateListView_SelectionChanged;
|
SelectionChanged += SelectableTemplateListView_SelectionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectableTemplateListView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
|
||||||
|
{
|
||||||
|
args.ItemContainer.ContentTemplate = args.ItemContainer.IsSelected
|
||||||
|
? SelectedItemTemplate
|
||||||
|
: ItemTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
private void SelectableTemplateListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void SelectableTemplateListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var listView = sender as ListView;
|
var listView = sender as ListView;
|
||||||
|
9
WinAppCommon/Messages/EntryFieldNameChangedMessage.cs
Normal file
9
WinAppCommon/Messages/EntryFieldNameChangedMessage.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Messages
|
||||||
|
{
|
||||||
|
public class EntryFieldNameChangedMessage
|
||||||
|
{
|
||||||
|
public string OldName { get; set; }
|
||||||
|
public string NewName { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
8
WinAppCommon/Messages/EntryFieldValueChangedMessage.cs
Normal file
8
WinAppCommon/Messages/EntryFieldValueChangedMessage.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Messages
|
||||||
|
{
|
||||||
|
public class EntryFieldValueChangedMessage
|
||||||
|
{
|
||||||
|
public string FieldName { get; set; }
|
||||||
|
public string FieldValue { get; set; }
|
||||||
|
}
|
||||||
|
}
|
37
WinAppCommon/ViewModels/Items/FieldVm.cs
Normal file
37
WinAppCommon/ViewModels/Items/FieldVm.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using GalaSoft.MvvmLight;
|
||||||
|
using Messages;
|
||||||
|
|
||||||
|
namespace ModernKeePass.ViewModels.ListItems
|
||||||
|
{
|
||||||
|
public class FieldVm: ViewModelBase
|
||||||
|
{
|
||||||
|
private string _name;
|
||||||
|
private string _value;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return _name; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
MessengerInstance.Send(new EntryFieldNameChangedMessage { OldName = Name, NewName = value, Value = Value });
|
||||||
|
Set(nameof(Name), ref _name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Value
|
||||||
|
{
|
||||||
|
get { return _value; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
MessengerInstance.Send(new EntryFieldValueChangedMessage { FieldName = Name, FieldValue = value });
|
||||||
|
Set(nameof(Value), ref _value, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldVm(string fieldName, string fieldValue)
|
||||||
|
{
|
||||||
|
_name = fieldName;
|
||||||
|
_value = fieldValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -13,6 +13,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
private readonly IRecentProxy _recent;
|
private readonly IRecentProxy _recent;
|
||||||
private ObservableCollection<RecentItemVm> _recentItems;
|
private ObservableCollection<RecentItemVm> _recentItems;
|
||||||
|
private int _selectedIndex;
|
||||||
|
|
||||||
public ObservableCollection<RecentItemVm> RecentItems
|
public ObservableCollection<RecentItemVm> RecentItems
|
||||||
{
|
{
|
||||||
@@ -22,6 +23,12 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public ICommand ClearAllCommand { get; }
|
public ICommand ClearAllCommand { get; }
|
||||||
|
|
||||||
|
public int SelectedIndex
|
||||||
|
{
|
||||||
|
get { return _selectedIndex; }
|
||||||
|
set { Set(() => SelectedIndex, ref _selectedIndex, value); }
|
||||||
|
}
|
||||||
|
|
||||||
public RecentVm(IRecentProxy recent)
|
public RecentVm(IRecentProxy recent)
|
||||||
{
|
{
|
||||||
_recent = recent;
|
_recent = recent;
|
||||||
@@ -34,6 +41,7 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
var recentItems = _recent.GetAll().Select(r => new RecentItemVm(r));
|
var recentItems = _recent.GetAll().Select(r => new RecentItemVm(r));
|
||||||
RecentItems = new ObservableCollection<RecentItemVm>(recentItems);
|
RecentItems = new ObservableCollection<RecentItemVm>(recentItems);
|
||||||
|
if (RecentItems.Any()) SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearAll()
|
private void ClearAll()
|
||||||
|
@@ -36,10 +36,13 @@
|
|||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpenedMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpenedMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpeningMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseOpeningMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseSavedMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\DatabaseSavedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\EntryFieldNameChangedMessage.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\EntryFieldValueChangedMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\FileNotFoundMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\FileNotFoundMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\NavigateToPageMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\NavigateToPageMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)Messages\SaveErrorMessage.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)Messages\SaveErrorMessage.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\AboutVm.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\AboutVm.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\FieldVm.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ViewModelLocatorCommon.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ViewModelLocatorCommon.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\ListMenuItemVm.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\MainMenuItemVm.cs" />
|
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\Items\MainMenuItemVm.cs" />
|
||||||
|
Reference in New Issue
Block a user