WIP removing global databaseFile property

This commit is contained in:
BONNEVILLE Geoffroy
2018-06-19 18:47:37 +02:00
parent b456e56789
commit 408b4eed90
18 changed files with 166 additions and 123 deletions

View File

@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
@@ -47,15 +49,28 @@ namespace ModernKeePass
? exception.InnerException
: exception;
var database = DatabaseService.Instance;
var resource = new ResourcesService();
if (realException is SaveException)
{
unhandledExceptionEventArgs.Handled = true;
MessageDialogHelper.SaveErrorDialog(realException as SaveException, DatabaseService.Instance);
}
else if (realException is DatabaseOpenedException)
{
unhandledExceptionEventArgs.Handled = true;
MessageDialogHelper.SaveUnchangedDialog(realException as DatabaseOpenedException, DatabaseService.Instance);
MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("MessageDialogSaveErrorTitle"),
realException.InnerException.Message,
resource.GetResourceValue("MessageDialogSaveErrorButtonSaveAs"),
resource.GetResourceValue("MessageDialogSaveErrorButtonDiscard"),
async command =>
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = $"{database.Name} - copy"
};
savePicker.FileTypeChoices.Add(resource.GetResourceValue("MessageDialogSaveErrorFileTypeDesc"),
new List<string> {".kdbx"});
var file = await savePicker.PickSaveFileAsync();
if (file != null) database.Save(file);
}, null);
}
}
@@ -110,17 +125,9 @@ namespace ModernKeePass
}
var lauchActivatedEventArgs = e as LaunchActivatedEventArgs;
if (lauchActivatedEventArgs != null)
{
if (rootFrame.Content == null)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(MainPage), lauchActivatedEventArgs.Arguments);
}
}
if (lauchActivatedEventArgs != null && rootFrame.Content == null)
rootFrame.Navigate(typeof(MainPage), lauchActivatedEventArgs.Arguments);
// Ensure the current window is active
Window.Current.Activate();
}
@@ -129,7 +136,7 @@ namespace ModernKeePass
{
var currentFrame = Window.Current.Content as Frame;
var database = DatabaseService.Instance;
if (database.DatabaseFile == null)
if (!database.IsOpen)
{
#if DEBUG
ToastNotificationHelper.ShowGenericToast("App suspended", "Nothing to do, no previous database opened");
@@ -191,8 +198,8 @@ namespace ModernKeePass
{
base.OnFileActivated(args);
var rootFrame = new Frame();
DatabaseService.Instance.DatabaseFile = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(MainPage), args);
var file = args.Files[0] as StorageFile;
rootFrame.Navigate(typeof(OpenDatabasePage), file);
Window.Current.Content = rootFrame;
Window.Current.Activate();
}

View File

@@ -1,15 +1,10 @@
using System;
using System.Collections.Generic;
using Windows.Storage.Pickers;
using Windows.UI.Popups;
using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces;
namespace ModernKeePass.Common
{
public static class MessageDialogHelper
{
// TODO: include resources
public static async void ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler actionCommand, UICommandInvokedHandler cancelCommand)
{
// Create the message dialog and set its content
@@ -21,36 +16,7 @@ namespace ModernKeePass.Common
// Show the message dialog
await messageDialog.ShowAsync();
}
public static void SaveErrorDialog(SaveException exception, IDatabaseService database)
{
ShowActionDialog("Save error", exception.InnerException.Message, "Save as", "Discard", async command =>
{
var savePicker = new FileSavePicker
{
SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
SuggestedFileName = $"{database.DatabaseFile.DisplayName} - copy"
};
savePicker.FileTypeChoices.Add("KeePass 2.x database", new List<string> { ".kdbx" });
var file = await savePicker.PickSaveFileAsync();
if (file != null) database.Save(file);
}, null);
}
public static void SaveUnchangedDialog(DatabaseOpenedException exception, IDatabaseService database)
{
ShowActionDialog("Opened database", $"Database {database.Name} is currently opened. What to you wish to do?", "Save changes", "Discard", command =>
{
database.Save();
database.Close();
},
command =>
{
database.Close();
});
}
public static async void ShowErrorDialog(Exception exception)
{
if (exception == null) return;

View File

@@ -1,5 +1,4 @@
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage;
using ModernKeePass.ViewModels;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.KeyDerivation;
@@ -13,17 +12,14 @@ namespace ModernKeePass.Interfaces
bool RecycleBinEnabled { get; set; }
GroupVm RootGroup { get; set; }
GroupVm RecycleBin { get; set; }
StorageFile DatabaseFile { get; set; }
CompositeKey CompositeKey { get; set; }
PwUuid DataCipher { get; set; }
PwCompressionAlgorithm CompressionAlgorithm { get; set; }
KdfParameters KeyDerivation { get; set; }
bool IsOpen { get; }
bool IsFileOpen { get; }
bool IsClosed { get; }
bool HasChanged { get; set; }
void Open(CompositeKey key, bool createNew = false);
void Open(StorageFile databaseFile, CompositeKey key, bool createNew = false);
void ReOpen();
void Save();
void Save(StorageFile file);

View File

@@ -33,26 +33,13 @@ namespace ModernKeePass.Services
}
}
public string Name => DatabaseFile?.Name;
public string Name => _databaseFile?.Name;
public bool RecycleBinEnabled
{
get { return _pwDatabase.RecycleBinEnabled; }
set { _pwDatabase.RecycleBinEnabled = value; }
}
public StorageFile DatabaseFile
{
get { return _databaseFile; }
set
{
if (IsOpen && HasChanged)
{
throw new DatabaseOpenedException();
}
_databaseFile = value;
}
}
public CompositeKey CompositeKey { get; set; }
@@ -92,10 +79,11 @@ namespace ModernKeePass.Services
/// <summary>
/// Open a KeePass database
/// </summary>
/// <param name="databaseFile">The database file</param>
/// <param name="key">The database composite key</param>
/// <param name="createNew">True to create a new database before opening it</param>
/// <returns>An error message, if any</returns>
public void Open(CompositeKey key, bool createNew = false)
public void Open(StorageFile databaseFile, CompositeKey key, bool createNew = false)
{
try
{
@@ -105,7 +93,7 @@ namespace ModernKeePass.Services
}
CompositeKey = key;
var ioConnection = IOConnectionInfo.FromFile(DatabaseFile);
var ioConnection = IOConnectionInfo.FromFile(databaseFile);
if (createNew)
{
_pwDatabase.New(ioConnection, key);
@@ -121,7 +109,8 @@ namespace ModernKeePass.Services
}
}
else _pwDatabase.Open(ioConnection, key, new NullStatusLogger());
_databaseFile = databaseFile;
RootGroup = new GroupVm(_pwDatabase.RootGroup, null, RecycleBinEnabled ? _pwDatabase.RecycleBinUuid : null);
}
catch (InvalidCompositeKeyException ex)
@@ -133,7 +122,7 @@ namespace ModernKeePass.Services
public void ReOpen()
{
Open(CompositeKey);
Open(_databaseFile, CompositeKey);
}
/// <summary>
@@ -158,15 +147,15 @@ namespace ModernKeePass.Services
/// <param name="file">The new database file</param>
public void Save(StorageFile file)
{
var oldFile = DatabaseFile;
DatabaseFile = file;
var oldFile = _databaseFile;
_databaseFile = file;
try
{
_pwDatabase.SaveAs(IOConnectionInfo.FromFile(DatabaseFile), true, new NullStatusLogger());
_pwDatabase.SaveAs(IOConnectionInfo.FromFile(_databaseFile), true, new NullStatusLogger());
}
catch
{
DatabaseFile = oldFile;
_databaseFile = oldFile;
throw;
}
}
@@ -177,7 +166,7 @@ namespace ModernKeePass.Services
public void Close(bool releaseFile = true)
{
_pwDatabase?.Close();
if (releaseFile) DatabaseFile = null;
if (releaseFile) _databaseFile = null;
}
public void AddDeletedItem(PwUuid id)

