diff --git a/ModernKeePass/Actions/SetupFocusAction.cs b/ModernKeePass/Actions/SetupFocusAction.cs new file mode 100644 index 0000000..4dcf00f --- /dev/null +++ b/ModernKeePass/Actions/SetupFocusAction.cs @@ -0,0 +1,23 @@ +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Microsoft.Xaml.Interactivity; + +namespace ModernKeePass.Actions +{ + public class SetupFocusAction : DependencyObject, IAction + { + public Control TargetObject + { + get { return (Control)GetValue(TargetObjectProperty); } + set { SetValue(TargetObjectProperty, value); } + } + + public static readonly DependencyProperty TargetObjectProperty = + DependencyProperty.Register("TargetObject", typeof(Control), typeof(SetupFocusAction), new PropertyMetadata(0)); + + public object Execute(object sender, object parameter) + { + return TargetObject?.Focus(FocusState.Programmatic); + } + } +} \ No newline at end of file diff --git a/ModernKeePass/App.xaml.cs b/ModernKeePass/App.xaml.cs index f048081..970952c 100644 --- a/ModernKeePass/App.xaml.cs +++ b/ModernKeePass/App.xaml.cs @@ -98,7 +98,7 @@ namespace ModernKeePass private void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); - // TODO: save state? + //TODO: Save application state and stop any background activity //Database.Save(); deferral.Complete(); } @@ -106,11 +106,11 @@ namespace ModernKeePass protected override void OnFileActivated(FileActivatedEventArgs args) { base.OnFileActivated(args); - Database.DatabaseFile = args.Files[0] as StorageFile; + /*Database.DatabaseFile = args.Files[0] as StorageFile; var rootFrame = new Frame(); rootFrame.Navigate(typeof(MainPage), args); Window.Current.Content = rootFrame; - Window.Current.Activate(); + Window.Current.Activate();*/ } } } diff --git a/ModernKeePass/Common/DatabaseHelper.cs b/ModernKeePass/Common/DatabaseHelper.cs index 01c8fc7..247a317 100644 --- a/ModernKeePass/Common/DatabaseHelper.cs +++ b/ModernKeePass/Common/DatabaseHelper.cs @@ -17,31 +17,22 @@ namespace ModernKeePass.Common Opened = 2 } private readonly PwDatabase _pwDatabase = new PwDatabase(); - private StorageFile _databaseFile; public GroupVm RootGroup { get; set; } public DatabaseStatus Status { get; private set; } = DatabaseStatus.Closed; - public string Name => DatabaseFile.Name; - - public StorageFile DatabaseFile - { - get { return _databaseFile; } - set - { - _databaseFile = value; - Status = DatabaseStatus.Opening; - } - } - public string Open(string password) + + public string Name { get; private set; } + public string Open(StorageFile databaseFile, string password) { var key = new CompositeKey(); try { key.AddUserKey(new KcpPassword(password)); - _pwDatabase.Open(IOConnectionInfo.FromFile(DatabaseFile), key, new NullStatusLogger()); + _pwDatabase.Open(IOConnectionInfo.FromFile(databaseFile), key, new NullStatusLogger()); if (_pwDatabase.IsOpen) { + Name = databaseFile.Name; Status = DatabaseStatus.Opened; RootGroup = new GroupVm(_pwDatabase.RootGroup, null); } diff --git a/ModernKeePass/Controls/OpenDatabaseUserControl.xaml.cs b/ModernKeePass/Controls/OpenDatabaseUserControl.xaml.cs index 14b705a..502a8cb 100644 --- a/ModernKeePass/Controls/OpenDatabaseUserControl.xaml.cs +++ b/ModernKeePass/Controls/OpenDatabaseUserControl.xaml.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Windows.Storage; using Windows.System; using Windows.UI.Core; using Windows.UI.Xaml; @@ -13,6 +14,18 @@ namespace ModernKeePass.Controls { public sealed partial class OpenDatabaseUserControl : UserControl { + public StorageFile DatabaseFile + { + get { return (StorageFile)GetValue(DatabaseFileProperty); } + set { SetValue(DatabaseFileProperty, value); } + } + public static readonly DependencyProperty DatabaseFileProperty = + DependencyProperty.Register( + "DatabaseFile", + typeof(StorageFile), + typeof(OpenDatabaseUserControl), + new PropertyMetadata(null, (o, args) => { })); + public OpenDatabaseUserControl() { InitializeComponent(); @@ -24,7 +37,7 @@ namespace ModernKeePass.Controls private void OpenButton_OnClick(object sender, RoutedEventArgs e) { var app = (App)Application.Current; - StatusTextBlock.Text = app.Database.Open(PasswordBox.Password); + StatusTextBlock.Text = app.Database.Open(DatabaseFile, PasswordBox.Password); if (app.Database.Status == DatabaseHelper.DatabaseStatus.Opened) ValidationChecked?.Invoke(this, new PasswordEventArgs(app.Database.RootGroup)); } diff --git a/ModernKeePass/ModernKeePass.csproj b/ModernKeePass/ModernKeePass.csproj index b8de761..e8866e7 100644 --- a/ModernKeePass/ModernKeePass.csproj +++ b/ModernKeePass/ModernKeePass.csproj @@ -107,6 +107,7 @@ true + App.xaml diff --git a/ModernKeePass/Pages/EntryDetailPage.xaml.cs b/ModernKeePass/Pages/EntryDetailPage.xaml.cs index d17f8a1..c15b01f 100644 --- a/ModernKeePass/Pages/EntryDetailPage.xaml.cs +++ b/ModernKeePass/Pages/EntryDetailPage.xaml.cs @@ -1,4 +1,5 @@ using System; +using Windows.UI.Popups; using ModernKeePass.Common; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; @@ -25,9 +26,9 @@ namespace ModernKeePass.Pages public EntryDetailPage() { - this.InitializeComponent(); - this.navigationHelper = new NavigationHelper(this); - this.navigationHelper.LoadState += navigationHelper_LoadState; + InitializeComponent(); + navigationHelper = new NavigationHelper(this); + navigationHelper.LoadState += navigationHelper_LoadState; } /// @@ -70,11 +71,28 @@ namespace ModernKeePass.Pages #endregion - private void AppBarButton_Click(object sender, RoutedEventArgs e) + private async void AppBarButton_Click(object sender, RoutedEventArgs e) { - var entry = DataContext as EntryVm; - entry?.RemoveEntry(); - if (Frame.CanGoBack) Frame.GoBack(); + // Create the message dialog and set its content + var messageDialog = new MessageDialog("Are you sure you want to delete this entry?"); + + // Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers + messageDialog.Commands.Add(new UICommand("Delete", delete => + { + var entry = DataContext as EntryVm; + entry?.RemoveEntry(); + if (Frame.CanGoBack) Frame.GoBack(); + })); + messageDialog.Commands.Add(new UICommand("Cancel")); + + // Set the command that will be invoked by default + messageDialog.DefaultCommandIndex = 1; + + // Set the command to be invoked when escape is pressed + messageDialog.CancelCommandIndex = 1; + + // Show the message dialog + await messageDialog.ShowAsync(); } private async void UrlButton_Click(object sender, RoutedEventArgs e) diff --git a/ModernKeePass/Pages/GroupDetailPage.xaml.cs b/ModernKeePass/Pages/GroupDetailPage.xaml.cs index ed8bb79..2f2b686 100644 --- a/ModernKeePass/Pages/GroupDetailPage.xaml.cs +++ b/ModernKeePass/Pages/GroupDetailPage.xaml.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Windows.Storage.Streams; +using Windows.UI.Popups; using ModernKeePass.Common; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; @@ -68,6 +69,9 @@ namespace ModernKeePass.Pages #endregion + + #region Event Handlers + private void groups_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (LeftListView.SelectedIndex == 0) @@ -99,13 +103,30 @@ namespace ModernKeePass.Pages Frame.Navigate(typeof(EntryDetailPage), GridView.SelectedItem as EntryVm); } - private void DeleteButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) + private async void DeleteButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) { - var group = DataContext as GroupVm; - group?.RemoveGroup(); - if (Frame.CanGoBack) Frame.GoBack(); - } + // Create the message dialog and set its content + var messageDialog = new MessageDialog("Are you sure you want to delete the whole group and all its entries?"); + // Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers + messageDialog.Commands.Add(new UICommand("Delete", delete => + { + var group = DataContext as GroupVm; + group?.RemoveGroup(); + if (Frame.CanGoBack) Frame.GoBack(); + })); + messageDialog.Commands.Add(new UICommand("Cancel")); + + // Set the command that will be invoked by default + messageDialog.DefaultCommandIndex = 1; + + // Set the command to be invoked when escape is pressed + messageDialog.CancelCommandIndex = 1; + + // Show the message dialog + await messageDialog.ShowAsync(); + } + private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e) { if (e.IsSourceZoomedInView == false) @@ -131,5 +152,8 @@ namespace ModernKeePass.Pages var entry = viewModel.Entries.Skip(1).FirstOrDefault(e => e.Id == args.Tag); Frame.Navigate(typeof(EntryDetailPage), entry); } + + #endregion + } } diff --git a/ModernKeePass/Pages/OpenDatabasePage.xaml b/ModernKeePass/Pages/OpenDatabasePage.xaml index 65e32ef..254d5c6 100644 --- a/ModernKeePass/Pages/OpenDatabasePage.xaml +++ b/ModernKeePass/Pages/OpenDatabasePage.xaml @@ -19,6 +19,6 @@ - + \ No newline at end of file diff --git a/ModernKeePass/Pages/RecentDatabasesPage.xaml b/ModernKeePass/Pages/RecentDatabasesPage.xaml index be6bdf7..23a53cf 100644 --- a/ModernKeePass/Pages/RecentDatabasesPage.xaml +++ b/ModernKeePass/Pages/RecentDatabasesPage.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:viewModels="using:ModernKeePass.ViewModels" xmlns:local="using:ModernKeePass.Controls" - xmlns:converters="using:ModernKeePass.Converters" + xmlns:converters="using:ModernKeePass.Converters" x:Class="ModernKeePass.Pages.RecentDatabasesPage" mc:Ignorable="d"> @@ -23,7 +23,7 @@ - + diff --git a/ModernKeePass/ViewModels/Items/RecentItemVm.cs b/ModernKeePass/ViewModels/Items/RecentItemVm.cs index 1c047dc..1c46c89 100644 --- a/ModernKeePass/ViewModels/Items/RecentItemVm.cs +++ b/ModernKeePass/ViewModels/Items/RecentItemVm.cs @@ -1,4 +1,5 @@ -using ModernKeePass.Common; +using Windows.Storage; +using ModernKeePass.Common; namespace ModernKeePass.ViewModels { @@ -7,6 +8,7 @@ namespace ModernKeePass.ViewModels private bool _isSelected; public string Token { get; set; } public string Name { get; set; } + public StorageFile File { get; set; } public bool IsSelected { diff --git a/ModernKeePass/ViewModels/OpenVm.cs b/ModernKeePass/ViewModels/OpenVm.cs index 6ff33dd..3e6cfc2 100644 --- a/ModernKeePass/ViewModels/OpenVm.cs +++ b/ModernKeePass/ViewModels/OpenVm.cs @@ -1,31 +1,24 @@ using System.ComponentModel; using Windows.Storage; using Windows.Storage.AccessCache; -using Windows.UI.Xaml; -using ModernKeePass.Common; namespace ModernKeePass.ViewModels { public class OpenVm: INotifyPropertyChanged { + public StorageFile File { get; set; } public bool ShowPasswordBox { - get { return ((App) Application.Current).Database.Status == DatabaseHelper.DatabaseStatus.Opening; } + get { return File != null; } } public string Name { - get { return ((App) Application.Current).Database.Name; } + get { return File?.Name; } } public event PropertyChangedEventHandler PropertyChanged; - - public OpenVm() - { - var database = ((App) Application.Current).Database; - if (database == null || database.Status != DatabaseHelper.DatabaseStatus.Opening) return; - OpenFile(database.DatabaseFile); - } + private void NotifyPropertyChanged(string propertyName) { @@ -34,8 +27,7 @@ namespace ModernKeePass.ViewModels public void OpenFile(StorageFile file) { - var database = ((App)Application.Current).Database; - database.DatabaseFile = file; + File = file; NotifyPropertyChanged("Name"); NotifyPropertyChanged("ShowPasswordBox"); AddToRecentList(file); diff --git a/ModernKeePass/ViewModels/RecentVm.cs b/ModernKeePass/ViewModels/RecentVm.cs index 064a263..3208a0e 100644 --- a/ModernKeePass/ViewModels/RecentVm.cs +++ b/ModernKeePass/ViewModels/RecentVm.cs @@ -2,7 +2,6 @@ using System.Collections.ObjectModel; using System.Linq; using Windows.Storage.AccessCache; -using Windows.UI.Xaml; using ModernKeePass.Common; namespace ModernKeePass.ViewModels @@ -11,17 +10,7 @@ namespace ModernKeePass.ViewModels { private RecentItemVm _selectedItem; private ObservableCollection _recentItems; - - public RecentVm() - { - var mru = StorageApplicationPermissions.MostRecentlyUsedList; - RecentItems = new ObservableCollection( - from entry in mru.Entries - select new RecentItemVm { Name = entry.Metadata, Token = entry.Token }); - if (RecentItems.Count > 0) - SelectedItem = RecentItems[0]; - } - + public ObservableCollection RecentItems { get { return _recentItems; } @@ -47,10 +36,19 @@ namespace ModernKeePass.ViewModels } var mru = StorageApplicationPermissions.MostRecentlyUsedList; - var file = mru.GetFileAsync(SelectedItem.Token).GetAwaiter().GetResult(); - var app = (App)Application.Current; - app.Database.DatabaseFile = file; + _selectedItem.File = mru.GetFileAsync(SelectedItem.Token).GetAwaiter().GetResult(); } } + + public RecentVm() + { + var mru = StorageApplicationPermissions.MostRecentlyUsedList; + RecentItems = new ObservableCollection( + from entry in mru.Entries + select new RecentItemVm { Name = entry.Metadata, Token = entry.Token }); + if (RecentItems.Count > 0) + SelectedItem = RecentItems[0]; + } + } }