mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Moved application code to the Application layer
Imported Win10 project Code cleanup WIP - Use common UWP services for Win8.1 and Win10
This commit is contained in:
27
ModernKeePass10/ViewModels/AboutViewModel.cs
Normal file
27
ModernKeePass10/ViewModels/AboutViewModel.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Windows.ApplicationModel;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class AboutViewModel
|
||||
{
|
||||
private readonly Package _package;
|
||||
|
||||
public string Name => _package.DisplayName;
|
||||
|
||||
public string Version
|
||||
{
|
||||
get
|
||||
{
|
||||
var version = _package.Id.Version;
|
||||
return $"{version.Major}.{version.Minor}";
|
||||
}
|
||||
}
|
||||
|
||||
public AboutViewModel() : this(Package.Current) { }
|
||||
|
||||
public AboutViewModel(Package package)
|
||||
{
|
||||
_package = package;
|
||||
}
|
||||
}
|
||||
}
|
71
ModernKeePass10/ViewModels/EntriesViewModel.cs
Normal file
71
ModernKeePass10/ViewModels/EntriesViewModel.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class EntriesViewModel : NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly GroupItemViewModel _parentGroupViewModel;
|
||||
//private Entry _reorderedEntry;
|
||||
private EntryItemViewModel _selectedEntry;
|
||||
|
||||
public ObservableCollection<EntryItemViewModel> Entries { get; set; }
|
||||
|
||||
public EntryItemViewModel SelectedEntry
|
||||
{
|
||||
get => _selectedEntry;
|
||||
set
|
||||
{
|
||||
_selectedEntry = value;
|
||||
OnPropertyChanged(nameof(SelectedEntry));
|
||||
}
|
||||
}
|
||||
|
||||
public EntriesViewModel(GroupItemViewModel parentGroup): this(App.Container.Resolve<IDatabaseService>(), parentGroup)
|
||||
{ }
|
||||
|
||||
public EntriesViewModel(IDatabaseService databaseService, GroupItemViewModel parentParentGroupViewModel)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_parentGroupViewModel = parentParentGroupViewModel;
|
||||
Entries = new ObservableCollection<EntryItemViewModel>();
|
||||
foreach (var entry in parentParentGroupViewModel.Entries)
|
||||
{
|
||||
Entries.Add(entry);
|
||||
}
|
||||
Entries.CollectionChanged += EntriesOnCollectionChanged;
|
||||
}
|
||||
|
||||
private void EntriesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
// TODO: rewrite this (with service)
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
/*var oldIndex = (uint)e.OldStartingIndex;
|
||||
_reorderedEntry = _group.Group.Entries.GetAt(oldIndex);
|
||||
_group.Group.Entries.RemoveAt(oldIndex);*/
|
||||
_databaseService.DeleteEntity((Entity)e.OldItems[0]);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
/*if (_reorderedEntry == null) _group.Group.AddEntry(((EntryItemViewModel)e.NewItems[0]).Entry, true);
|
||||
else _group.Group.Entries.Insert((uint)e.NewStartingIndex, _reorderedEntry);*/
|
||||
_databaseService.AddEntity(_parentGroupViewModel.GroupEntity, (Entity)e.NewItems[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddNewEntry(string text)
|
||||
{
|
||||
var entry = new EntryItemViewModel(new EntryEntity(), _parentGroupViewModel) {Name = text};
|
||||
Entries.Add(entry);
|
||||
SelectedEntry = entry;
|
||||
}
|
||||
}
|
||||
}
|
57
ModernKeePass10/ViewModels/GroupsViewModel.cs
Normal file
57
ModernKeePass10/ViewModels/GroupsViewModel.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class GroupsViewModel : NotifyPropertyChangedBase
|
||||
{
|
||||
private string _title;
|
||||
private string _newGroupName;
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
_title = value;
|
||||
OnPropertyChanged(nameof(Title));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check why binding not working
|
||||
public string NewGroupName
|
||||
{
|
||||
get => _newGroupName;
|
||||
set
|
||||
{
|
||||
_newGroupName = value;
|
||||
OnPropertyChanged(nameof(NewGroupName));
|
||||
}
|
||||
}
|
||||
|
||||
public GroupItemViewModel RootItemViewModel { get; set; }
|
||||
|
||||
public GroupsViewModel(): this(App.Container.Resolve<IDatabaseService>().RootGroupEntity)
|
||||
{ }
|
||||
|
||||
public GroupsViewModel(GroupEntity groupEntity)
|
||||
{
|
||||
Title = groupEntity.Name;
|
||||
RootItemViewModel = new GroupItemViewModel(groupEntity, null);
|
||||
}
|
||||
|
||||
public void AddNewGroup(string groupName = "")
|
||||
{
|
||||
var group = new GroupEntity
|
||||
{
|
||||
Name = groupName,
|
||||
Icon = Icon.Folder,
|
||||
};
|
||||
RootItemViewModel.Children.Add(new GroupItemViewModel(group, RootItemViewModel));
|
||||
}
|
||||
}
|
||||
}
|
147
ModernKeePass10/ViewModels/ListItems/EntryItemViewModel.cs
Normal file
147
ModernKeePass10/ViewModels/ListItems/EntryItemViewModel.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.UI;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class EntryItemViewModel : NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly ISecurityService _securityService;
|
||||
|
||||
public EntryEntity EntryEntity { get; }
|
||||
public GroupItemViewModel Parent { get; }
|
||||
|
||||
public bool HasExpired => HasExpirationDate && EntryEntity.ExpirationDate < DateTime.Now;
|
||||
|
||||
public bool HasUrl => !string.IsNullOrEmpty(Url);
|
||||
|
||||
public double PasswordComplexityIndicator => _securityService.EstimatePasswordComplexity(Password);
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => EntryEntity.Name;
|
||||
set
|
||||
{
|
||||
EntryEntity.Name = value;
|
||||
OnPropertyChanged(nameof(Name));
|
||||
}
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get => EntryEntity.UserName;
|
||||
set => EntryEntity.UserName = value;
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => EntryEntity.Password;
|
||||
set
|
||||
{
|
||||
EntryEntity.Password = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Url
|
||||
{
|
||||
get => EntryEntity.Url?.ToString();
|
||||
set => EntryEntity.Url = new Uri(value);
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get => EntryEntity.Notes;
|
||||
set => EntryEntity.Notes = value;
|
||||
}
|
||||
|
||||
public Icon Icon
|
||||
{
|
||||
get => HasExpired ? Icon.Important : EntryEntity.Icon;
|
||||
set => EntryEntity.Icon = value;
|
||||
}
|
||||
|
||||
public DateTimeOffset ExpiryDate
|
||||
{
|
||||
get => EntryEntity.ExpirationDate;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
EntryEntity.ExpirationDate = value;
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan ExpiryTime
|
||||
{
|
||||
get => EntryEntity.ExpirationDate.TimeOfDay;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
EntryEntity.ExpirationDate = EntryEntity.ExpirationDate.Date.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasExpirationDate
|
||||
{
|
||||
get => EntryEntity.HasExpirationDate;
|
||||
set
|
||||
{
|
||||
EntryEntity.HasExpirationDate = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Color BackgroundColor
|
||||
{
|
||||
get => Color.FromArgb(EntryEntity.BackgroundColor.A, EntryEntity.BackgroundColor.R, EntryEntity.BackgroundColor.G, EntryEntity.BackgroundColor.B);
|
||||
set
|
||||
{
|
||||
EntryEntity.BackgroundColor = System.Drawing.Color.FromArgb(value.A, value.R, value.G, value.B);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Color ForegroundColor
|
||||
{
|
||||
get => Color.FromArgb(EntryEntity.ForegroundColor.A, EntryEntity.ForegroundColor.R, EntryEntity.ForegroundColor.G, EntryEntity.ForegroundColor.B);
|
||||
set
|
||||
{
|
||||
EntryEntity.ForegroundColor = System.Drawing.Color.FromArgb(value.A, value.R, value.G, value.B);
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<EntryItemViewModel> History
|
||||
{
|
||||
get
|
||||
{
|
||||
var history = new Stack<EntryItemViewModel>();
|
||||
foreach (var historyEntry in EntryEntity.History)
|
||||
{
|
||||
history.Push(new EntryItemViewModel(_securityService, historyEntry, Parent));
|
||||
}
|
||||
history.Push(this);
|
||||
|
||||
return history;
|
||||
}
|
||||
}
|
||||
public Dictionary<string, string> AdditionalFields => EntryEntity.AdditionalFields;
|
||||
|
||||
public EntryItemViewModel(EntryEntity entryEntity, GroupItemViewModel parentGroup): this(App.Container.Resolve<ISecurityService>(), entryEntity, parentGroup)
|
||||
{ }
|
||||
|
||||
public EntryItemViewModel(ISecurityService securityService, EntryEntity entryEntity, GroupItemViewModel parentGroup)
|
||||
{
|
||||
_securityService = securityService;
|
||||
EntryEntity = entryEntity;
|
||||
Parent = parentGroup;
|
||||
}
|
||||
|
||||
public override string ToString() => EntryEntity.LastModificationDate.ToString("g");
|
||||
}
|
||||
}
|
101
ModernKeePass10/ViewModels/ListItems/GroupItemViewModel.cs
Normal file
101
ModernKeePass10/ViewModels/ListItems/GroupItemViewModel.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class GroupItemViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
//private Group _reorderedGroup;
|
||||
private bool _isEditMode;
|
||||
|
||||
public GroupEntity GroupEntity { get; }
|
||||
public GroupItemViewModel ParentViewModel { get; }
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => _isEditMode;
|
||||
set
|
||||
{
|
||||
_isEditMode = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
get => GroupEntity.Name;
|
||||
set
|
||||
{
|
||||
GroupEntity.Name = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<EntryItemViewModel> SubEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
var subEntries = new List<EntryItemViewModel>();
|
||||
subEntries.AddRange(Entries);
|
||||
foreach (var group in Children)
|
||||
{
|
||||
subEntries.AddRange(group.SubEntries);
|
||||
}
|
||||
|
||||
return subEntries;
|
||||
}
|
||||
}
|
||||
|
||||
public Icon Symbol => GroupEntity.Icon;
|
||||
public List<EntryItemViewModel> Entries { get; }
|
||||
public ObservableCollection<GroupItemViewModel> Children { get; set; } = new ObservableCollection<GroupItemViewModel>();
|
||||
|
||||
public GroupItemViewModel(GroupEntity groupEntity, GroupItemViewModel parent): this(App.Container.Resolve<IDatabaseService>(), groupEntity, parent)
|
||||
{ }
|
||||
|
||||
public GroupItemViewModel(IDatabaseService databaseService, GroupEntity groupEntity, GroupItemViewModel parentViewModel)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
GroupEntity = groupEntity;
|
||||
ParentViewModel = parentViewModel;
|
||||
|
||||
Entries = new List<EntryItemViewModel>();
|
||||
foreach (var entry in groupEntity.Entries)
|
||||
{
|
||||
Entries.Add(new EntryItemViewModel(entry, this));
|
||||
}
|
||||
|
||||
foreach (var subGroup in groupEntity.SubGroups)
|
||||
{
|
||||
Children.Add(new GroupItemViewModel(subGroup, this));
|
||||
}
|
||||
Children.CollectionChanged += Children_CollectionChanged;
|
||||
}
|
||||
|
||||
// TODO: not triggered when reordering
|
||||
private void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
/*var oldIndex = (uint)e.OldStartingIndex;
|
||||
_reorderedGroup = Group.SubGroups.GetAt(oldIndex);
|
||||
Group.SubGroups.RemoveAt(oldIndex);*/
|
||||
_databaseService.DeleteEntity((Entity)e.OldItems[0]);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
/*if (_reorderedGroup == null) Group.AddGroup(((GroupItem)e.NewItems[0]).Group, true);
|
||||
else Group.Groups.Insert((uint)e.NewStartingIndex, _reorderedGroup);*/
|
||||
_databaseService.AddEntity(ParentViewModel.GroupEntity, (Entity)e.NewItems[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class ListMenuItemViewModel : 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 => _isSelected;
|
||||
set => SetProperty(ref _isSelected, value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Title;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class MainMenuItemViewModel: ListMenuItemViewModel
|
||||
{
|
||||
public object Parameter { get; set; }
|
||||
public Frame Destination { get; set; }
|
||||
}
|
||||
}
|
36
ModernKeePass10/ViewModels/ListItems/RecentItemViewModel.cs
Normal file
36
ModernKeePass10/ViewModels/ListItems/RecentItemViewModel.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class RecentItemViewModel: NotifyPropertyChangedBase, ISelectableModel
|
||||
{
|
||||
private readonly IRecentService _recentService;
|
||||
private bool _isSelected;
|
||||
|
||||
public string Token { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set => SetProperty(ref _isSelected, value);
|
||||
}
|
||||
|
||||
public RecentItemViewModel(): this (App.Container.Resolve<IRecentService>())
|
||||
{ }
|
||||
|
||||
public RecentItemViewModel(IRecentService recentService)
|
||||
{
|
||||
_recentService = recentService;
|
||||
}
|
||||
|
||||
public async Task UpdateAccessTime()
|
||||
{
|
||||
await _recentService.Get(Token);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
// TODO: implement Kdf settings
|
||||
public class SettingsDatabaseViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly ICryptographyService _cryptographyService;
|
||||
|
||||
public bool HasRecycleBin
|
||||
{
|
||||
get => _databaseService.IsRecycleBinEnabled;
|
||||
set {
|
||||
// TODO: do something here
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsNewRecycleBin
|
||||
{
|
||||
get => _databaseService.RecycleBin == null;
|
||||
set
|
||||
{
|
||||
// TODO: make this work
|
||||
if (value) _databaseService.AddEntity(_databaseService.RootGroupEntity, new Entity{Name = "Recycle Bin"});
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<GroupEntity> Groups { get; set; }
|
||||
|
||||
public ObservableCollection<Entity> Ciphers => new ObservableCollection<Entity>(_cryptographyService.Ciphers);
|
||||
|
||||
public IEnumerable<string> Compressions => _cryptographyService.CompressionAlgorithms;
|
||||
|
||||
public IEnumerable<Entity> KeyDerivations => _cryptographyService.KeyDerivations;
|
||||
|
||||
public Entity SelectedCipher
|
||||
{
|
||||
get => Ciphers.FirstOrDefault(c => c.Id == _databaseService.Cipher.Id);
|
||||
set
|
||||
{
|
||||
if (_databaseService.Cipher != value)
|
||||
{
|
||||
_databaseService.Cipher = value;
|
||||
//OnPropertyChanged(nameof(SelectedCipher));
|
||||
}
|
||||
}
|
||||
}
|
||||
public Entity SelectedKeyDerivation
|
||||
{
|
||||
get => _databaseService.KeyDerivation;
|
||||
set
|
||||
{
|
||||
if (_databaseService.KeyDerivation != value)
|
||||
{
|
||||
_databaseService.KeyDerivation = value;
|
||||
OnPropertyChanged(nameof(SelectedKeyDerivation));
|
||||
}
|
||||
}
|
||||
}
|
||||
public string SelectedCompression
|
||||
{
|
||||
get => _databaseService.Compression;
|
||||
set
|
||||
{
|
||||
if (_databaseService.Compression != value)
|
||||
{
|
||||
_databaseService.Compression = value;
|
||||
OnPropertyChanged(nameof(SelectedCompression));
|
||||
}
|
||||
}
|
||||
}
|
||||
public GroupEntity SelectedRecycleBin
|
||||
{
|
||||
get => _databaseService.RecycleBin;
|
||||
set
|
||||
{
|
||||
if (_databaseService.RecycleBin != value)
|
||||
{
|
||||
_databaseService.RecycleBin = value;
|
||||
OnPropertyChanged(nameof(SelectedRecycleBin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsDatabaseViewModel() : this(App.Container.Resolve<IDatabaseService>(), App.Container.Resolve<ICryptographyService>()) { }
|
||||
|
||||
public SettingsDatabaseViewModel(IDatabaseService databaseService, ICryptographyService cryptographyService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_cryptographyService = cryptographyService;
|
||||
Groups = new ObservableCollection<GroupEntity>(_databaseService.RootGroupEntity.SubGroups);
|
||||
}
|
||||
}
|
||||
}
|
33
ModernKeePass10/ViewModels/ListItems/SettingsNewViewModel.cs
Normal file
33
ModernKeePass10/ViewModels/ListItems/SettingsNewViewModel.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsNewViewModel
|
||||
{
|
||||
private readonly ISettingsService _settings;
|
||||
|
||||
public SettingsNewViewModel() : this(App.Container.Resolve<ISettingsService>())
|
||||
{ }
|
||||
|
||||
public SettingsNewViewModel(ISettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public bool IsCreateSample
|
||||
{
|
||||
get => _settings.GetSetting<bool>("Sample");
|
||||
set => _settings.PutSetting("Sample", value);
|
||||
}
|
||||
|
||||
public IEnumerable<string> FileFormats => new []{"2", "4"};
|
||||
|
||||
public string FileFormatVersion
|
||||
{
|
||||
get => _settings.GetSetting("DefaultFileFormat", "2");
|
||||
set => _settings.PutSetting("DefaultFileFormat", value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels.ListItems
|
||||
{
|
||||
public class SettingsSaveViewModel
|
||||
{
|
||||
private readonly ISettingsService _settings;
|
||||
|
||||
public SettingsSaveViewModel() : this(App.Container.Resolve<ISettingsService>())
|
||||
{ }
|
||||
|
||||
public SettingsSaveViewModel(ISettingsService settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public bool IsSaveSuspend
|
||||
{
|
||||
get => _settings.GetSetting("SaveSuspend", true);
|
||||
set => _settings.PutSetting("SaveSuspend", value);
|
||||
}
|
||||
}
|
||||
}
|
30
ModernKeePass10/ViewModels/MainViewModel.cs
Normal file
30
ModernKeePass10/ViewModels/MainViewModel.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Windows.Storage;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class MainViewModel
|
||||
{
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly IRecentService _recentService;
|
||||
|
||||
public bool IsDatabaseOpened => _databaseService.IsOpen;
|
||||
public bool HasRecentItems => _recentService.HasEntries;
|
||||
|
||||
public string OpenedDatabaseName => _databaseService.Name;
|
||||
public IStorageFile File { get; set; }
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
_databaseService = App.Container.Resolve<IDatabaseService>();
|
||||
_recentService = App.Container.Resolve<IRecentService>();
|
||||
}
|
||||
|
||||
public MainViewModel(IDatabaseService databaseService, IRecentService recentService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_recentService = recentService;
|
||||
}
|
||||
}
|
||||
}
|
99
ModernKeePass10/ViewModels/NewViewModel.cs
Normal file
99
ModernKeePass10/ViewModels/NewViewModel.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.AccessCache;
|
||||
using ModernKeePass.Converters;
|
||||
using ModernKeePass.Domain.Entities;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class NewViewModel : OpenViewModel
|
||||
{
|
||||
private string _importFormatHelp;
|
||||
private readonly IDatabaseService _databaseService;
|
||||
private readonly IImportService _importService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public string Password { get; set; }
|
||||
|
||||
public bool IsImportChecked { get; set; }
|
||||
|
||||
public IStorageFile ImportFile { get; set; }
|
||||
|
||||
public string ImportFileExtensionFilter { get; set; } = "*";
|
||||
|
||||
public ImportFormat ImportFormat { get; set; }
|
||||
|
||||
public string ImportFormatHelp
|
||||
{
|
||||
get => _importFormatHelp;
|
||||
set
|
||||
{
|
||||
_importFormatHelp = value;
|
||||
OnPropertyChanged(nameof(ImportFormatHelp));
|
||||
}
|
||||
}
|
||||
|
||||
public NewViewModel()
|
||||
{ }
|
||||
|
||||
public NewViewModel(IDatabaseService databaseService, IImportService importService, ISettingsService settingsService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_importService = importService;
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
public void PopulateInitialData()
|
||||
{
|
||||
if (_settingsService.GetSetting<bool>("Sample") && !IsImportChecked) CreateSampleData(_databaseService.RootGroupEntity);
|
||||
else if (IsImportChecked && ImportFile != null)
|
||||
{
|
||||
var token = StorageApplicationPermissions.FutureAccessList.Add(ImportFile);
|
||||
_importService.Import(ImportFormat, token, _databaseService.RootGroupEntity);
|
||||
StorageApplicationPermissions.FutureAccessList.Remove(token);
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateSampleData(GroupEntity groupEntity)
|
||||
{
|
||||
var converter = new IconToSymbolConverter();
|
||||
|
||||
groupEntity.SubGroups.Add(new GroupEntity
|
||||
{
|
||||
Name = "Banking",
|
||||
Icon = Icon.Calculator
|
||||
});
|
||||
|
||||
groupEntity.SubGroups.Add(new GroupEntity
|
||||
{
|
||||
Name = "Email",
|
||||
Icon = Icon.Mail
|
||||
});
|
||||
|
||||
groupEntity.SubGroups.Add(new GroupEntity
|
||||
{
|
||||
Name = "Internet",
|
||||
Icon = Icon.World
|
||||
});
|
||||
|
||||
groupEntity.Entries.Add(new EntryEntity
|
||||
{
|
||||
Name = "Sample Entry",
|
||||
UserName = "Username",
|
||||
Url = new Uri("https://keepass.info"),
|
||||
Password = "Password",
|
||||
Notes = "You may safely delete this sample"
|
||||
});
|
||||
|
||||
groupEntity.Entries.Add(new EntryEntity
|
||||
{
|
||||
Name = "Sample Entry #2",
|
||||
UserName = "Michael321",
|
||||
Url = new Uri("https://keepass.info/help/base/kb/testform.html"),
|
||||
Password = "12345"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
322
ModernKeePass10/ViewModels/Old/EntryVm.cs
Normal file
322
ModernKeePass10/ViewModels/Old/EntryVm.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Windows.Input;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||
using ModernKeePassLib.Security;
|
||||
using ModernKeePassLib.Cryptography;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class EntryVm : INotifyPropertyChanged, IPwEntity, ISelectableModel
|
||||
{
|
||||
public GroupVm ParentGroup { get; private set; }
|
||||
public GroupVm PreviousGroup { get; private set; }
|
||||
public bool IsRevealPasswordEnabled => !string.IsNullOrEmpty(Password);
|
||||
public bool HasExpired => HasExpirationDate && _pwEntry.ExpiryTime < DateTime.Now;
|
||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||
public bool UpperCasePatternSelected { get; set; } = true;
|
||||
public bool LowerCasePatternSelected { get; set; } = true;
|
||||
public bool DigitsPatternSelected { get; set; } = true;
|
||||
public bool MinusPatternSelected { get; set; }
|
||||
public bool UnderscorePatternSelected { get; set; }
|
||||
public bool SpacePatternSelected { get; set; }
|
||||
public bool SpecialPatternSelected { get; set; }
|
||||
public bool BracketsPatternSelected { get; set; }
|
||||
public string CustomChars { get; set; } = string.Empty;
|
||||
public PwUuid IdUuid => _pwEntry?.Uuid;
|
||||
public string Id => _pwEntry?.Uuid.ToHexString();
|
||||
public bool IsRecycleOnDelete => _database.IsRecycleBinEnabled && !ParentGroup.IsSelected;
|
||||
public IEnumerable<IPwEntity> BreadCrumb => new List<IPwEntity>(ParentGroup.BreadCrumb) {ParentGroup};
|
||||
/// <summary>
|
||||
/// Determines if the Entry is current or from history
|
||||
/// </summary>
|
||||
public bool IsSelected { get; set; } = true;
|
||||
|
||||
public double PasswordLength
|
||||
{
|
||||
get => _passwordLength;
|
||||
set
|
||||
{
|
||||
_passwordLength = value;
|
||||
NotifyPropertyChanged("PasswordLength");
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => GetEntryValue(PwDefs.TitleField);
|
||||
set => SetEntryValue(PwDefs.TitleField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get => GetEntryValue(PwDefs.UserNameField);
|
||||
set => SetEntryValue(PwDefs.UserNameField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => GetEntryValue(PwDefs.PasswordField);
|
||||
set
|
||||
{
|
||||
SetEntryValue(PwDefs.PasswordField, new ProtectedString(true, value));
|
||||
NotifyPropertyChanged("Password");
|
||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||
}
|
||||
}
|
||||
|
||||
public string Url
|
||||
{
|
||||
get => GetEntryValue(PwDefs.UrlField);
|
||||
set => SetEntryValue(PwDefs.UrlField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public string Notes
|
||||
{
|
||||
get => GetEntryValue(PwDefs.NotesField);
|
||||
set => SetEntryValue(PwDefs.NotesField, new ProtectedString(true, value));
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HasExpired) return (int) PwIcon.Expired;
|
||||
if (_pwEntry?.IconId != null) return (int) _pwEntry?.IconId;
|
||||
return -1;
|
||||
}
|
||||
set
|
||||
{
|
||||
HandleBackup();
|
||||
_pwEntry.IconId = (PwIcon)value;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTimeOffset ExpiryDate
|
||||
{
|
||||
get => new DateTimeOffset(_pwEntry.ExpiryTime.Date);
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
HandleBackup();
|
||||
_pwEntry.ExpiryTime = value.DateTime;
|
||||
}
|
||||
}
|
||||
|
||||
public TimeSpan ExpiryTime
|
||||
{
|
||||
get => _pwEntry.ExpiryTime.TimeOfDay;
|
||||
set
|
||||
{
|
||||
if (!HasExpirationDate) return;
|
||||
HandleBackup();
|
||||
_pwEntry.ExpiryTime = _pwEntry.ExpiryTime.Date.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => IsSelected && _isEditMode;
|
||||
set
|
||||
{
|
||||
_isEditMode = value;
|
||||
NotifyPropertyChanged("IsEditMode");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get => _isVisible;
|
||||
set
|
||||
{
|
||||
_isVisible = value;
|
||||
NotifyPropertyChanged("IsVisible");
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRevealPassword
|
||||
{
|
||||
get => _isRevealPassword;
|
||||
set
|
||||
{
|
||||
_isRevealPassword = value;
|
||||
NotifyPropertyChanged("IsRevealPassword");
|
||||
}
|
||||
}
|
||||
public bool HasExpirationDate
|
||||
{
|
||||
get => _pwEntry.Expires;
|
||||
set
|
||||
{
|
||||
_pwEntry.Expires = value;
|
||||
NotifyPropertyChanged("HasExpirationDate");
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IPwEntity> History
|
||||
{
|
||||
get
|
||||
{
|
||||
var history = new Stack<EntryVm>();
|
||||
foreach (var historyEntry in _pwEntry.History)
|
||||
{
|
||||
history.Push(new EntryVm(historyEntry, ParentGroup) {IsSelected = false});
|
||||
}
|
||||
history.Push(this);
|
||||
|
||||
return history;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Color? BackgroundColor
|
||||
{
|
||||
get => _pwEntry?.BackgroundColor;
|
||||
set
|
||||
{
|
||||
if (value != null) _pwEntry.BackgroundColor = (Color) value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color? ForegroundColor
|
||||
{
|
||||
get => _pwEntry?.ForegroundColor;
|
||||
set
|
||||
{
|
||||
if (value != null) _pwEntry.ForegroundColor = (Color)value;
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand GeneratePasswordCommand { get; }
|
||||
public ICommand UndoDeleteCommand { get; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private readonly PwEntry _pwEntry;
|
||||
private readonly IDatabaseService _database;
|
||||
private readonly IResourceService _resource;
|
||||
private bool _isEditMode;
|
||||
private bool _isDirty = true;
|
||||
private bool _isRevealPassword;
|
||||
private double _passwordLength = 25;
|
||||
private bool _isVisible = true;
|
||||
|
||||
private void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public EntryVm() { }
|
||||
|
||||
internal EntryVm(PwEntry entry, GroupVm parent) : this(entry, parent, DatabaseService.Instance, new ResourcesService()) { }
|
||||
|
||||
public EntryVm(PwEntry entry, GroupVm parent, IDatabaseService database, IResourceService resource)
|
||||
{
|
||||
_database = database;
|
||||
_resource = resource;
|
||||
_pwEntry = entry;
|
||||
ParentGroup = parent;
|
||||
|
||||
SaveCommand = new RelayCommand(() => _database.Save());
|
||||
GeneratePasswordCommand = new RelayCommand(GeneratePassword);
|
||||
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
||||
}
|
||||
|
||||
public void GeneratePassword()
|
||||
{
|
||||
var pwProfile = new PwProfile
|
||||
{
|
||||
GeneratorType = PasswordGeneratorType.CharSet,
|
||||
Length = (uint)PasswordLength,
|
||||
CharSet = new PwCharSet()
|
||||
};
|
||||
|
||||
if (UpperCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.UpperCase);
|
||||
if (LowerCasePatternSelected) pwProfile.CharSet.Add(PwCharSet.LowerCase);
|
||||
if (DigitsPatternSelected) pwProfile.CharSet.Add(PwCharSet.Digits);
|
||||
if (SpecialPatternSelected) pwProfile.CharSet.Add(PwCharSet.SpecialChars);
|
||||
if (MinusPatternSelected) pwProfile.CharSet.Add('-');
|
||||
if (UnderscorePatternSelected) pwProfile.CharSet.Add('_');
|
||||
if (SpacePatternSelected) pwProfile.CharSet.Add(' ');
|
||||
if (BracketsPatternSelected) pwProfile.CharSet.Add(PwCharSet.Brackets);
|
||||
|
||||
pwProfile.CharSet.Add(CustomChars);
|
||||
|
||||
ProtectedString password;
|
||||
PwGenerator.Generate(out password, pwProfile, null, new CustomPwGeneratorPool());
|
||||
|
||||
SetEntryValue(PwDefs.PasswordField, password);
|
||||
NotifyPropertyChanged("Password");
|
||||
NotifyPropertyChanged("IsRevealPasswordEnabled");
|
||||
NotifyPropertyChanged("PasswordComplexityIndicator");
|
||||
}
|
||||
|
||||
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.IsRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.IsRecycleBinEnabled && !ParentGroup.IsSelected ? _database.RecycleBin : null);
|
||||
}
|
||||
|
||||
public void Move(GroupVm destination)
|
||||
{
|
||||
PreviousGroup = ParentGroup;
|
||||
PreviousGroup.Entries.Remove(this);
|
||||
if (destination == null)
|
||||
{
|
||||
_database.AddDeletedItem(IdUuid);
|
||||
return;
|
||||
}
|
||||
ParentGroup = destination;
|
||||
ParentGroup.Entries.Add(this);
|
||||
}
|
||||
|
||||
public void CommitDelete()
|
||||
{
|
||||
_pwEntry.ParentGroup.Entries.Remove(_pwEntry);
|
||||
if (!_database.IsRecycleBinEnabled || PreviousGroup.IsSelected) _database.AddDeletedItem(IdUuid);
|
||||
}
|
||||
|
||||
public PwEntry GetPwEntry()
|
||||
{
|
||||
return _pwEntry;
|
||||
}
|
||||
public void Reset()
|
||||
{
|
||||
_isDirty = false;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return IsSelected ? _resource.GetResourceValue("EntryCurrent") : _pwEntry.LastModificationTime.ToString("g");
|
||||
}
|
||||
|
||||
private void HandleBackup()
|
||||
{
|
||||
if (_isDirty) return;
|
||||
_pwEntry?.Touch(true);
|
||||
_pwEntry?.CreateBackup(null);
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
private string GetEntryValue(string key)
|
||||
{
|
||||
return _pwEntry?.Strings.GetSafe(key).ReadString();
|
||||
}
|
||||
|
||||
private void SetEntryValue(string key, ProtectedString newValue)
|
||||
{
|
||||
HandleBackup();
|
||||
_pwEntry?.Strings.Set(key, newValue);
|
||||
}
|
||||
}
|
||||
}
|
257
ModernKeePass10/ViewModels/Old/GroupVm.cs
Normal file
257
ModernKeePass10/ViewModels/Old/GroupVm.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class GroupVm : NotifyPropertyChangedBase, IPwEntity, ISelectableModel
|
||||
{
|
||||
public GroupVm ParentGroup { get; private set; }
|
||||
public GroupVm PreviousGroup { get; private set; }
|
||||
|
||||
public ObservableCollection<EntryVm> Entries
|
||||
{
|
||||
get => _entries;
|
||||
private set => SetProperty(ref _entries, value);
|
||||
}
|
||||
|
||||
public IEnumerable<EntryVm> SubEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
var subEntries = new List<EntryVm>();
|
||||
subEntries.AddRange(Entries);
|
||||
foreach (var group in Groups)
|
||||
{
|
||||
subEntries.AddRange(group.SubEntries);
|
||||
}
|
||||
|
||||
return subEntries;
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
||||
|
||||
public PwUuid IdUuid => _pwGroup?.Uuid;
|
||||
public string Id => IdUuid?.ToHexString();
|
||||
public bool IsNotRoot => ParentGroup != null;
|
||||
|
||||
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
|
||||
|
||||
public bool IsRecycleOnDelete => _database.IsRecycleBinEnabled && !IsSelected && !ParentGroup.IsSelected;
|
||||
|
||||
/// <summary>
|
||||
/// Is the Group the database Recycle Bin?
|
||||
/// </summary>
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _database != null && _database.IsRecycleBinEnabled && _database.RecycleBin?.Id == Id;
|
||||
set
|
||||
{
|
||||
if (value && _pwGroup != null) _database.RecycleBin = this;
|
||||
}
|
||||
}
|
||||
|
||||
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
|
||||
group e by e.Name.ToUpper().FirstOrDefault() into grp
|
||||
orderby grp.Key
|
||||
select grp;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _pwGroup == null ? string.Empty : _pwGroup.Name;
|
||||
set => _pwGroup.Name = value;
|
||||
}
|
||||
|
||||
public int IconId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_pwGroup?.IconId != null) return (int) _pwGroup?.IconId;
|
||||
return -1;
|
||||
}
|
||||
set => _pwGroup.IconId = (PwIcon)value;
|
||||
}
|
||||
|
||||
public bool IsEditMode
|
||||
{
|
||||
get => _isEditMode;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _isEditMode, value);
|
||||
((RelayCommand)SortEntriesCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)SortGroupsCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMenuClosed
|
||||
{
|
||||
get => _isMenuClosed;
|
||||
set => SetProperty(ref _isMenuClosed, value);
|
||||
}
|
||||
|
||||
public IEnumerable<IPwEntity> BreadCrumb
|
||||
{
|
||||
get
|
||||
{
|
||||
var groups = new Stack<GroupVm>();
|
||||
var group = this;
|
||||
while (group.ParentGroup != null)
|
||||
{
|
||||
group = group.ParentGroup;
|
||||
groups.Push(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand SortEntriesCommand { get; }
|
||||
public ICommand SortGroupsCommand { get; }
|
||||
public ICommand UndoDeleteCommand { get; }
|
||||
|
||||
private readonly PwGroup _pwGroup;
|
||||
private readonly IDatabaseService _database;
|
||||
private bool _isEditMode;
|
||||
private PwEntry _reorderedEntry;
|
||||
private ObservableCollection<EntryVm> _entries = new ObservableCollection<EntryVm>();
|
||||
private bool _isMenuClosed = true;
|
||||
|
||||
public GroupVm() {}
|
||||
|
||||
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
||||
DatabaseService.Instance, recycleBinId)
|
||||
{ }
|
||||
|
||||
public GroupVm(PwGroup pwGroup, GroupVm parent, IDatabaseService database, PwUuid recycleBinId = null)
|
||||
{
|
||||
_pwGroup = pwGroup;
|
||||
_database = database;
|
||||
ParentGroup = parent;
|
||||
|
||||
SaveCommand = new RelayCommand(() => _database.Save());
|
||||
SortEntriesCommand = new RelayCommand(async () =>
|
||||
await SortEntriesAsync().ConfigureAwait(false), () => IsEditMode);
|
||||
SortGroupsCommand = new RelayCommand(async () =>
|
||||
await SortGroupsAsync().ConfigureAwait(false), () => IsEditMode);
|
||||
UndoDeleteCommand = new RelayCommand(() => Move(PreviousGroup), () => PreviousGroup != null);
|
||||
|
||||
if (recycleBinId != null && _pwGroup.Uuid.Equals(recycleBinId)) _database.RecycleBin = this;
|
||||
Entries = new ObservableCollection<EntryVm>(pwGroup.Entries.Select(e => new EntryVm(e, this)));
|
||||
Entries.CollectionChanged += Entries_CollectionChanged;
|
||||
Groups = new ObservableCollection<GroupVm>(pwGroup.Groups.Select(g => new GroupVm(g, this, recycleBinId)));
|
||||
}
|
||||
|
||||
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
switch (e.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
var oldIndex = (uint) e.OldStartingIndex;
|
||||
_reorderedEntry = _pwGroup.Entries.GetAt(oldIndex);
|
||||
_pwGroup.Entries.RemoveAt(oldIndex);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
if (_reorderedEntry == null) _pwGroup.AddEntry(((EntryVm) e.NewItems[0]).GetPwEntry(), true);
|
||||
else _pwGroup.Entries.Insert((uint)e.NewStartingIndex, _reorderedEntry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public GroupVm AddNewGroup(string name = "")
|
||||
{
|
||||
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
|
||||
_pwGroup.AddGroup(pwGroup, true);
|
||||
var newGroup = new GroupVm(pwGroup, this) {Name = name, IsEditMode = string.IsNullOrEmpty(name)};
|
||||
Groups.Add(newGroup);
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
public EntryVm AddNewEntry()
|
||||
{
|
||||
var pwEntry = new PwEntry(true, true);
|
||||
var newEntry = new EntryVm(pwEntry, this) {IsEditMode = true};
|
||||
newEntry.GeneratePassword();
|
||||
Entries.Add(newEntry);
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
public void MarkForDelete(string recycleBinTitle)
|
||||
{
|
||||
if (_database.IsRecycleBinEnabled && _database.RecycleBin?.IdUuid == null)
|
||||
_database.CreateRecycleBin(recycleBinTitle);
|
||||
Move(_database.IsRecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||
((RelayCommand)UndoDeleteCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
public void UndoDelete()
|
||||
{
|
||||
Move(PreviousGroup);
|
||||
}
|
||||
|
||||
public void Move(GroupVm destination)
|
||||
{
|
||||
PreviousGroup = ParentGroup;
|
||||
PreviousGroup.Groups.Remove(this);
|
||||
PreviousGroup._pwGroup.Groups.Remove(_pwGroup);
|
||||
if (destination == null)
|
||||
{
|
||||
_database.AddDeletedItem(IdUuid);
|
||||
return;
|
||||
}
|
||||
ParentGroup = destination;
|
||||
ParentGroup.Groups.Add(this);
|
||||
ParentGroup._pwGroup.AddGroup(_pwGroup, true);
|
||||
}
|
||||
|
||||
public void CommitDelete()
|
||||
{
|
||||
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
|
||||
if (_database.IsRecycleBinEnabled && !PreviousGroup.IsSelected) _database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
|
||||
else _database.AddDeletedItem(IdUuid);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
private async Task SortEntriesAsync()
|
||||
{
|
||||
var comparer = new PwEntryComparer(PwDefs.TitleField, true, false);
|
||||
try
|
||||
{
|
||||
_pwGroup.Entries.Sort(comparer);
|
||||
Entries = new ObservableCollection<EntryVm>(Entries.OrderBy(e => e.Name));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SortGroupsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_pwGroup.SortSubGroups(false);
|
||||
Groups = new ObservableCollection<GroupVm>(Groups.OrderBy(g => g.Name).ThenBy(g => g._pwGroup == null));
|
||||
OnPropertyChanged("Groups");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
44
ModernKeePass10/ViewModels/OpenViewModel.cs
Normal file
44
ModernKeePass10/ViewModels/OpenViewModel.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class OpenViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly IRecentService _recentService;
|
||||
private string _name;
|
||||
private string _databaseFilePath;
|
||||
|
||||
public bool IsFileSelected => !string.IsNullOrEmpty(DatabaseFilePath);
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
private set => SetProperty(ref _name, value);
|
||||
}
|
||||
|
||||
public string DatabaseFilePath
|
||||
{
|
||||
get => _databaseFilePath;
|
||||
private set => SetProperty(ref _databaseFilePath, value);
|
||||
}
|
||||
|
||||
public OpenViewModel(): this(App.Container.Resolve<IRecentService>())
|
||||
{ }
|
||||
public OpenViewModel(IRecentService recentService)
|
||||
{
|
||||
_recentService = recentService;
|
||||
}
|
||||
|
||||
public async Task OpenFile(FileInfo fileInfo)
|
||||
{
|
||||
Name = fileInfo.Name;
|
||||
DatabaseFilePath = fileInfo.Path;
|
||||
OnPropertyChanged(nameof(IsFileSelected));
|
||||
await _recentService.Add(fileInfo);
|
||||
}
|
||||
}
|
||||
}
|
69
ModernKeePass10/ViewModels/RecentViewModel.cs
Normal file
69
ModernKeePass10/ViewModels/RecentViewModel.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
using Autofac;
|
||||
using ModernKeePass.Application.Common.Interfaces;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
using ModernKeePass.ViewModels.ListItems;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class RecentViewModel : NotifyPropertyChangedBase, IHasSelectableObject
|
||||
{
|
||||
private readonly IRecentService _recentService;
|
||||
private ISelectableModel _selectedItem;
|
||||
private ObservableCollection<RecentItemViewModel> _recentItems = new ObservableCollection<RecentItemViewModel>();
|
||||
|
||||
public ObservableCollection<RecentItemViewModel> RecentItems
|
||||
{
|
||||
get => _recentItems;
|
||||
set => SetProperty(ref _recentItems, value);
|
||||
}
|
||||
|
||||
public ISelectableModel SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set
|
||||
{
|
||||
if (_selectedItem == value) return;
|
||||
if (_selectedItem != null)
|
||||
{
|
||||
_selectedItem.IsSelected = false;
|
||||
}
|
||||
|
||||
SetProperty(ref _selectedItem, value);
|
||||
|
||||
if (_selectedItem == null) return;
|
||||
_selectedItem.IsSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand ClearAllCommand { get; }
|
||||
|
||||
public RecentViewModel() : this (App.Container.Resolve<IRecentService>())
|
||||
{ }
|
||||
|
||||
public RecentViewModel(IRecentService recentService)
|
||||
{
|
||||
_recentService = recentService;
|
||||
ClearAllCommand = new RelayCommand(ClearAll);
|
||||
|
||||
RecentItems = new ObservableCollection<RecentItemViewModel>(
|
||||
_recentService.GetAll().GetAwaiter().GetResult().Select(r => new RecentItemViewModel
|
||||
{
|
||||
Name = r.Name,
|
||||
Token = r.Path
|
||||
})
|
||||
);
|
||||
if (RecentItems.Count > 0) SelectedItem = RecentItems[0];
|
||||
}
|
||||
|
||||
private void ClearAll()
|
||||
{
|
||||
_recentService.ClearAll();
|
||||
RecentItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
31
ModernKeePass10/ViewModels/SaveViewModel.cs
Normal file
31
ModernKeePass10/ViewModels/SaveViewModel.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class SaveViewModel
|
||||
{
|
||||
private readonly IDatabaseService _database;
|
||||
public SaveViewModel() : this(App.Container.Resolve<IDatabaseService>()) { }
|
||||
|
||||
public SaveViewModel(IDatabaseService database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public void Save(bool close = true)
|
||||
{
|
||||
_database.Save();
|
||||
if (close) _database.Close();
|
||||
}
|
||||
|
||||
public void Save(string token)
|
||||
{
|
||||
_database.SaveAs(new FileInfo
|
||||
{
|
||||
Path = token
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
20
ModernKeePass10/ViewModels/SettingsViewModel.cs
Normal file
20
ModernKeePass10/ViewModels/SettingsViewModel.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class SettingsViewModel
|
||||
{
|
||||
private readonly IDatabaseService _database;
|
||||
|
||||
public bool IsDatabaseOpened => _database != null && _database.IsOpen;
|
||||
|
||||
public SettingsViewModel() : this(App.Container.Resolve<IDatabaseService>())
|
||||
{ }
|
||||
|
||||
public SettingsViewModel(IDatabaseService database)
|
||||
{
|
||||
_database = database;
|
||||
}
|
||||
}
|
||||
}
|
149
ModernKeePass10/ViewModels/UserControls/CredentialsViewModel.cs
Normal file
149
ModernKeePass10/ViewModels/UserControls/CredentialsViewModel.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Autofac;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class CredentialsViewModel: NotifyPropertyChangedBase
|
||||
{
|
||||
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private bool _isOpening;
|
||||
private string _password = string.Empty;
|
||||
private string _status;
|
||||
private CredentialStatusTypes _statusType;
|
||||
private string _keyFilePath = string.Empty;
|
||||
private string _keyFileText;
|
||||
private readonly IResourceService _resourceService;
|
||||
private readonly IDatabaseService _databaseService;
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get => _hasPassword;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasPassword, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get => _hasKeyFile;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasKeyFile, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUserAccount
|
||||
{
|
||||
get => _hasUserAccount;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _hasUserAccount, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => !_isOpening && (HasPassword || HasKeyFile && KeyFilePath != string.Empty || HasUserAccount);
|
||||
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value);
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get => (int)_statusType;
|
||||
set => SetProperty(ref _statusType, (CredentialStatusTypes)value);
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set
|
||||
{
|
||||
_password = value;
|
||||
StatusType = (int)CredentialStatusTypes.Normal;
|
||||
Status = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFilePath
|
||||
{
|
||||
get => _keyFilePath;
|
||||
set
|
||||
{
|
||||
_keyFilePath = value;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get => _keyFileText;
|
||||
set => SetProperty(ref _keyFileText, value);
|
||||
}
|
||||
|
||||
|
||||
public CredentialsViewModel() : this(App.Container.Resolve<IDatabaseService>(), App.Container.Resolve<IResourceService>()) { }
|
||||
|
||||
public CredentialsViewModel(IDatabaseService databaseService, IResourceService resourceService)
|
||||
{
|
||||
_databaseService = databaseService;
|
||||
_resourceService = resourceService;
|
||||
_keyFileText = _resourceService.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
}
|
||||
|
||||
public async Task<bool> OpenDatabase(FileInfo fileInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isOpening = true;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
var credentials = new Credentials
|
||||
{
|
||||
KeyFilePath = HasKeyFile ? KeyFilePath : string.Empty,
|
||||
Password = HasPassword ? Password : string.Empty
|
||||
};
|
||||
await Task.Run(() => _databaseService.Open(fileInfo, credentials));
|
||||
return true;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
var errorMessage = new StringBuilder($"{_resourceService.GetResourceValue("CompositeKeyErrorOpen")}\n");
|
||||
if (HasPassword) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasKeyFile) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
if (HasUserAccount) errorMessage.AppendLine(_resourceService.GetResourceValue("CompositeKeyErrorUserAccount"));
|
||||
UpdateStatus(errorMessage.ToString(), CredentialStatusTypes.Error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
var error = $"{_resourceService.GetResourceValue("CompositeKeyErrorOpen")}{e.Message}";
|
||||
UpdateStatus(error, CredentialStatusTypes.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isOpening = false;
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateStatus(string text, CredentialStatusTypes type)
|
||||
{
|
||||
Status = text;
|
||||
StatusType = (int)type;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,93 @@
|
||||
using Autofac;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using ModernKeePass.Domain.AOP;
|
||||
using ModernKeePass.Domain.Dtos;
|
||||
using ModernKeePass.Domain.Enums;
|
||||
using ModernKeePass.Domain.Interfaces;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class UpdateCredentialsViewModel : NotifyPropertyChangedBase
|
||||
{
|
||||
private readonly ISecurityService _securityService;
|
||||
private bool _hasPassword;
|
||||
private bool _hasKeyFile;
|
||||
private bool _hasUserAccount;
|
||||
private string _confirmPassword;
|
||||
private string _password;
|
||||
private string _keyFileText;
|
||||
private string _status;
|
||||
private CredentialStatusTypes _statusType;
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _password, value);
|
||||
OnPropertyChanged(nameof(IsValid));
|
||||
}
|
||||
}
|
||||
|
||||
public string ConfirmPassword
|
||||
{
|
||||
get => _confirmPassword;
|
||||
set => SetProperty(ref _confirmPassword, value);
|
||||
}
|
||||
|
||||
public string KeyFilePath { get; set; }
|
||||
|
||||
public bool HasPassword
|
||||
{
|
||||
get => _hasPassword;
|
||||
set => SetProperty(ref _hasPassword, value);
|
||||
}
|
||||
|
||||
public bool HasKeyFile
|
||||
{
|
||||
get => _hasKeyFile;
|
||||
set => SetProperty(ref _hasKeyFile, value);
|
||||
}
|
||||
|
||||
public bool HasUserAccount
|
||||
{
|
||||
get => _hasUserAccount;
|
||||
set => SetProperty(ref _hasUserAccount, value);
|
||||
}
|
||||
|
||||
public string KeyFileText
|
||||
{
|
||||
get => _keyFileText;
|
||||
set => SetProperty(ref _keyFileText, value);
|
||||
}
|
||||
|
||||
public string Status
|
||||
{
|
||||
get => _status;
|
||||
set => SetProperty(ref _status, value);
|
||||
}
|
||||
|
||||
public int StatusType
|
||||
{
|
||||
get => (int)_statusType;
|
||||
set => SetProperty(ref _statusType, (CredentialStatusTypes)value);
|
||||
}
|
||||
|
||||
public double PasswordComplexityIndicator => _securityService.EstimatePasswordComplexity(Password);
|
||||
|
||||
public bool IsValid => HasPassword && Password == ConfirmPassword || HasKeyFile && KeyFilePath != string.Empty || HasUserAccount;
|
||||
|
||||
public UpdateCredentialsViewModel(): this(App.Container.Resolve<ISecurityService>()) { }
|
||||
|
||||
public UpdateCredentialsViewModel(ISecurityService securityService)
|
||||
{
|
||||
_securityService = securityService;
|
||||
}
|
||||
|
||||
internal Task<bool> CreateDatabase(FileInfo fileInfo)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user