View File

@@ -270,4 +270,28 @@
<data name="EntryCurrent" xml:space="preserve">
<value>Current</value>
</data>
<data name="MessageDialogDBOpenButtonDiscard" xml:space="preserve">
<value>Discard</value>
</data>
<data name="MessageDialogDBOpenButtonSave" xml:space="preserve">
<value>Save changes</value>
</data>
<data name="MessageDialogDBOpenDesc" xml:space="preserve">
<value>Database {0} is currently opened. What would you wish to do?</value>
</data>
<data name="MessageDialogDBOpenTitle" xml:space="preserve">
<value>Opened database</value>
</data>
<data name="MessageDialogSaveErrorButtonDiscard" xml:space="preserve">
<value>Discard</value>
</data>
<data name="MessageDialogSaveErrorButtonSaveAs" xml:space="preserve">
<value>Save as</value>
</data>
<data name="MessageDialogSaveErrorFileTypeDesc" xml:space="preserve">
<value>KeePass 2.x database</value>
</data>
<data name="MessageDialogSaveErrorTitle" xml:space="preserve">
<value>Save error</value>
</data>
</root>

View File

@@ -270,4 +270,28 @@
<data name="EntryCurrent" xml:space="preserve">
<value>Courante</value>
</data>
<data name="MessageDialogDBOpenButtonDiscard" xml:space="preserve">
<value>Abandonner</value>
</data>
<data name="MessageDialogDBOpenButtonSave" xml:space="preserve">
<value>Sauvegarder</value>
</data>
<data name="MessageDialogDBOpenDesc" xml:space="preserve">
<value>La base de données {0} est actuellement ouverte. Que souhaitez-vous faire ?</value>
</data>
<data name="MessageDialogDBOpenTitle" xml:space="preserve">
<value>Base de données ouverte</value>
</data>
<data name="MessageDialogSaveErrorButtonDiscard" xml:space="preserve">
<value>Abandonner</value>
</data>
<data name="MessageDialogSaveErrorButtonSaveAs" xml:space="preserve">
<value>Sauvegarder sous</value>
</data>
<data name="MessageDialogSaveErrorFileTypeDesc" xml:space="preserve">
<value>Base de données KeePass 2.x</value>
</data>
<data name="MessageDialogSaveErrorTitle" xml:space="preserve">
<value>Erreur de sauvegarde</value>
</data>
</root>

