mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Created a Settings Service
Created a Recent Service Created a Resources Service Code refactor Updated tests
This commit is contained in:
@@ -1,16 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Data.Json;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Exceptions;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
|
||||
@@ -22,7 +19,7 @@ namespace ModernKeePass
|
||||
/// </summary>
|
||||
sealed partial class App
|
||||
{
|
||||
public DatabaseService Database { get; set; } = new DatabaseService();
|
||||
public DatabaseService Database { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
@@ -49,7 +46,7 @@ namespace ModernKeePass
|
||||
|
||||
if (!(realException is SaveException)) return;
|
||||
unhandledExceptionEventArgs.Handled = true;
|
||||
MessageDialogService.SaveErrorDialog(realException as SaveException, Database);
|
||||
MessageDialogHelper.SaveErrorDialog(realException as SaveException, Database);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,6 +121,7 @@ namespace ModernKeePass
|
||||
}*/
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
Database = new DatabaseService();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -5,9 +5,9 @@ using Windows.UI.Popups;
|
||||
using ModernKeePass.Exceptions;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
namespace ModernKeePass.Common
|
||||
{
|
||||
public static class MessageDialogService
|
||||
public static class MessageDialogHelper
|
||||
{
|
||||
public static async void ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler action)
|
||||
{
|
@@ -5,9 +5,9 @@ using Windows.UI.Notifications;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.ViewModels;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
namespace ModernKeePass.Common
|
||||
{
|
||||
public static class ToastNotificationService
|
||||
public static class ToastNotificationHelper
|
||||
{
|
||||
public static void ShowMovedToast(IPwEntity entity, string action, string text)
|
||||
{
|
14
ModernKeePass/Interfaces/IRecent.cs
Normal file
14
ModernKeePass/Interfaces/IRecent.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IRecent
|
||||
{
|
||||
int EntryCount { get; }
|
||||
Task<IStorageItem> GetFileAsync(string token);
|
||||
ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true);
|
||||
void Add(IStorageItem file, string metadata);
|
||||
}
|
||||
}
|
11
ModernKeePass/Interfaces/IRecentItem.cs
Normal file
11
ModernKeePass/Interfaces/IRecentItem.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Windows.Storage;
|
||||
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IRecentItem
|
||||
{
|
||||
StorageFile DatabaseFile { get; }
|
||||
string Token { get; }
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
7
ModernKeePass/Interfaces/IResource.cs
Normal file
7
ModernKeePass/Interfaces/IResource.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface IResource
|
||||
{
|
||||
string GetResourceValue(string key);
|
||||
}
|
||||
}
|
8
ModernKeePass/Interfaces/ISettings.cs
Normal file
8
ModernKeePass/Interfaces/ISettings.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace ModernKeePass.Interfaces
|
||||
{
|
||||
public interface ISettings
|
||||
{
|
||||
T GetSetting<T>(string property);
|
||||
void PutSetting<T>(string property, T value);
|
||||
}
|
||||
}
|
@@ -113,18 +113,24 @@
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Interfaces\IRecent.cs" />
|
||||
<Compile Include="Interfaces\IRecentItem.cs" />
|
||||
<Compile Include="Interfaces\IResource.cs" />
|
||||
<Compile Include="Pages\MainPageFrames\DonatePage.xaml.cs">
|
||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Services\DatabaseService.cs" />
|
||||
<Compile Include="Services\MessageDialogService.cs" />
|
||||
<Compile Include="Interfaces\ISettings.cs" />
|
||||
<Compile Include="Common\MessageDialogHelper.cs" />
|
||||
<Compile Include="Common\NavigationHelper.cs" />
|
||||
<Compile Include="Common\NotifyPropertyChangedBase.cs" />
|
||||
<Compile Include="Common\ObservableDictionary.cs" />
|
||||
<Compile Include="Common\RelayCommand.cs" />
|
||||
<Compile Include="Common\SuspensionManager.cs" />
|
||||
<Compile Include="Services\RecentService.cs" />
|
||||
<Compile Include="Services\ResourcesService.cs" />
|
||||
<Compile Include="Services\SettingsService.cs" />
|
||||
<Compile Include="Services\ToastNotificationService.cs" />
|
||||
<Compile Include="Common\ToastNotificationHelper.cs" />
|
||||
<Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" />
|
||||
<Compile Include="Converters\EmptyStringToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
||||
@@ -218,6 +224,7 @@
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<PRIResource Include="Strings\en-US\CodeBehind.resw" />
|
||||
<PRIResource Include="Strings\en-US\Resources.resw" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@@ -394,11 +394,11 @@
|
||||
</AppBarButton>
|
||||
</CommandBar.SecondaryCommands>
|
||||
<AppBarToggleButton Icon="Edit" Label="Edit" IsChecked="{Binding IsEditMode, Mode=TwoWay}">
|
||||
<!--<interactivity:Interaction.Behaviors>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Click">
|
||||
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>-->
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</AppBarToggleButton>
|
||||
<AppBarButton Icon="Undo" Label="Restore" Visibility="{Binding ParentGroup.IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
|
@@ -77,9 +77,9 @@ namespace ModernKeePass.Pages
|
||||
? "Are you sure you want to send this entry to the recycle bin?"
|
||||
: "Are you sure you want to delete this entry?";
|
||||
var text = isRecycleBinEnabled ? "Item moved to the Recycle bin" : "Item permanently removed";
|
||||
MessageDialogService.ShowActionDialog("Warning", message, "Delete", "Cancel", a =>
|
||||
MessageDialogHelper.ShowActionDialog("Warning", message, "Delete", "Cancel", a =>
|
||||
{
|
||||
ToastNotificationService.ShowMovedToast(Model, "Deleting", text);
|
||||
ToastNotificationHelper.ShowMovedToast(Model, "Deleting", text);
|
||||
Model.MarkForDelete();
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
});
|
||||
@@ -87,7 +87,7 @@ namespace ModernKeePass.Pages
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToastNotificationService.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||
ToastNotificationHelper.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace ModernKeePass.Pages
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageDialogService.ShowErrorDialog(ex);
|
||||
MessageDialogHelper.ShowErrorDialog(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -64,11 +64,11 @@
|
||||
</Button.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarToggleButton Icon="Edit" Label="Edit" IsChecked="{Binding IsEditMode, Mode=TwoWay}">
|
||||
<!--<interactivity:Interaction.Behaviors>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Click">
|
||||
<core:ChangePropertyAction TargetObject="{Binding ElementName=CommandBar}" PropertyName="IsOpen" Value="False" />
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>-->
|
||||
</interactivity:Interaction.Behaviors>
|
||||
</AppBarToggleButton>
|
||||
<AppBarButton Icon="Undo" Label="Restore" Visibility="{Binding ShowRestore, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
|
||||
<interactivity:Interaction.Behaviors>
|
||||
|
@@ -115,9 +115,9 @@ namespace ModernKeePass.Pages
|
||||
? "Are you sure you want to send the whole group and all its entries to the recycle bin?"
|
||||
: "Are you sure you want to delete the whole group and all its entries?";
|
||||
var text = isRecycleBinEnabled ? "Item moved to the Recycle bin" : "Item permanently removed";
|
||||
MessageDialogService.ShowActionDialog("Warning", message, "Delete", "Cancel", a =>
|
||||
MessageDialogHelper.ShowActionDialog("Warning", message, "Delete", "Cancel", a =>
|
||||
{
|
||||
ToastNotificationService.ShowMovedToast(Model, "Deleting", text);
|
||||
ToastNotificationHelper.ShowMovedToast(Model, "Deleting", text);
|
||||
Model.MarkForDelete();
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
});
|
||||
@@ -125,7 +125,7 @@ namespace ModernKeePass.Pages
|
||||
|
||||
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToastNotificationService.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||
ToastNotificationHelper.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||
if (Frame.CanGoBack) Frame.GoBack();
|
||||
}
|
||||
|
||||
|
@@ -18,7 +18,7 @@ namespace ModernKeePass.Pages
|
||||
|
||||
private void CompositeKeyUserControl_OnValidationChecked(object sender, PasswordEventArgs e)
|
||||
{
|
||||
ToastNotificationService.ShowGenericToast("Composite key", "Database successfully updated.");
|
||||
ToastNotificationHelper.ShowGenericToast("Composite key", "Database successfully updated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ namespace ModernKeePass.Services
|
||||
Opened = 2
|
||||
}
|
||||
private readonly PwDatabase _pwDatabase = new PwDatabase();
|
||||
private readonly ISettings _settings;
|
||||
private readonly IResource _resource;
|
||||
private StorageFile _databaseFile;
|
||||
private GroupVm _recycleBin;
|
||||
|
||||
@@ -77,7 +79,15 @@ namespace ModernKeePass.Services
|
||||
get { return _pwDatabase.KdfParameters; }
|
||||
set { _pwDatabase.KdfParameters = value; }
|
||||
}
|
||||
|
||||
|
||||
public DatabaseService() : this(new SettingsService())
|
||||
{ }
|
||||
|
||||
public DatabaseService(ISettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open a KeePass database
|
||||
/// </summary>
|
||||
@@ -99,8 +109,8 @@ namespace ModernKeePass.Services
|
||||
_pwDatabase.New(ioConnection, key);
|
||||
|
||||
//Get settings default values
|
||||
if (SettingsService.GetSetting<bool>("Sample")) CreateSampleData();
|
||||
var fileFormat = SettingsService.GetSetting<string>("DefaultFileFormat");
|
||||
if (_settings.GetSetting<bool>("Sample")) CreateSampleData();
|
||||
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
|
||||
switch (fileFormat)
|
||||
{
|
||||
case "4":
|
||||
|
45
ModernKeePass/Services/RecentService.cs
Normal file
45
ModernKeePass/Services/RecentService.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using ModernKeePass.Interfaces;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.AccessCache;
|
||||
using ModernKeePass.ViewModels;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class RecentService : IRecent
|
||||
{
|
||||
private readonly StorageItemMostRecentlyUsedList _mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
|
||||
public int EntryCount => _mru.Entries.Count;
|
||||
|
||||
public ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true)
|
||||
{
|
||||
var result = new ObservableCollection<IRecentItem>();
|
||||
foreach (var entry in _mru.Entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = _mru.GetFileAsync(entry.Token, AccessCacheOptions.SuppressAccessTimeUpdate).GetAwaiter().GetResult();
|
||||
result.Add(new RecentItemVm(entry.Token, entry.Metadata, file));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (removeIfNonExistant) _mru.Remove(entry.Token);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Add(IStorageItem file, string metadata)
|
||||
{
|
||||
_mru.Add(file, metadata);
|
||||
}
|
||||
|
||||
public async Task<IStorageItem> GetFileAsync(string token)
|
||||
{
|
||||
return await _mru.GetFileAsync(token);
|
||||
}
|
||||
}
|
||||
}
|
17
ModernKeePass/Services/ResourcesService.cs
Normal file
17
ModernKeePass/Services/ResourcesService.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class ResourcesService: IResource
|
||||
{
|
||||
private const string ResourceFileName = "CodeBehind";
|
||||
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
||||
|
||||
public string GetResourceValue(string key)
|
||||
{
|
||||
var resource = _resourceLoader.GetString($"/{ResourceFileName}/{key}");
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,15 +1,19 @@
|
||||
using System;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.Storage;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePass.Services
|
||||
{
|
||||
public class SettingsService
|
||||
public class SettingsService : ISettings
|
||||
{
|
||||
public static T GetSetting<T>(string property)
|
||||
private readonly IPropertySet _values = ApplicationData.Current.LocalSettings.Values;
|
||||
|
||||
public T GetSetting<T>(string property)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T)Convert.ChangeType(ApplicationData.Current.LocalSettings.Values[property], typeof(T));
|
||||
return (T)Convert.ChangeType(_values[property], typeof(T));
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
@@ -17,12 +21,11 @@ namespace ModernKeePass.Services
|
||||
}
|
||||
}
|
||||
|
||||
public static void PutSetting<T>(string property, T value)
|
||||
public void PutSetting<T>(string property, T value)
|
||||
{
|
||||
var localSettings = ApplicationData.Current.LocalSettings;
|
||||
if (localSettings.Values.ContainsKey(property))
|
||||
localSettings.Values[property] = value;
|
||||
else localSettings.Values.Add(property, value);
|
||||
if (_values.ContainsKey(property))
|
||||
_values[property] = value;
|
||||
else _values.Add(property, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
183
ModernKeePass/Strings/en-US/CodeBehind.resw
Normal file
183
ModernKeePass/Strings/en-US/CodeBehind.resw
Normal file
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="CompositeKeyDefaultKeyFile" xml:space="preserve">
|
||||
<value>Select key file from disk...</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorOpen" xml:space="preserve">
|
||||
<value>Error</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserKeyFile" xml:space="preserve">
|
||||
<value>key file</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserOr" xml:space="preserve">
|
||||
<value> or </value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserPassword" xml:space="preserve">
|
||||
<value>password</value>
|
||||
</data>
|
||||
<data name="CompositeKeyErrorUserStart" xml:space="preserve">
|
||||
<value>Error: wrong </value>
|
||||
</data>
|
||||
<data name="CompositeKeyUpdated" xml:space="preserve">
|
||||
<value>Database composite key updated.</value>
|
||||
</data>
|
||||
<data name="EntryNew" xml:space="preserve">
|
||||
<value>< New entry ></value>
|
||||
</data>
|
||||
<data name="GroupNew" xml:space="preserve">
|
||||
<value>< New group ></value>
|
||||
</data>
|
||||
<data name="MainMenuItemAbout" xml:space="preserve">
|
||||
<value>About</value>
|
||||
</data>
|
||||
<data name="MainMenuItemDonate" xml:space="preserve">
|
||||
<value>Donate</value>
|
||||
</data>
|
||||
<data name="MainMenuItemNew" xml:space="preserve">
|
||||
<value>New</value>
|
||||
</data>
|
||||
<data name="MainMenuItemOpen" xml:space="preserve">
|
||||
<value>Open</value>
|
||||
</data>
|
||||
<data name="MainMenuItemRecent" xml:space="preserve">
|
||||
<value>Recent</value>
|
||||
</data>
|
||||
<data name="MainMenuItemSave" xml:space="preserve">
|
||||
<value>Save</value>
|
||||
</data>
|
||||
<data name="MainMenuItemSettings" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="SettingsMenuGroupApplication" xml:space="preserve">
|
||||
<value>Application</value>
|
||||
</data>
|
||||
<data name="SettingsMenuGroupDatabase" xml:space="preserve">
|
||||
<value>Database</value>
|
||||
</data>
|
||||
<data name="SettingsMenuItemGeneral" xml:space="preserve">
|
||||
<value>General</value>
|
||||
</data>
|
||||
<data name="SettingsMenuItemNew" xml:space="preserve">
|
||||
<value>New</value>
|
||||
</data>
|
||||
<data name="SettingsMenuItemSecurity" xml:space="preserve">
|
||||
<value>Security</value>
|
||||
</data>
|
||||
</root>
|
@@ -29,7 +29,8 @@ namespace ModernKeePass.ViewModels
|
||||
private string _status;
|
||||
private StatusTypes _statusType;
|
||||
private StorageFile _keyFile;
|
||||
private string _keyFileText = "Select key file from disk...";
|
||||
private string _keyFileText;
|
||||
private readonly IResource _resource;
|
||||
|
||||
public IDatabase Database { get; set; }
|
||||
|
||||
@@ -100,10 +101,12 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public double PasswordComplexityIndicator => QualityEstimation.EstimatePasswordBits(Password?.ToCharArray());
|
||||
|
||||
public CompositeKeyVm() : this((Application.Current as App)?.Database) { }
|
||||
public CompositeKeyVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
|
||||
|
||||
public CompositeKeyVm(IDatabase database)
|
||||
public CompositeKeyVm(IDatabase database, IResource resource)
|
||||
{
|
||||
_resource = resource;
|
||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||
Database = database;
|
||||
}
|
||||
|
||||
@@ -116,18 +119,18 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = $"Error: {e.Message}";
|
||||
error = $"{_resource.GetResourceValue("CompositeKeyErrorOpen")}: {e.Message}";
|
||||
}
|
||||
switch ((DatabaseService.DatabaseStatus)Database.Status)
|
||||
{
|
||||
case DatabaseService.DatabaseStatus.Opened:
|
||||
await Task.Run( () => RootGroup = Database.RootGroup);
|
||||
await Task.Run(() => RootGroup = Database.RootGroup);
|
||||
return true;
|
||||
case DatabaseService.DatabaseStatus.CompositeKeyError:
|
||||
var errorMessage = new StringBuilder("Error: wrong ");
|
||||
if (HasPassword) errorMessage.Append("password");
|
||||
if (HasPassword && HasKeyFile) errorMessage.Append(" or ");
|
||||
if (HasKeyFile) errorMessage.Append("key file");
|
||||
var errorMessage = new StringBuilder(_resource.GetResourceValue("CompositeKeyErrorUserStart"));
|
||||
if (HasPassword) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserPassword"));
|
||||
if (HasPassword && HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserOr"));
|
||||
if (HasKeyFile) errorMessage.Append(_resource.GetResourceValue("CompositeKeyErrorUserKeyFile"));
|
||||
UpdateStatus(errorMessage.ToString(), StatusTypes.Error);
|
||||
break;
|
||||
case DatabaseService.DatabaseStatus.Error:
|
||||
@@ -140,7 +143,7 @@ namespace ModernKeePass.ViewModels
|
||||
public void UpdateKey()
|
||||
{
|
||||
Database.UpdateCompositeKey(CreateCompositeKey());
|
||||
UpdateStatus("Database composite key updated.", StatusTypes.Success);
|
||||
UpdateStatus(_resource.GetResourceValue("CompositeKeyUpdated"), StatusTypes.Success);
|
||||
}
|
||||
|
||||
public void CreateKeyFile(StorageFile file)
|
||||
|
@@ -5,6 +5,7 @@ using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Mappings;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePassLib;
|
||||
using ModernKeePassLib.Cryptography.PasswordGenerator;
|
||||
using ModernKeePassLib.Security;
|
||||
@@ -48,8 +49,9 @@ namespace ModernKeePass.ViewModels
|
||||
{
|
||||
get
|
||||
{
|
||||
var title = GetEntryValue(PwDefs.TitleField);
|
||||
return title == null ? "< New entry >" : title;
|
||||
/*var title = GetEntryValue(PwDefs.TitleField);
|
||||
return title == null ? _resource.GetResourceValue("EntryNew") : title;*/
|
||||
return GetEntryValue(PwDefs.TitleField);
|
||||
}
|
||||
set { SetEntryValue(PwDefs.TitleField, value); }
|
||||
}
|
||||
|
@@ -19,10 +19,10 @@ namespace ModernKeePass.ViewModels
|
||||
public GroupVm ParentGroup { get; private set; }
|
||||
public GroupVm PreviousGroup { get; private set; }
|
||||
public ObservableCollection<EntryVm> Entries { get; set; } = new ObservableCollection<EntryVm>();
|
||||
|
||||
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
||||
|
||||
public int EntryCount => Entries.Count() - 1;
|
||||
public int EntryCount => Entries.Count;
|
||||
// TODO: put in a converter
|
||||
public FontWeight FontWeight => _pwGroup == null ? FontWeights.Bold : FontWeights.Normal;
|
||||
public int GroupCount => Groups.Count - 1;
|
||||
public PwUuid IdUuid => _pwGroup?.Uuid;
|
||||
@@ -50,7 +50,7 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _pwGroup == null ? "< New group >" : _pwGroup.Name; }
|
||||
get { return _pwGroup == null ? string.Empty : _pwGroup.Name; }
|
||||
set { _pwGroup.Name = value; }
|
||||
}
|
||||
|
||||
@@ -86,10 +86,9 @@ namespace ModernKeePass.ViewModels
|
||||
private readonly IDatabase _database;
|
||||
private bool _isEditMode;
|
||||
private PwEntry _reorderedEntry;
|
||||
//private int _reorderedEntryIndex;
|
||||
|
||||
public GroupVm() {}
|
||||
|
||||
|
||||
internal GroupVm(PwGroup pwGroup, GroupVm parent, PwUuid recycleBinId = null) : this(pwGroup, parent,
|
||||
(Application.Current as App)?.Database, recycleBinId)
|
||||
{ }
|
||||
@@ -104,7 +103,7 @@ namespace ModernKeePass.ViewModels
|
||||
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)));
|
||||
Groups.Insert(0, new GroupVm ());
|
||||
Groups.Insert(0, new GroupVm());
|
||||
}
|
||||
|
||||
private void Entries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
@@ -148,7 +147,6 @@ namespace ModernKeePass.ViewModels
|
||||
Move(_database.RecycleBinEnabled && !IsSelected ? _database.RecycleBin : null);
|
||||
}
|
||||
|
||||
|
||||
public void UndoDelete()
|
||||
{
|
||||
Move(PreviousGroup);
|
||||
@@ -192,7 +190,7 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageDialogService.ShowErrorDialog(e);
|
||||
MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,7 +204,7 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageDialogService.ShowErrorDialog(e);
|
||||
MessageDialogHelper.ShowErrorDialog(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,24 +1,15 @@
|
||||
using System;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage;
|
||||
using ModernKeePass.Common;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel
|
||||
public class RecentItemVm: NotifyPropertyChangedBase, ISelectableModel, IRecentItem
|
||||
{
|
||||
private bool _isSelected;
|
||||
|
||||
public RecentItemVm() {}
|
||||
public RecentItemVm(AccessListEntry entry, StorageFile file)
|
||||
{
|
||||
Token = entry.Token;
|
||||
Name = entry.Metadata;
|
||||
DatabaseFile = file;
|
||||
}
|
||||
|
||||
|
||||
public StorageFile DatabaseFile { get; }
|
||||
public string Token { get; }
|
||||
public string Name { get; }
|
||||
@@ -30,6 +21,14 @@ namespace ModernKeePass.ViewModels
|
||||
set { SetProperty(ref _isSelected, value); }
|
||||
}
|
||||
|
||||
public RecentItemVm() {}
|
||||
public RecentItemVm(string token, string metadata, IStorageItem file)
|
||||
{
|
||||
Token = token;
|
||||
Name = metadata;
|
||||
DatabaseFile = file as StorageFile;
|
||||
}
|
||||
|
||||
public void OpenDatabaseFile()
|
||||
{
|
||||
OpenDatabaseFile((Application.Current as App)?.Database);
|
||||
@@ -40,10 +39,14 @@ namespace ModernKeePass.ViewModels
|
||||
database.DatabaseFile = DatabaseFile;
|
||||
}
|
||||
|
||||
public async void UpdateAccessTime()
|
||||
public void UpdateAccessTime()
|
||||
{
|
||||
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
await mru.GetFileAsync(Token);
|
||||
UpdateAccessTime(new RecentService());
|
||||
}
|
||||
|
||||
public async void UpdateAccessTime(IRecent recent)
|
||||
{
|
||||
await recent.GetFileAsync(Token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@ using ModernKeePassLib.Cryptography.KeyDerivation;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
// TODO: implement Kdf settings
|
||||
public class SettingsDatabaseVm: NotifyPropertyChangedBase, IHasSelectableObject
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
|
@@ -1,23 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class SettingsNewVm
|
||||
{
|
||||
private ISettings _settings;
|
||||
|
||||
public SettingsNewVm() : this(new SettingsService())
|
||||
{ }
|
||||
|
||||
public SettingsNewVm(ISettings settings)
|
||||
{
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public bool IsCreateSample
|
||||
{
|
||||
get { return SettingsService.GetSetting<bool>("Sample"); }
|
||||
set { SettingsService.PutSetting("Sample", value); }
|
||||
get { return _settings.GetSetting<bool>("Sample"); }
|
||||
set { _settings.PutSetting("Sample", value); }
|
||||
}
|
||||
|
||||
public IEnumerable<string> FileFormats => new []{"2", "4"};
|
||||
|
||||
public string FileFormatVersion
|
||||
{
|
||||
get { return SettingsService.GetSetting<string>("DefaultFileFormat"); }
|
||||
set { SettingsService.PutSetting("DefaultFileFormat", value); }
|
||||
get { return _settings.GetSetting<string>("DefaultFileFormat"); }
|
||||
set { _settings.PutSetting("DefaultFileFormat", value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using ModernKeePass.Common;
|
||||
@@ -46,40 +45,68 @@ namespace ModernKeePass.ViewModels
|
||||
|
||||
public MainVm() {}
|
||||
|
||||
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame, (Application.Current as App)?.Database) { }
|
||||
internal MainVm(Frame referenceFrame, Frame destinationFrame) : this(referenceFrame, destinationFrame,
|
||||
(Application.Current as App)?.Database, new ResourcesService(), new RecentService())
|
||||
{ }
|
||||
|
||||
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database)
|
||||
public MainVm(Frame referenceFrame, Frame destinationFrame, IDatabase database, IResource resource, IRecent recent)
|
||||
{
|
||||
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
var isDatabaseOpen = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opened;
|
||||
|
||||
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
|
||||
{
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = "Open", PageType = typeof(OpenDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Page2,
|
||||
Title = resource.GetResourceValue("MainMenuItemOpen"),
|
||||
PageType = typeof(OpenDatabasePage),
|
||||
Destination = destinationFrame,
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Page2,
|
||||
IsSelected = database != null && database.Status == (int) DatabaseService.DatabaseStatus.Opening
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = "New" , PageType = typeof(NewDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Add
|
||||
Title = resource.GetResourceValue("MainMenuItemNew"),
|
||||
PageType = typeof(NewDatabasePage),
|
||||
Destination = destinationFrame,
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Add
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = "Save" , PageType = typeof(SaveDatabasePage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Save,
|
||||
IsSelected = isDatabaseOpen, IsEnabled = isDatabaseOpen
|
||||
},
|
||||
new MainMenuItemVm {
|
||||
Title = "Recent" , PageType = typeof(RecentDatabasesPage), Destination = destinationFrame, Parameter = referenceFrame, SymbolIcon = Symbol.Copy,
|
||||
IsSelected = (database == null || database.Status == (int) DatabaseService.DatabaseStatus.Closed) && mru.Entries.Count > 0, IsEnabled = mru.Entries.Count > 0
|
||||
Title = resource.GetResourceValue("MainMenuItemSave"),
|
||||
PageType = typeof(SaveDatabasePage),
|
||||
Destination = destinationFrame,
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Save,
|
||||
IsSelected = isDatabaseOpen,
|
||||
IsEnabled = isDatabaseOpen
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = "Settings" , PageType = typeof(SettingsPage), Destination = referenceFrame, SymbolIcon = Symbol.Setting
|
||||
Title = resource.GetResourceValue("MainMenuItemRecent"),
|
||||
PageType = typeof(RecentDatabasesPage),
|
||||
Destination = destinationFrame,
|
||||
Parameter = referenceFrame,
|
||||
SymbolIcon = Symbol.Copy,
|
||||
IsSelected =
|
||||
(database == null || database.Status == (int) DatabaseService.DatabaseStatus.Closed) &&
|
||||
recent.EntryCount > 0,
|
||||
IsEnabled = recent.EntryCount > 0
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = "About" , PageType = typeof(AboutPage), Destination = destinationFrame, SymbolIcon = Symbol.Help
|
||||
Title = resource.GetResourceValue("MainMenuItemSettings"),
|
||||
PageType = typeof(SettingsPage),
|
||||
Destination = referenceFrame,
|
||||
SymbolIcon = Symbol.Setting
|
||||
},
|
||||
new MainMenuItemVm
|
||||
{
|
||||
Title = resource.GetResourceValue("MainMenuItemAbout"),
|
||||
PageType = typeof(AboutPage),
|
||||
Destination = destinationFrame,
|
||||
SymbolIcon = Symbol.Help
|
||||
}
|
||||
};
|
||||
// Auto-select the Recent Items menu item if the conditions are met
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Windows.UI.Xaml;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
@@ -23,19 +22,23 @@ namespace ModernKeePass.ViewModels
|
||||
if (database == null || database.Status != (int) DatabaseService.DatabaseStatus.Opening) return;
|
||||
OpenFile(database.DatabaseFile);
|
||||
}
|
||||
|
||||
|
||||
public void OpenFile(StorageFile file)
|
||||
{
|
||||
OpenFile(file, new RecentService());
|
||||
}
|
||||
|
||||
public void OpenFile(StorageFile file, IRecent recent)
|
||||
{
|
||||
_database.DatabaseFile = file;
|
||||
OnPropertyChanged("Name");
|
||||
OnPropertyChanged("ShowPasswordBox");
|
||||
AddToRecentList(file);
|
||||
AddToRecentList(file, recent);
|
||||
}
|
||||
|
||||
private void AddToRecentList(StorageFile file)
|
||||
private void AddToRecentList(StorageFile file, IRecent recent)
|
||||
{
|
||||
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
mru.Add(file, file.DisplayName);
|
||||
recent.Add(file, file.DisplayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,17 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Windows.Storage.AccessCache;
|
||||
using System.Collections.ObjectModel;
|
||||
using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
public class RecentVm : NotifyPropertyChangedBase, IHasSelectableObject
|
||||
{
|
||||
private ISelectableModel _selectedItem;
|
||||
private ObservableCollection<RecentItemVm> _recentItems = new ObservableCollection<RecentItemVm>();
|
||||
private ObservableCollection<IRecentItem> _recentItems = new ObservableCollection<IRecentItem>();
|
||||
|
||||
public ObservableCollection<RecentItemVm> RecentItems
|
||||
public ObservableCollection<IRecentItem> RecentItems
|
||||
{
|
||||
get { return _recentItems; }
|
||||
set { SetProperty(ref _recentItems, value); }
|
||||
@@ -35,23 +34,14 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public RecentVm()
|
||||
public RecentVm() : this (new RecentService())
|
||||
{ }
|
||||
|
||||
public RecentVm(IRecent recent)
|
||||
{
|
||||
var mru = StorageApplicationPermissions.MostRecentlyUsedList;
|
||||
foreach (var entry in mru.Entries)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = mru.GetFileAsync(entry.Token, AccessCacheOptions.SuppressAccessTimeUpdate).GetAwaiter().GetResult();
|
||||
RecentItems.Add(new RecentItemVm(entry, file));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
mru.Remove(entry.Token);
|
||||
}
|
||||
}
|
||||
RecentItems = recent.GetAllFiles();
|
||||
if (RecentItems.Count > 0)
|
||||
SelectedItem = RecentItems[0];
|
||||
SelectedItem = RecentItems[0] as RecentItemVm;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ using ModernKeePass.Common;
|
||||
using ModernKeePass.Interfaces;
|
||||
using ModernKeePass.Pages;
|
||||
using ModernKeePass.Pages.SettingsPageFrames;
|
||||
using ModernKeePass.Services;
|
||||
|
||||
namespace ModernKeePass.ViewModels
|
||||
{
|
||||
@@ -41,32 +42,32 @@ namespace ModernKeePass.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsVm() : this((Application.Current as App)?.Database) { }
|
||||
public SettingsVm() : this((Application.Current as App)?.Database, new ResourcesService()) { }
|
||||
|
||||
public SettingsVm(IDatabase database)
|
||||
public SettingsVm(IDatabase database, IResource resource)
|
||||
{
|
||||
var menuItems = new ObservableCollection<ListMenuItemVm>
|
||||
{
|
||||
new ListMenuItemVm
|
||||
{
|
||||
Title = "New",
|
||||
Group = "Application",
|
||||
Title = resource.GetResourceValue("SettingsMenuItemNew"),
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupApplication"),
|
||||
SymbolIcon = Symbol.Add,
|
||||
PageType = typeof(SettingsNewDatabasePage),
|
||||
IsSelected = true
|
||||
},
|
||||
new ListMenuItemVm
|
||||
{
|
||||
Title = "General",
|
||||
Group = "Database",
|
||||
Title = resource.GetResourceValue("SettingsMenuItemGeneral"),
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||
SymbolIcon = Symbol.Setting,
|
||||
PageType = typeof(SettingsDatabasePage),
|
||||
IsEnabled = database?.Status == 2
|
||||
},
|
||||
new ListMenuItemVm
|
||||
{
|
||||
Title = "Security",
|
||||
Group = "Database",
|
||||
Title = resource.GetResourceValue("SettingsMenuItemSecurity"),
|
||||
Group = resource.GetResourceValue("SettingsMenuGroupDatabase"),
|
||||
SymbolIcon = Symbol.Permissions,
|
||||
PageType = typeof(SettingsSecurityPage),
|
||||
IsEnabled = database?.Status == 2
|
||||
|
@@ -4,13 +4,14 @@ using Windows.Storage;
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using ModernKeePass.Services;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePassApp.Test.Mock;
|
||||
|
||||
namespace ModernKeePassApp.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class DatabaseTests
|
||||
{
|
||||
private readonly DatabaseService _database = new DatabaseService();
|
||||
private readonly DatabaseService _database = new DatabaseService(new SettingsServiceMock());
|
||||
|
||||
[TestMethod]
|
||||
public void TestCreate()
|
||||
@@ -47,12 +48,12 @@ namespace ModernKeePassApp.Test
|
||||
{
|
||||
_database.Open(null, createNew);
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.NoCompositeKey, _database.Status);
|
||||
var compositeKey = new CompositeKeyVm(_database)
|
||||
var compositeKey = new CompositeKeyVm(_database, new ResourceServiceMock())
|
||||
{
|
||||
HasPassword = true,
|
||||
Password = "test"
|
||||
};
|
||||
compositeKey.OpenDatabase(createNew);
|
||||
compositeKey.OpenDatabase(createNew).GetAwaiter().GetResult();
|
||||
Assert.AreEqual((int)DatabaseService.DatabaseStatus.Opened, _database.Status);
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ using Windows.Storage;
|
||||
|
||||
namespace ModernKeePassApp.Test.Mock
|
||||
{
|
||||
public class DatabaseHelperMock : IDatabase
|
||||
public class DatabaseServiceMock : IDatabase
|
||||
{
|
||||
public PwCompressionAlgorithm CompressionAlgorithm { get; set; }
|
||||
|
28
ModernKeePassApp.Test/Mock/RecentServiceMock.cs
Normal file
28
ModernKeePassApp.Test/Mock/RecentServiceMock.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using ModernKeePass.Interfaces;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace ModernKeePassApp.Test.Mock
|
||||
{
|
||||
class RecentServiceMock : IRecent
|
||||
{
|
||||
public int EntryCount => 0;
|
||||
|
||||
public void Add(IStorageItem file, string metadata)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ObservableCollection<IRecentItem> GetAllFiles(bool removeIfNonExistant = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IStorageItem> GetFileAsync(string token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
13
ModernKeePassApp.Test/Mock/ResourceServiceMock.cs
Normal file
13
ModernKeePassApp.Test/Mock/ResourceServiceMock.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePassApp.Test.Mock
|
||||
{
|
||||
class ResourceServiceMock : IResource
|
||||
{
|
||||
public string GetResourceValue(string key)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
18
ModernKeePassApp.Test/Mock/SettingsServiceMock.cs
Normal file
18
ModernKeePassApp.Test/Mock/SettingsServiceMock.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using ModernKeePass.Interfaces;
|
||||
|
||||
namespace ModernKeePassApp.Test.Mock
|
||||
{
|
||||
public class SettingsServiceMock : ISettings
|
||||
{
|
||||
public T GetSetting<T>(string property)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public void PutSetting<T>(string property, T value)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@@ -120,7 +120,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DatabaseTests.cs" />
|
||||
<Compile Include="Mock\DatabaseHelperMock.cs" />
|
||||
<Compile Include="Mock\DatabaseServiceMock.cs" />
|
||||
<Compile Include="Mock\RecentServiceMock.cs" />
|
||||
<Compile Include="Mock\ResourceServiceMock.cs" />
|
||||
<Compile Include="Mock\SettingsServiceMock.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ViewModelsTests.cs" />
|
||||
</ItemGroup>
|
||||
|
@@ -3,6 +3,8 @@ using System.Linq;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.Storage.AccessCache;
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using ModernKeePass.Pages;
|
||||
using ModernKeePass.Pages.SettingsPageFrames;
|
||||
using ModernKeePass.ViewModels;
|
||||
using ModernKeePassApp.Test.Mock;
|
||||
|
||||
@@ -11,6 +13,9 @@ namespace ModernKeePassApp.Test
|
||||
[TestClass]
|
||||
public class ViewModelsTests
|
||||
{
|
||||
private RecentServiceMock _recent = new RecentServiceMock();
|
||||
private ResourceServiceMock _resource = new ResourceServiceMock();
|
||||
|
||||
[TestMethod]
|
||||
public void TestAboutVm()
|
||||
{
|
||||
@@ -21,29 +26,30 @@ namespace ModernKeePassApp.Test
|
||||
[TestMethod]
|
||||
public void TestMainVm()
|
||||
{
|
||||
var database = new DatabaseHelperMock();
|
||||
var mainVm = new MainVm(null, null, database);
|
||||
var database = new DatabaseServiceMock();
|
||||
|
||||
var mainVm = new MainVm(null, null, database, _resource, _recent);
|
||||
Assert.AreEqual(1, mainVm.MainMenuItems.Count());
|
||||
var firstGroup = mainVm.MainMenuItems.FirstOrDefault();
|
||||
Assert.AreEqual(6, firstGroup.Count());
|
||||
|
||||
database.Status = 1;
|
||||
mainVm = new MainVm(null, null, database);
|
||||
mainVm = new MainVm(null, null, database, _resource, _recent);
|
||||
Assert.IsNotNull(mainVm.SelectedItem);
|
||||
Assert.AreEqual("Open", ((MainMenuItemVm) mainVm.SelectedItem).Title);
|
||||
Assert.AreEqual(typeof(OpenDatabasePage), ((MainMenuItemVm) mainVm.SelectedItem).PageType);
|
||||
|
||||
database.Status = 2;
|
||||
mainVm = new MainVm(null, null, database);
|
||||
mainVm = new MainVm(null, null, database, _resource, _recent);
|
||||
Assert.IsNotNull(mainVm.SelectedItem);
|
||||
Assert.AreEqual(2, mainVm.MainMenuItems.Count());
|
||||
Assert.AreEqual("Save", ((MainMenuItemVm) mainVm.SelectedItem).Title);
|
||||
Assert.AreEqual(typeof(SaveDatabasePage), ((MainMenuItemVm) mainVm.SelectedItem).PageType);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestCompositeKeyVm()
|
||||
{
|
||||
var database = new DatabaseHelperMock();
|
||||
var compositeKeyVm = new CompositeKeyVm(database);
|
||||
var database = new DatabaseServiceMock();
|
||||
var compositeKeyVm = new CompositeKeyVm(database, _resource);
|
||||
Assert.IsTrue(compositeKeyVm.OpenDatabase(false).GetAwaiter().GetResult());
|
||||
compositeKeyVm.StatusType = 1;
|
||||
compositeKeyVm.Password = "test";
|
||||
@@ -54,7 +60,7 @@ namespace ModernKeePassApp.Test
|
||||
[TestMethod]
|
||||
public void TestOpenVm()
|
||||
{
|
||||
var database = new DatabaseHelperMock
|
||||
var database = new DatabaseServiceMock
|
||||
{
|
||||
Status = 1,
|
||||
DatabaseFile = Package.Current.InstalledLocation.GetFileAsync(@"Databases\TestDatabase.kdbx")
|
||||
@@ -78,7 +84,7 @@ namespace ModernKeePassApp.Test
|
||||
.GetAwaiter().GetResult(), "MockDatabase");
|
||||
var recentVm = new RecentVm();
|
||||
Assert.IsTrue(recentVm.RecentItems.Count == 1);
|
||||
recentVm.SelectedItem = recentVm.RecentItems.FirstOrDefault();
|
||||
recentVm.SelectedItem = recentVm.RecentItems.FirstOrDefault() as RecentItemVm;
|
||||
Assert.IsTrue(recentVm.SelectedItem.IsSelected);
|
||||
mru.Clear();
|
||||
}
|
||||
@@ -91,13 +97,14 @@ namespace ModernKeePassApp.Test
|
||||
[TestMethod]
|
||||
public void TestSettingsVm()
|
||||
{
|
||||
var settingsVm = new SettingsVm();
|
||||
var settingsVm = new SettingsVm(new DatabaseServiceMock(), _resource);
|
||||
Assert.AreEqual(1, settingsVm.MenuItems.Count());
|
||||
var firstGroup = settingsVm.MenuItems.FirstOrDefault();
|
||||
Assert.AreEqual(1, firstGroup.Count());
|
||||
// All groups have an empty title, so all settings are put inside the empty group
|
||||
Assert.AreEqual(3, firstGroup.Count());
|
||||
Assert.IsNotNull(settingsVm.SelectedItem);
|
||||
var selectedItem = (ListMenuItemVm) settingsVm.SelectedItem;
|
||||
Assert.AreEqual("New", selectedItem.Title);
|
||||
Assert.AreEqual(typeof(SettingsNewDatabasePage), selectedItem.PageType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user