View File

@@ -3,6 +3,7 @@ using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using ModernKeePass.Common;
using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePassLib.Cryptography;
@@ -120,12 +121,12 @@ namespace ModernKeePass.ViewModels
Database = database;
}
public async Task<bool> OpenDatabase(bool createNew)
public async Task<bool> OpenDatabase(StorageFile databaseFile, bool createNew)
{
try
{
_isOpening = true;
Database.Open(CreateCompositeKey(), createNew);
Database.Open(databaseFile, CreateCompositeKey(), createNew);
await Task.Run(() => RootGroup = Database.RootGroup);
return true;
}

View File

@@ -27,17 +27,7 @@ namespace ModernKeePass.ViewModels
Name = metadata;
DatabaseFile = file as StorageFile;
}
public void OpenDatabaseFile()
{
OpenDatabaseFile(DatabaseService.Instance);
}
public void OpenDatabaseFile(IDatabaseService database)
{
database.DatabaseFile = DatabaseFile;
}
public void UpdateAccessTime()
{
UpdateAccessTime(RecentService.Instance);

View File

@@ -60,8 +60,7 @@ namespace ModernKeePass.ViewModels
PageType = typeof(OpenDatabasePage),
Destination = destinationFrame,
Parameter = referenceFrame,
SymbolIcon = Symbol.Page2,
IsSelected = database != null && database.IsFileOpen && !database.IsOpen
SymbolIcon = Symbol.Page2
},
new MainMenuItemVm
{
@@ -89,7 +88,7 @@ namespace ModernKeePass.ViewModels
Parameter = referenceFrame,
SymbolIcon = Symbol.Copy,
IsSelected =
(database == null || database.IsClosed) &&
(database == null || !database.IsOpen) &&
recent.EntryCount > 0,
IsEnabled = recent.EntryCount > 0
},

View File

@@ -7,19 +7,18 @@ namespace ModernKeePass.ViewModels
{
public class OpenVm: NotifyPropertyChangedBase
{
public bool ShowPasswordBox => _database.IsFileOpen;
public bool IsFileSelected => DatabaseFile != null;
public string Name => _database?.Name;
public string Name => DatabaseFile.DisplayName;
private readonly IDatabaseService _database;
public StorageFile DatabaseFile { get; private set; }
public OpenVm() : this(DatabaseService.Instance) { }
public OpenVm() : this(null) { }
public OpenVm(IDatabaseService database)
public OpenVm(StorageFile file)
{
_database = database;
if (database == null || !database.IsFileOpen) return;
OpenFile(database.DatabaseFile);
if (!IsFileSelected) return;
OpenFile(file);
}
public void OpenFile(StorageFile file)
@@ -29,9 +28,9 @@ namespace ModernKeePass.ViewModels
public void OpenFile(StorageFile file, IRecentService recent)
{
_database.DatabaseFile = file;
DatabaseFile = file;
OnPropertyChanged("Name");
OnPropertyChanged("ShowPasswordBox");
OnPropertyChanged("IsFileSelected");
AddToRecentList(file, recent);
}

View File

@@ -23,6 +23,7 @@ namespace ModernKeePass.Views
private new void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
base.ListView_SelectionChanged(sender, e);
var selectedItem = Model.SelectedItem as MainMenuItemVm;
if (selectedItem == null) MenuFrame.Navigate(typeof(WelcomePage));
else selectedItem.Destination.Navigate(selectedItem.PageType, selectedItem.Parameter);

View File

@@ -23,7 +23,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl CreateNew="True" x:Uid="CompositeKeyNewButton">
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ValidationChecked">
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />

View File

@@ -24,7 +24,7 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding ShowPasswordBox, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton">
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyOpenButton" DatabaseFile="{Binding DatabaseFile}">
<interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="ValidationChecked">
<Core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" />

View File

@@ -1,7 +1,7 @@
using System;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using ModernKeePass.ViewModels;
@@ -14,8 +14,6 @@ namespace ModernKeePass.Views
/// </summary>
public sealed partial class OpenDatabasePage
{
private Frame _mainFrame;
public OpenVm Model => (OpenVm)DataContext;
public OpenDatabasePage()
@@ -26,7 +24,11 @@ namespace ModernKeePass.Views
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
_mainFrame = e.Parameter as Frame;
var file = e.Parameter as StorageFile;
if (file != null)
{
Model.OpenFile(file);
}
}
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)

View File

@@ -45,8 +45,8 @@
Foreground="{Binding PasswordComplexityIndicator, ConverterParameter=128, Converter={StaticResource DoubleToForegroungBrushConverter}}"
Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" />
<CheckBox Grid.Row="1" Grid.Column="0" IsChecked="{Binding HasKeyFile, Mode=TwoWay}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding HasKeyFile}" Click="CreateKeyFileButton_Click">
<HyperlinkButton Grid.Row="1" Grid.Column="1" Margin="-15,0,0,0" Content="{Binding KeyFileText}" IsEnabled="{Binding HasKeyFile}" Click="KeyFileButton_Click" Style="{StaticResource MainColorHyperlinkButton}" />
<HyperlinkButton Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding ShowComplexityIndicator, ElementName=UserControl, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding HasKeyFile}" Style="{StaticResource MainColorHyperlinkButton}" Click="CreateKeyFileButton_Click">
<SymbolIcon Symbol="Add">
<ToolTipService.ToolTip>
<ToolTip x:Uid="CompositeKeyNewKeyFileTooltip" />

View File

@@ -1,11 +1,15 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;
using ModernKeePass.Common;
using ModernKeePass.Events;
using ModernKeePass.Extensions;
using ModernKeePass.Interfaces;
using ModernKeePass.Services;
using ModernKeePass.ViewModels;
@@ -53,6 +57,17 @@ namespace ModernKeePass.Views.UserControls
typeof(CompositeKeyUserControl),
new PropertyMetadata("OK", (o, args) => { }));
public StorageFile DatabaseFile
{
get { return (StorageFile)GetValue(DatabaseFileProperty); }
set { SetValue(DatabaseFileProperty, value); }
}
public static readonly DependencyProperty DatabaseFileProperty =
DependencyProperty.Register(
"DatabaseFile",
typeof(StorageFile),
typeof(CompositeKeyUserControl),
new PropertyMetadata(null, (o, args) => { }));
public bool ShowComplexityIndicator => CreateNew || UpdateKey;
@@ -77,14 +92,30 @@ namespace ModernKeePass.Views.UserControls
}
else
{
var database = DatabaseService.Instance;
var resource = new ResourcesService();
var oldLabel = ButtonLabel;
ButtonLabel = resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(CreateNew)))
if (database.IsOpen)
{
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("MessageDialogDBOpenTitle"),
string.Format(resource.GetResourceValue("MessageDialogDBOpenDesc"), database.Name),
resource.GetResourceValue("MessageDialogDBOpenButtonSave"),
resource.GetResourceValue("MessageDialogDBOpenButtonDiscard"),
async command =>
{
database.Save();
database.Close(false);
await OpenDatabase(resource);
},
async command =>
{
database.Close(false);
await OpenDatabase(resource);
});
}
else
{
await OpenDatabase(resource);
}
ButtonLabel = oldLabel;
}
}
@@ -128,5 +159,17 @@ namespace ModernKeePass.Views.UserControls
Model.CreateKeyFile(file);
}
private async Task OpenDatabase(IResourceService resource)
{
var oldLabel = ButtonLabel;
ButtonLabel = resource.GetResourceValue("CompositeKeyOpening");
if (await Dispatcher.RunTaskAsync(async () => await Model.OpenDatabase(DatabaseFile, CreateNew)))
{
ValidationChecked?.Invoke(this, new PasswordEventArgs(Model.RootGroup));
}
ButtonLabel = oldLabel;
}
}
}

View File

@@ -1,2 +1,3 @@
Entry history feature added
Design improvements
KeePassLib version bump to 2.39.1

View File

@@ -1,2 +1,3 @@
Ajout de la fonctionnalite d'historique des entrees
Ameliorations de design
Version de la KeePassLib passe a 2.39.1