mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Create a shared project with all Win App common files (8.1 and 10)
Finally use the dependency injected Resource Service
This commit is contained in:
@@ -28,6 +28,7 @@ namespace ModernKeePass.Infrastructure
|
|||||||
services.AddScoped(typeof(IFileProxy), typeof(StorageFileClient));
|
services.AddScoped(typeof(IFileProxy), typeof(StorageFileClient));
|
||||||
services.AddTransient(typeof(ISettingsProxy), typeof(UwpSettingsClient));
|
services.AddTransient(typeof(ISettingsProxy), typeof(UwpSettingsClient));
|
||||||
services.AddTransient(typeof(IRecentProxy), typeof(UwpRecentFilesClient));
|
services.AddTransient(typeof(IRecentProxy), typeof(UwpRecentFilesClient));
|
||||||
|
services.AddTransient(typeof(IResourceProxy), typeof(UwpResourceClient));
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,10 +6,11 @@ namespace ModernKeePass.Infrastructure.UWP
|
|||||||
public class UwpResourceClient: IResourceProxy
|
public class UwpResourceClient: IResourceProxy
|
||||||
{
|
{
|
||||||
private const string ResourceFileName = "CodeBehind";
|
private const string ResourceFileName = "CodeBehind";
|
||||||
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
private ResourceLoader _resourceLoader;
|
||||||
|
|
||||||
public string GetResourceValue(string key)
|
public string GetResourceValue(string key)
|
||||||
{
|
{
|
||||||
|
if (_resourceLoader == null) _resourceLoader = ResourceLoader.GetForCurrentView();
|
||||||
var resource = _resourceLoader.GetString($"/{ResourceFileName}/{key}");
|
var resource = _resourceLoader.GetString($"/{ResourceFileName}/{key}");
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 14.0.25420.1
|
VisualStudioVersion = 16.0.30011.22
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win81App", "ModernKeePass\Win81App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win81App", "ModernKeePass\Win81App.csproj", "{A0CFC681-769B-405A-8482-0CDEE595A91F}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -34,7 +34,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win10App", "ModernKeePass10
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernKeePassApp.ViewModelTest", "ModernKeePass.ViewModelTest\ModernKeePassApp.ViewModelTest.csproj", "{D978E25B-028C-446C-8143-D85563ECA914}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernKeePassApp.ViewModelTest", "ModernKeePass.ViewModelTest\ModernKeePassApp.ViewModelTest.csproj", "{D978E25B-028C-446C-8143-D85563ECA914}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "WinAppCommon", "WinAppCommon\WinAppCommon.shproj", "{A66B7A53-1D8F-41E2-A8AB-840C81B1AA92}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
|
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||||
|
WinAppCommon\WinAppCommon.projitems*{a0cfc681-769b-405a-8482-0cdee595a91f}*SharedItemsImports = 4
|
||||||
|
WinAppCommon\WinAppCommon.projitems*{a66b7a53-1d8f-41e2-a8ab-840c81b1aa92}*SharedItemsImports = 13
|
||||||
|
WinAppCommon\WinAppCommon.projitems*{d16caff7-4187-45a8-a69e-d0658b7ac5bf}*SharedItemsImports = 4
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|ARM = Debug|ARM
|
Debug|ARM = Debug|ARM
|
||||||
@@ -204,6 +211,7 @@ Global
|
|||||||
{52FEA1EE-2FA7-4862-85FE-CB05893D439E} = {107C7C00-56F4-41B0-A8CC-0156C46A3650}
|
{52FEA1EE-2FA7-4862-85FE-CB05893D439E} = {107C7C00-56F4-41B0-A8CC-0156C46A3650}
|
||||||
{D16CAFF7-4187-45A8-A69E-D0658B7AC5BF} = {C7DB9A6F-77A8-4FE5-83CB-9C11F7100647}
|
{D16CAFF7-4187-45A8-A69E-D0658B7AC5BF} = {C7DB9A6F-77A8-4FE5-83CB-9C11F7100647}
|
||||||
{D978E25B-028C-446C-8143-D85563ECA914} = {107C7C00-56F4-41B0-A8CC-0156C46A3650}
|
{D978E25B-028C-446C-8143-D85563ECA914} = {107C7C00-56F4-41B0-A8CC-0156C46A3650}
|
||||||
|
{A66B7A53-1D8F-41E2-A8AB-840C81B1AA92} = {C7DB9A6F-77A8-4FE5-83CB-9C11F7100647}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {0ADC1BC6-B1CA-427D-A97C-3CA40AAB0428}
|
SolutionGuid = {0ADC1BC6-B1CA-427D-A97C-3CA40AAB0428}
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
using Windows.ApplicationModel.Resources;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
public class ResourceHelper
|
|
||||||
{
|
|
||||||
private const string ResourceFileName = "CodeBehind";
|
|
||||||
private readonly ResourceLoader _resourceLoader = ResourceLoader.GetForCurrentView();
|
|
||||||
|
|
||||||
public string GetResourceValue(string key)
|
|
||||||
{
|
|
||||||
var resource = _resourceLoader.GetString($"/{ResourceFileName}/{key}");
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -12,7 +12,6 @@ using ModernKeePass.Application.Security.Commands.GenerateKeyFile;
|
|||||||
using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity;
|
using ModernKeePass.Application.Security.Queries.EstimatePasswordComplexity;
|
||||||
using ModernKeePass.Domain.AOP;
|
using ModernKeePass.Domain.AOP;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
using ModernKeePass.Common;
|
|
||||||
|
|
||||||
namespace ModernKeePass.ViewModels
|
namespace ModernKeePass.ViewModels
|
||||||
{
|
{
|
||||||
@@ -113,15 +112,18 @@ namespace ModernKeePass.ViewModels
|
|||||||
private string _keyFileText;
|
private string _keyFileText;
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
private readonly ISettingsProxy _settings;
|
private readonly ISettingsProxy _settings;
|
||||||
private readonly ResourceHelper _resource;
|
private readonly IResourceProxy _resource;
|
||||||
|
|
||||||
public CompositeKeyVm() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<ISettingsProxy>()) { }
|
public CompositeKeyVm() : this(
|
||||||
|
App.Services.GetRequiredService<IMediator>(),
|
||||||
|
App.Services.GetRequiredService<ISettingsProxy>(),
|
||||||
|
App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
|
|
||||||
public CompositeKeyVm(IMediator mediator, ISettingsProxy settings)
|
public CompositeKeyVm(IMediator mediator, ISettingsProxy settings, IResourceProxy resource)
|
||||||
{
|
{
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
_resource = new ResourceHelper();
|
_resource = resource;
|
||||||
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
_keyFileText = _resource.GetResourceValue("CompositeKeyDefaultKeyFile");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,6 @@ using MediatR;
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Domain.AOP;
|
using ModernKeePass.Domain.AOP;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
using ModernKeePass.Domain.Interfaces;
|
using ModernKeePass.Domain.Interfaces;
|
||||||
@@ -50,13 +49,17 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public MainVm() {}
|
public MainVm() {}
|
||||||
|
|
||||||
internal MainVm(Frame referenceFrame, Frame destinationFrame, FileInfo databaseFile = null) : this(referenceFrame, destinationFrame,
|
internal MainVm(Frame referenceFrame, Frame destinationFrame, FileInfo databaseFile = null) : this(
|
||||||
App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IRecentProxy>(), databaseFile)
|
referenceFrame,
|
||||||
|
destinationFrame,
|
||||||
|
App.Services.GetRequiredService<IMediator>(),
|
||||||
|
App.Services.GetRequiredService<IRecentProxy>(),
|
||||||
|
App.Services.GetRequiredService<IResourceProxy>(),
|
||||||
|
databaseFile)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IRecentProxy recent, FileInfo databaseFile = null)
|
public MainVm(Frame referenceFrame, Frame destinationFrame, IMediator mediator, IRecentProxy recent, IResourceProxy resource, FileInfo databaseFile = null)
|
||||||
{
|
{
|
||||||
var resource = new ResourceHelper();
|
|
||||||
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||||
|
|
||||||
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
|
var mainMenuItems = new ObservableCollection<MainMenuItemVm>
|
||||||
|
@@ -3,8 +3,8 @@ using System.Linq;
|
|||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Domain.AOP;
|
using ModernKeePass.Domain.AOP;
|
||||||
using ModernKeePass.Domain.Interfaces;
|
using ModernKeePass.Domain.Interfaces;
|
||||||
using ModernKeePass.Views;
|
using ModernKeePass.Views;
|
||||||
@@ -43,11 +43,10 @@ namespace ModernKeePass.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SettingsVm() : this(App.Services.GetRequiredService<IMediator>()) { }
|
public SettingsVm() : this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
|
|
||||||
public SettingsVm(IMediator mediator)
|
public SettingsVm(IMediator mediator, IResourceProxy resource)
|
||||||
{
|
{
|
||||||
var resource = new ResourceHelper();
|
|
||||||
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
var database = mediator.Send(new GetDatabaseQuery()).GetAwaiter().GetResult();
|
||||||
var menuItems = new ObservableCollection<ListMenuItemVm>
|
var menuItems = new ObservableCollection<ListMenuItemVm>
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Models;
|
using ModernKeePass.Models;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
@@ -14,6 +16,7 @@ namespace ModernKeePass.Views
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class EntryDetailPage
|
public sealed partial class EntryDetailPage
|
||||||
{
|
{
|
||||||
|
private readonly IResourceProxy _resource;
|
||||||
public EntryDetailVm Model => (EntryDetailVm) DataContext;
|
public EntryDetailVm Model => (EntryDetailVm) DataContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -22,9 +25,11 @@ namespace ModernKeePass.Views
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public NavigationHelper NavigationHelper { get; }
|
public NavigationHelper NavigationHelper { get; }
|
||||||
|
|
||||||
public EntryDetailPage()
|
public EntryDetailPage(): this(App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
|
public EntryDetailPage(IResourceProxy resource)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
_resource = resource;
|
||||||
NavigationHelper = new NavigationHelper(this);
|
NavigationHelper = new NavigationHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,29 +71,28 @@ namespace ModernKeePass.Views
|
|||||||
|
|
||||||
private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e)
|
private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var resource = new ResourceHelper();
|
|
||||||
if (Model.IsCurrentEntry)
|
if (Model.IsCurrentEntry)
|
||||||
{
|
{
|
||||||
var isRecycleOnDelete = Model.IsRecycleOnDelete;
|
var isRecycleOnDelete = Model.IsRecycleOnDelete;
|
||||||
|
|
||||||
var message = isRecycleOnDelete
|
var message = isRecycleOnDelete
|
||||||
? resource.GetResourceValue("EntryRecyclingConfirmation")
|
? _resource.GetResourceValue("EntryRecyclingConfirmation")
|
||||||
: resource.GetResourceValue("EntryDeletingConfirmation");
|
: _resource.GetResourceValue("EntryDeletingConfirmation");
|
||||||
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
|
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("EntityDeleteTitle"), message,
|
||||||
resource.GetResourceValue("EntityDeleteActionButton"),
|
_resource.GetResourceValue("EntityDeleteActionButton"),
|
||||||
resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
_resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
||||||
{
|
{
|
||||||
var text = isRecycleOnDelete ? resource.GetResourceValue("EntryRecycled") : resource.GetResourceValue("EntryDeleted");
|
var text = isRecycleOnDelete ? _resource.GetResourceValue("EntryRecycled") : _resource.GetResourceValue("EntryDeleted");
|
||||||
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
||||||
await Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
await Model.MarkForDelete(_resource.GetResourceValue("RecycleBinTitle"));
|
||||||
NavigationHelper.GoBack();
|
NavigationHelper.GoBack();
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("HistoryDeleteTitle"), resource.GetResourceValue("HistoryDeleteDescription"),
|
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("HistoryDeleteTitle"), _resource.GetResourceValue("HistoryDeleteDescription"),
|
||||||
resource.GetResourceValue("EntityDeleteActionButton"),
|
_resource.GetResourceValue("EntityDeleteActionButton"),
|
||||||
resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
_resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
||||||
{
|
{
|
||||||
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
//ToastNotificationHelper.ShowMovedToast(Entity, _resource.GetResourceValue("EntityDeleting"), text);
|
||||||
await Model.DeleteHistory();
|
await Model.DeleteHistory();
|
||||||
|
@@ -5,11 +5,13 @@ using Windows.Storage.Streams;
|
|||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using Windows.UI.Xaml.Navigation;
|
using Windows.UI.Xaml.Navigation;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
|
using ModernKeePass.Application.Entry.Models;
|
||||||
using ModernKeePass.Common;
|
using ModernKeePass.Common;
|
||||||
using ModernKeePass.Events;
|
using ModernKeePass.Events;
|
||||||
using ModernKeePass.Models;
|
using ModernKeePass.Models;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using EntryVm = ModernKeePass.Application.Entry.Models.EntryVm;
|
|
||||||
|
|
||||||
// The Group Detail Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234229
|
// The Group Detail Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234229
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ namespace ModernKeePass.Views
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class GroupDetailPage
|
public sealed partial class GroupDetailPage
|
||||||
{
|
{
|
||||||
|
private readonly IResourceProxy _resource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// NavigationHelper is used on each page to aid in navigation and
|
/// NavigationHelper is used on each page to aid in navigation and
|
||||||
/// process lifetime management
|
/// process lifetime management
|
||||||
@@ -28,9 +32,11 @@ namespace ModernKeePass.Views
|
|||||||
public NavigationHelper NavigationHelper { get; }
|
public NavigationHelper NavigationHelper { get; }
|
||||||
public GroupDetailVm Model => (GroupDetailVm)DataContext;
|
public GroupDetailVm Model => (GroupDetailVm)DataContext;
|
||||||
|
|
||||||
public GroupDetailPage()
|
public GroupDetailPage(): this (App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
|
public GroupDetailPage(IResourceProxy resource)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
_resource = resource;
|
||||||
NavigationHelper = new NavigationHelper(this);
|
NavigationHelper = new NavigationHelper(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,19 +156,18 @@ namespace ModernKeePass.Views
|
|||||||
|
|
||||||
private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e)
|
private async void TopMenu_OnDeleteButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var resource = new ResourceHelper();
|
|
||||||
var isRecycleOnDelete = Model.IsRecycleOnDelete;
|
var isRecycleOnDelete = Model.IsRecycleOnDelete;
|
||||||
|
|
||||||
var message = isRecycleOnDelete
|
var message = isRecycleOnDelete
|
||||||
? resource.GetResourceValue("GroupRecyclingConfirmation")
|
? _resource.GetResourceValue("GroupRecyclingConfirmation")
|
||||||
: resource.GetResourceValue("GroupDeletingConfirmation");
|
: _resource.GetResourceValue("GroupDeletingConfirmation");
|
||||||
var text = isRecycleOnDelete ? resource.GetResourceValue("GroupRecycled") : resource.GetResourceValue("GroupDeleted");
|
var text = isRecycleOnDelete ? _resource.GetResourceValue("GroupRecycled") : _resource.GetResourceValue("GroupDeleted");
|
||||||
await MessageDialogHelper.ShowActionDialog(resource.GetResourceValue("EntityDeleteTitle"), message,
|
await MessageDialogHelper.ShowActionDialog(_resource.GetResourceValue("EntityDeleteTitle"), message,
|
||||||
resource.GetResourceValue("EntityDeleteActionButton"),
|
_resource.GetResourceValue("EntityDeleteActionButton"),
|
||||||
resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
_resource.GetResourceValue("EntityDeleteCancelButton"), async a =>
|
||||||
{
|
{
|
||||||
//ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text);
|
//ToastNotificationHelper.ShowMovedToast(Entity, resource.GetResourceValue("EntityDeleting"), text);
|
||||||
await Model.MarkForDelete(resource.GetResourceValue("RecycleBinTitle"));
|
await Model.MarkForDelete(_resource.GetResourceValue("RecycleBinTitle"));
|
||||||
NavigationHelper.GoBack();
|
NavigationHelper.GoBack();
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,8 @@ using Windows.Storage.AccessCache;
|
|||||||
using Windows.Storage.Pickers;
|
using Windows.Storage.Pickers;
|
||||||
using Windows.UI.Xaml;
|
using Windows.UI.Xaml;
|
||||||
using Windows.UI.Xaml.Controls;
|
using Windows.UI.Xaml.Controls;
|
||||||
using ModernKeePass.Common;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Domain.Dtos;
|
using ModernKeePass.Domain.Dtos;
|
||||||
using ModernKeePass.Infrastructure.File;
|
using ModernKeePass.Infrastructure.File;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
@@ -18,10 +19,13 @@ namespace ModernKeePass.Views
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class NewDatabasePage
|
public sealed partial class NewDatabasePage
|
||||||
{
|
{
|
||||||
|
private readonly IResourceProxy _resource;
|
||||||
public NewVm Model => (NewVm)DataContext;
|
public NewVm Model => (NewVm)DataContext;
|
||||||
|
|
||||||
public NewDatabasePage()
|
public NewDatabasePage(): this(App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
|
public NewDatabasePage(IResourceProxy resource)
|
||||||
{
|
{
|
||||||
|
_resource = resource;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,14 +53,13 @@ namespace ModernKeePass.Views
|
|||||||
|
|
||||||
private void ImportFormatComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void ImportFormatComboBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var resource = new ResourceHelper();
|
|
||||||
var comboBox = sender as ComboBox;
|
var comboBox = sender as ComboBox;
|
||||||
switch (comboBox?.SelectedIndex)
|
switch (comboBox?.SelectedIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
Model.ImportFormat = new CsvImportFormat();
|
Model.ImportFormat = new CsvImportFormat();
|
||||||
Model.ImportFileExtensionFilter = ".csv";
|
Model.ImportFileExtensionFilter = ".csv";
|
||||||
Model.ImportFormatHelp = resource.GetResourceValue("NewImportFormatHelpCSV");
|
Model.ImportFormatHelp = _resource.GetResourceValue("NewImportFormatHelpCSV");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ using Windows.UI.Xaml;
|
|||||||
using Windows.UI.Xaml.Input;
|
using Windows.UI.Xaml.Input;
|
||||||
using MediatR;
|
using MediatR;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ModernKeePass.Application.Common.Interfaces;
|
||||||
using ModernKeePass.Application.Database.Commands.CloseDatabase;
|
using ModernKeePass.Application.Database.Commands.CloseDatabase;
|
||||||
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
using ModernKeePass.Application.Database.Commands.SaveDatabase;
|
||||||
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
using ModernKeePass.Application.Database.Queries.GetDatabase;
|
||||||
@@ -24,7 +25,7 @@ namespace ModernKeePass.Views.UserControls
|
|||||||
public sealed partial class CompositeKeyUserControl
|
public sealed partial class CompositeKeyUserControl
|
||||||
{
|
{
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
private readonly ResourceHelper _resource;
|
private readonly IResourceProxy _resource;
|
||||||
public CompositeKeyVm Model => Grid.DataContext as CompositeKeyVm;
|
public CompositeKeyVm Model => Grid.DataContext as CompositeKeyVm;
|
||||||
|
|
||||||
public bool CreateNew
|
public bool CreateNew
|
||||||
@@ -77,13 +78,12 @@ namespace ModernKeePass.Views.UserControls
|
|||||||
|
|
||||||
public bool ShowComplexityIndicator => CreateNew || UpdateKey;
|
public bool ShowComplexityIndicator => CreateNew || UpdateKey;
|
||||||
|
|
||||||
public CompositeKeyUserControl(): this(App.Services.GetRequiredService<IMediator>())
|
public CompositeKeyUserControl(): this(App.Services.GetRequiredService<IMediator>(), App.Services.GetRequiredService<IResourceProxy>()) { }
|
||||||
{ }
|
|
||||||
|
|
||||||
public CompositeKeyUserControl(IMediator mediator)
|
public CompositeKeyUserControl(IMediator mediator, IResourceProxy resource)
|
||||||
{
|
{
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
_resource = new ResourceHelper();
|
_resource = resource;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -89,34 +89,15 @@
|
|||||||
<Prefer32Bit>true</Prefer32Bit>
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Actions\ClipboardAction.cs" />
|
|
||||||
<Compile Include="Actions\NavigateToUrlAction.cs" />
|
|
||||||
<Compile Include="Actions\SetupFocusAction.cs" />
|
|
||||||
<Compile Include="Actions\ToastAction.cs" />
|
|
||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Common\Constants.cs" />
|
|
||||||
<Compile Include="Common\ResourceHelper.cs" />
|
|
||||||
<Compile Include="Converters\IconToSymbolConverter.cs" />
|
|
||||||
<Compile Include="DependencyInjection.cs" />
|
<Compile Include="DependencyInjection.cs" />
|
||||||
<Compile Include="Extensions\ColorExtensions.cs" />
|
|
||||||
<Compile Include="Models\NavigationItem.cs" />
|
<Compile Include="Models\NavigationItem.cs" />
|
||||||
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
|
||||||
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
|
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" />
|
||||||
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
||||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Common\MessageDialogHelper.cs" />
|
|
||||||
<Compile Include="Common\NavigationHelper.cs" />
|
|
||||||
<Compile Include="Common\ObservableDictionary.cs" />
|
|
||||||
<Compile Include="Common\RelayCommand.cs" />
|
|
||||||
<Compile Include="Common\SuspensionManager.cs" />
|
|
||||||
<Compile Include="Common\ToastNotificationHelper.cs" />
|
|
||||||
<Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\EmptyStringToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
|
||||||
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
|
|
||||||
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
||||||
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs">
|
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs">
|
||||||
<DependentUpon>ImportExportPage.xaml</DependentUpon>
|
<DependentUpon>ImportExportPage.xaml</DependentUpon>
|
||||||
@@ -136,8 +117,6 @@
|
|||||||
<Compile Include="Views\SettingsPageFrames\SettingsWelcomePage.xaml.cs">
|
<Compile Include="Views\SettingsPageFrames\SettingsWelcomePage.xaml.cs">
|
||||||
<DependentUpon>SettingsWelcomePage.xaml</DependentUpon>
|
<DependentUpon>SettingsWelcomePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="TemplateSelectors\FirstItemDataTemplateSelector.cs" />
|
|
||||||
<Compile Include="Controls\ListViewWithDisable.cs" />
|
|
||||||
<Compile Include="Views\UserControls\BreadCrumbUserControl.xaml.cs">
|
<Compile Include="Views\UserControls\BreadCrumbUserControl.xaml.cs">
|
||||||
<DependentUpon>BreadCrumbUserControl.xaml</DependentUpon>
|
<DependentUpon>BreadCrumbUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -147,15 +126,6 @@
|
|||||||
<Compile Include="Views\UserControls\CompositeKeyUserControl.xaml.cs">
|
<Compile Include="Views\UserControls\CompositeKeyUserControl.xaml.cs">
|
||||||
<DependentUpon>CompositeKeyUserControl.xaml</DependentUpon>
|
<DependentUpon>CompositeKeyUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\TextBoxWithButton.cs" />
|
|
||||||
<Compile Include="Converters\BooleanToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\ColorToBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\PluralizationConverter.cs" />
|
|
||||||
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
|
|
||||||
<Compile Include="Converters\TextToWidthConverter.cs" />
|
|
||||||
<Compile Include="Events\PasswordEventArgs.cs" />
|
|
||||||
<Compile Include="Interfaces\IVmEntity.cs" />
|
<Compile Include="Interfaces\IVmEntity.cs" />
|
||||||
<Compile Include="Views\MainPage.xaml.cs">
|
<Compile Include="Views\MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
@@ -557,6 +527,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
<Import Project="..\WinAppCommon\WinAppCommon.projitems" Label="Shared" />
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '12.0' ">
|
||||||
<VisualStudioVersion>12.0</VisualStudioVersion>
|
<VisualStudioVersion>12.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -1,27 +0,0 @@
|
|||||||
using Windows.ApplicationModel.DataTransfer;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Microsoft.Xaml.Interactivity;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Actions
|
|
||||||
{
|
|
||||||
public class ClipboardAction : DependencyObject, IAction
|
|
||||||
{
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get => (string)GetValue(TextProperty);
|
|
||||||
set => SetValue(TextProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty TextProperty =
|
|
||||||
DependencyProperty.Register("Text", typeof(string), typeof(ClipboardAction), new PropertyMetadata(string.Empty));
|
|
||||||
|
|
||||||
public object Execute(object sender, object parameter)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(Text)) return null;
|
|
||||||
var dataPackage = new DataPackage { RequestedOperation = DataPackageOperation.Copy };
|
|
||||||
dataPackage.SetText(Text);
|
|
||||||
Clipboard.SetContent(dataPackage);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,65 +0,0 @@
|
|||||||
using System.Windows.Input;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Autofac;
|
|
||||||
using Microsoft.Xaml.Interactivity;
|
|
||||||
using ModernKeePass.Common;
|
|
||||||
using ModernKeePass.Domain.Entities;
|
|
||||||
using ModernKeePass.Domain.Interfaces;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Actions
|
|
||||||
{
|
|
||||||
public class DeleteEntityAction : DependencyObject, IAction
|
|
||||||
{
|
|
||||||
private readonly IResourceService _resourceService;
|
|
||||||
private readonly IDatabaseService _databaseService;
|
|
||||||
|
|
||||||
public Entity Entity
|
|
||||||
{
|
|
||||||
get => (Entity)GetValue(EntityProperty);
|
|
||||||
set => SetValue(EntityProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty EntityProperty =
|
|
||||||
DependencyProperty.Register("Entity", typeof(Entity), typeof(DeleteEntityAction),
|
|
||||||
new PropertyMetadata(null));
|
|
||||||
|
|
||||||
public ICommand Command
|
|
||||||
{
|
|
||||||
get => (ICommand)GetValue(CommandProperty);
|
|
||||||
set => SetValue(CommandProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty CommandProperty =
|
|
||||||
DependencyProperty.Register("Command", typeof(ICommand), typeof(DeleteEntityAction),
|
|
||||||
new PropertyMetadata(null));
|
|
||||||
|
|
||||||
public DeleteEntityAction(): this(App.Container.Resolve<IResourceService>(), App.Container.Resolve<IDatabaseService>())
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public DeleteEntityAction(IResourceService resourceService, IDatabaseService databaseService)
|
|
||||||
{
|
|
||||||
_resourceService = resourceService;
|
|
||||||
_databaseService = databaseService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Execute(object sender, object parameter)
|
|
||||||
{
|
|
||||||
var type = Entity is GroupEntity ? "Group" : "Entry";
|
|
||||||
|
|
||||||
var message = _databaseService.IsRecycleBinEnabled
|
|
||||||
? _resourceService.GetResourceValue($"{type}RecyclingConfirmation")
|
|
||||||
: _resourceService.GetResourceValue($"{type}DeletingConfirmation");
|
|
||||||
var text = _databaseService.IsRecycleBinEnabled ? _resourceService.GetResourceValue($"{type}Recycled") : _resourceService.GetResourceValue($"{type}Deleted");
|
|
||||||
MessageDialogHelper.ShowActionDialog(_resourceService.GetResourceValue("EntityDeleteTitle"), message,
|
|
||||||
_resourceService.GetResourceValue("EntityDeleteActionButton"),
|
|
||||||
_resourceService.GetResourceValue("EntityDeleteCancelButton"), a =>
|
|
||||||
{
|
|
||||||
ToastNotificationHelper.ShowMovedToast(Entity, _resourceService.GetResourceValue("EntityDeleting"), text);
|
|
||||||
//Entity.MarkForDelete(_resourceService.GetResourceValue("RecycleBinTitle"));
|
|
||||||
Command.Execute(null);
|
|
||||||
}, null).GetAwaiter();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,33 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Microsoft.Xaml.Interactivity;
|
|
||||||
using ModernKeePass.Common;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Actions
|
|
||||||
{
|
|
||||||
public class NavigateToUrlAction : DependencyObject, IAction
|
|
||||||
{
|
|
||||||
public string Url
|
|
||||||
{
|
|
||||||
get => (string)GetValue(UrlProperty);
|
|
||||||
set => SetValue(UrlProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty UrlProperty =
|
|
||||||
DependencyProperty.Register("Url", typeof(string), typeof(NavigateToUrlAction), new PropertyMetadata(string.Empty));
|
|
||||||
|
|
||||||
public object Execute(object sender, object parameter)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var uri = new Uri(Url);
|
|
||||||
return Windows.System.Launcher.LaunchUriAsync(uri).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageDialogHelper.ShowErrorDialog(ex).GetAwaiter();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.UI.Core;
|
|
||||||
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 => (Control)GetValue(TargetObjectProperty);
|
|
||||||
set => SetValue(TargetObjectProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty TargetObjectProperty =
|
|
||||||
DependencyProperty.Register("TargetObject", typeof(Control), typeof(SetupFocusAction), new PropertyMetadata(null));
|
|
||||||
|
|
||||||
public object Execute(object sender, object parameter)
|
|
||||||
{
|
|
||||||
return Task.Factory.StartNew(
|
|
||||||
() => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
|
|
||||||
() => TargetObject?.Focus(FocusState.Programmatic)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,33 +0,0 @@
|
|||||||
using Windows.UI.Xaml;
|
|
||||||
using Microsoft.Xaml.Interactivity;
|
|
||||||
using ModernKeePass.Common;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Actions
|
|
||||||
{
|
|
||||||
public class ToastAction : DependencyObject, IAction
|
|
||||||
{
|
|
||||||
public string Title
|
|
||||||
{
|
|
||||||
get => (string)GetValue(TitleProperty);
|
|
||||||
set => SetValue(TitleProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty TitleProperty =
|
|
||||||
DependencyProperty.Register("Title", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
|
|
||||||
|
|
||||||
public string Message
|
|
||||||
{
|
|
||||||
get => (string)GetValue(MessageProperty);
|
|
||||||
set => SetValue(MessageProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly DependencyProperty MessageProperty =
|
|
||||||
DependencyProperty.Register("Message", typeof(string), typeof(ToastAction), new PropertyMetadata(string.Empty));
|
|
||||||
|
|
||||||
public object Execute(object sender, object parameter)
|
|
||||||
{
|
|
||||||
ToastNotificationHelper.ShowGenericToast(Title, Message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.UI.Popups;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
public static class MessageDialogHelper
|
|
||||||
{
|
|
||||||
public static async Task ShowActionDialog(string title, string contentText, string actionButtonText, string cancelButtonText, UICommandInvokedHandler actionCommand, UICommandInvokedHandler cancelCommand)
|
|
||||||
{
|
|
||||||
// Create the message dialog and set its content
|
|
||||||
var messageDialog = CreateBasicDialog(title, contentText, cancelButtonText, cancelCommand);
|
|
||||||
|
|
||||||
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
|
||||||
messageDialog.Commands.Add(new UICommand(actionButtonText, actionCommand));
|
|
||||||
|
|
||||||
// Show the message dialog
|
|
||||||
await messageDialog.ShowAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task ShowErrorDialog(Exception exception)
|
|
||||||
{
|
|
||||||
if (exception == null) return;
|
|
||||||
// Create the message dialog and set its content
|
|
||||||
var messageDialog = CreateBasicDialog(exception.Message, exception.StackTrace, "OK");
|
|
||||||
|
|
||||||
// Show the message dialog
|
|
||||||
await messageDialog.ShowAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task ShowNotificationDialog(string title, string message)
|
|
||||||
{
|
|
||||||
var dialog = CreateBasicDialog(title, message, "OK");
|
|
||||||
|
|
||||||
// Show the message dialog
|
|
||||||
await dialog.ShowAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MessageDialog CreateBasicDialog(string title, string message, string dismissActionText, UICommandInvokedHandler cancelCommand = null)
|
|
||||||
{
|
|
||||||
// Create the message dialog and set its content
|
|
||||||
var messageDialog = new MessageDialog(message, title);
|
|
||||||
|
|
||||||
// Add commands and set their callbacks
|
|
||||||
messageDialog.Commands.Add(new UICommand(dismissActionText, cancelCommand));
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
return messageDialog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,433 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using Windows.System;
|
|
||||||
using Windows.UI.Core;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using Windows.UI.Xaml.Navigation;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// NavigationHelper aids in navigation between pages. It provides commands used to
|
|
||||||
/// navigate back and forward as well as registers for standard mouse and keyboard
|
|
||||||
/// shortcuts used to go back and forward in Windows and the hardware back button in
|
|
||||||
/// Windows Phone. In addition it integrates SuspensionManger to handle process lifetime
|
|
||||||
/// management and state management when navigating between pages.
|
|
||||||
/// </summary>
|
|
||||||
/// <example>
|
|
||||||
/// To make use of NavigationHelper, follow these two steps or
|
|
||||||
/// start with a BasicPage or any other Page item template other than BlankPage.
|
|
||||||
///
|
|
||||||
/// 1) Create an instance of the NavigationHelper somewhere such as in the
|
|
||||||
/// constructor for the page and register a callback for the LoadState and
|
|
||||||
/// SaveState events.
|
|
||||||
/// <code>
|
|
||||||
/// public MyPage()
|
|
||||||
/// {
|
|
||||||
/// this.InitializeComponent();
|
|
||||||
/// var navigationHelper = new NavigationHelper(this);
|
|
||||||
/// this.navigationHelper.LoadState += navigationHelper_LoadState;
|
|
||||||
/// this.navigationHelper.SaveState += navigationHelper_SaveState;
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
|
|
||||||
/// { }
|
|
||||||
/// private async void navigationHelper_SaveState(object sender, LoadStateEventArgs e)
|
|
||||||
/// { }
|
|
||||||
/// </code>
|
|
||||||
///
|
|
||||||
/// 2) Register the page to call into the NavigationHelper whenever the page participates
|
|
||||||
/// in navigation by overriding the <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedTo"/>
|
|
||||||
/// and <see cref="Windows.UI.Xaml.Controls.Page.OnNavigatedFrom"/> events.
|
|
||||||
/// <code>
|
|
||||||
/// protected override void OnNavigatedTo(NavigationEventArgs e)
|
|
||||||
/// {
|
|
||||||
/// navigationHelper.OnNavigatedTo(e);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// protected override void OnNavigatedFrom(NavigationEventArgs e)
|
|
||||||
/// {
|
|
||||||
/// navigationHelper.OnNavigatedFrom(e);
|
|
||||||
/// }
|
|
||||||
/// </code>
|
|
||||||
/// </example>
|
|
||||||
[Windows.Foundation.Metadata.WebHostHidden]
|
|
||||||
public class NavigationHelper : DependencyObject
|
|
||||||
{
|
|
||||||
private Page Page { get; set; }
|
|
||||||
private Frame Frame => this.Page.Frame;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="NavigationHelper"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="page">A reference to the current page used for navigation.
|
|
||||||
/// This reference allows for frame manipulation and to ensure that keyboard
|
|
||||||
/// navigation requests only occur when the page is occupying the entire window.</param>
|
|
||||||
public NavigationHelper(Page page)
|
|
||||||
{
|
|
||||||
this.Page = page;
|
|
||||||
|
|
||||||
// When this page is part of the visual tree make two changes:
|
|
||||||
// 1) Map application view state to visual state for the page
|
|
||||||
// 2) Handle hardware navigation requests
|
|
||||||
this.Page.Loaded += (sender, e) =>
|
|
||||||
{
|
|
||||||
#if WINDOWS_PHONE_APP
|
|
||||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
|
|
||||||
#else
|
|
||||||
// Keyboard and mouse navigation only apply when occupying the entire window
|
|
||||||
if (this.Page.ActualHeight == Window.Current.Bounds.Height &&
|
|
||||||
this.Page.ActualWidth == Window.Current.Bounds.Width)
|
|
||||||
{
|
|
||||||
// Listen to the window directly so focus isn't required
|
|
||||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated +=
|
|
||||||
CoreDispatcher_AcceleratorKeyActivated;
|
|
||||||
Window.Current.CoreWindow.PointerPressed +=
|
|
||||||
this.CoreWindow_PointerPressed;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// Undo the same changes when the page is no longer visible
|
|
||||||
this.Page.Unloaded += (sender, e) =>
|
|
||||||
{
|
|
||||||
#if WINDOWS_PHONE_APP
|
|
||||||
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
|
|
||||||
#else
|
|
||||||
Window.Current.CoreWindow.Dispatcher.AcceleratorKeyActivated -=
|
|
||||||
CoreDispatcher_AcceleratorKeyActivated;
|
|
||||||
Window.Current.CoreWindow.PointerPressed -=
|
|
||||||
this.CoreWindow_PointerPressed;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Navigation support
|
|
||||||
|
|
||||||
RelayCommand _goBackCommand;
|
|
||||||
RelayCommand _goForwardCommand;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="RelayCommand"/> used to bind to the back Button's Command property
|
|
||||||
/// for navigating to the most recent item in back navigation history, if a Frame
|
|
||||||
/// manages its own navigation history.
|
|
||||||
///
|
|
||||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoBack"/>
|
|
||||||
/// as the Execute Action and <see cref="CanGoBack"/> for CanExecute.
|
|
||||||
/// </summary>
|
|
||||||
public RelayCommand GoBackCommand
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_goBackCommand == null)
|
|
||||||
{
|
|
||||||
_goBackCommand = new RelayCommand(
|
|
||||||
() => this.GoBack(),
|
|
||||||
() => this.CanGoBack());
|
|
||||||
}
|
|
||||||
return _goBackCommand;
|
|
||||||
}
|
|
||||||
set => _goBackCommand = value;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="RelayCommand"/> used for navigating to the most recent item in
|
|
||||||
/// the forward navigation history, if a Frame manages its own navigation history.
|
|
||||||
///
|
|
||||||
/// The <see cref="RelayCommand"/> is set up to use the virtual method <see cref="GoForward"/>
|
|
||||||
/// as the Execute Action and <see cref="CanGoForward"/> for CanExecute.
|
|
||||||
/// </summary>
|
|
||||||
public RelayCommand GoForwardCommand
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_goForwardCommand == null)
|
|
||||||
{
|
|
||||||
_goForwardCommand = new RelayCommand(
|
|
||||||
() => this.GoForward(),
|
|
||||||
() => this.CanGoForward());
|
|
||||||
}
|
|
||||||
return _goForwardCommand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Virtual method used by the <see cref="GoBackCommand"/> property
|
|
||||||
/// to determine if the <see cref="Frame"/> can go back.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// true if the <see cref="Frame"/> has at least one entry
|
|
||||||
/// in the back navigation history.
|
|
||||||
/// </returns>
|
|
||||||
public virtual bool CanGoBack()
|
|
||||||
{
|
|
||||||
return this.Frame != null && this.Frame.CanGoBack;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
|
||||||
/// to determine if the <see cref="Frame"/> can go forward.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// true if the <see cref="Frame"/> has at least one entry
|
|
||||||
/// in the forward navigation history.
|
|
||||||
/// </returns>
|
|
||||||
public virtual bool CanGoForward()
|
|
||||||
{
|
|
||||||
return this.Frame != null && this.Frame.CanGoForward;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Virtual method used by the <see cref="GoBackCommand"/> property
|
|
||||||
/// to invoke the <see cref="Windows.UI.Xaml.Controls.Frame.GoBack"/> method.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void GoBack()
|
|
||||||
{
|
|
||||||
if (this.Frame != null && this.Frame.CanGoBack) this.Frame.GoBack();
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Virtual method used by the <see cref="GoForwardCommand"/> property
|
|
||||||
/// to invoke the <see cref="Windows.UI.Xaml.Controls.Frame.GoForward"/> method.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void GoForward()
|
|
||||||
{
|
|
||||||
if (this.Frame != null && this.Frame.CanGoForward) this.Frame.GoForward();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if WINDOWS_PHONE_APP
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when the hardware back button is pressed. For Windows Phone only.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">Instance that triggered the event.</param>
|
|
||||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
|
||||||
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
|
|
||||||
{
|
|
||||||
if (this.GoBackCommand.CanExecute(null))
|
|
||||||
{
|
|
||||||
e.Handled = true;
|
|
||||||
this.GoBackCommand.Execute(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked on every keystroke, including system keys such as Alt key combinations, when
|
|
||||||
/// this page is active and occupies the entire window. Used to detect keyboard navigation
|
|
||||||
/// between pages even when the page itself doesn't have focus.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">Instance that triggered the event.</param>
|
|
||||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
|
||||||
private void CoreDispatcher_AcceleratorKeyActivated(CoreDispatcher sender,
|
|
||||||
AcceleratorKeyEventArgs e)
|
|
||||||
{
|
|
||||||
var virtualKey = e.VirtualKey;
|
|
||||||
|
|
||||||
// Only investigate further when Left, Right, or the dedicated Previous or Next keys
|
|
||||||
// are pressed
|
|
||||||
if ((e.EventType == CoreAcceleratorKeyEventType.SystemKeyDown ||
|
|
||||||
e.EventType == CoreAcceleratorKeyEventType.KeyDown) &&
|
|
||||||
(virtualKey == VirtualKey.Left || virtualKey == VirtualKey.Right ||
|
|
||||||
(int)virtualKey == 166 || (int)virtualKey == 167))
|
|
||||||
{
|
|
||||||
var coreWindow = Window.Current.CoreWindow;
|
|
||||||
var downState = CoreVirtualKeyStates.Down;
|
|
||||||
bool menuKey = (coreWindow.GetKeyState(VirtualKey.Menu) & downState) == downState;
|
|
||||||
bool controlKey = (coreWindow.GetKeyState(VirtualKey.Control) & downState) == downState;
|
|
||||||
bool shiftKey = (coreWindow.GetKeyState(VirtualKey.Shift) & downState) == downState;
|
|
||||||
bool noModifiers = !menuKey && !controlKey && !shiftKey;
|
|
||||||
bool onlyAlt = menuKey && !controlKey && !shiftKey;
|
|
||||||
|
|
||||||
if (((int)virtualKey == 166 && noModifiers) ||
|
|
||||||
(virtualKey == VirtualKey.Left && onlyAlt))
|
|
||||||
{
|
|
||||||
// When the previous key or Alt+Left are pressed navigate back
|
|
||||||
e.Handled = true;
|
|
||||||
this.GoBackCommand.Execute(null);
|
|
||||||
}
|
|
||||||
else if (((int)virtualKey == 167 && noModifiers) ||
|
|
||||||
(virtualKey == VirtualKey.Right && onlyAlt))
|
|
||||||
{
|
|
||||||
// When the next key or Alt+Right are pressed navigate forward
|
|
||||||
e.Handled = true;
|
|
||||||
this.GoForwardCommand.Execute(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked on every mouse click, touch screen tap, or equivalent interaction when this
|
|
||||||
/// page is active and occupies the entire window. Used to detect browser-style next and
|
|
||||||
/// previous mouse button clicks to navigate between pages.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sender">Instance that triggered the event.</param>
|
|
||||||
/// <param name="e">Event data describing the conditions that led to the event.</param>
|
|
||||||
private void CoreWindow_PointerPressed(CoreWindow sender,
|
|
||||||
PointerEventArgs e)
|
|
||||||
{
|
|
||||||
var properties = e.CurrentPoint.Properties;
|
|
||||||
|
|
||||||
// Ignore button chords with the left, right, and middle buttons
|
|
||||||
if (properties.IsLeftButtonPressed || properties.IsRightButtonPressed ||
|
|
||||||
properties.IsMiddleButtonPressed) return;
|
|
||||||
|
|
||||||
// If back or foward are pressed (but not both) navigate appropriately
|
|
||||||
bool backPressed = properties.IsXButton1Pressed;
|
|
||||||
bool forwardPressed = properties.IsXButton2Pressed;
|
|
||||||
if (backPressed ^ forwardPressed)
|
|
||||||
{
|
|
||||||
e.Handled = true;
|
|
||||||
if (backPressed) this.GoBackCommand.Execute(null);
|
|
||||||
if (forwardPressed) this.GoForwardCommand.Execute(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Process lifetime management
|
|
||||||
|
|
||||||
private String _pageKey;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register this event on the current page to populate the page
|
|
||||||
/// with content passed during navigation as well as any saved
|
|
||||||
/// state provided when recreating a page from a prior session.
|
|
||||||
/// </summary>
|
|
||||||
public event LoadStateEventHandler LoadState;
|
|
||||||
/// <summary>
|
|
||||||
/// Register this event on the current page to preserve
|
|
||||||
/// state associated with the current page in case the
|
|
||||||
/// application is suspended or the page is discarded from
|
|
||||||
/// the navigaqtion cache.
|
|
||||||
/// </summary>
|
|
||||||
public event SaveStateEventHandler SaveState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when this page is about to be displayed in a Frame.
|
|
||||||
/// This method calls <see cref="LoadState"/>, where all page specific
|
|
||||||
/// navigation and process lifetime management logic should be placed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
|
||||||
/// property provides the group to be displayed.</param>
|
|
||||||
public void OnNavigatedTo(NavigationEventArgs e)
|
|
||||||
{
|
|
||||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
|
||||||
this._pageKey = "Page-" + this.Frame.BackStackDepth;
|
|
||||||
|
|
||||||
if (e.NavigationMode == NavigationMode.New)
|
|
||||||
{
|
|
||||||
// Clear existing state for forward navigation when adding a new page to the
|
|
||||||
// navigation stack
|
|
||||||
var nextPageKey = this._pageKey;
|
|
||||||
int nextPageIndex = this.Frame.BackStackDepth;
|
|
||||||
while (frameState.Remove(nextPageKey))
|
|
||||||
{
|
|
||||||
nextPageIndex++;
|
|
||||||
nextPageKey = "Page-" + nextPageIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass the navigation parameter to the new page
|
|
||||||
if (this.LoadState != null)
|
|
||||||
{
|
|
||||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Pass the navigation parameter and preserved page state to the page, using
|
|
||||||
// the same strategy for loading suspended state and recreating pages discarded
|
|
||||||
// from cache
|
|
||||||
if (this.LoadState != null)
|
|
||||||
{
|
|
||||||
this.LoadState(this, new LoadStateEventArgs(e.Parameter, (Dictionary<String, Object>)frameState[this._pageKey]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when this page will no longer be displayed in a Frame.
|
|
||||||
/// This method calls <see cref="SaveState"/>, where all page specific
|
|
||||||
/// navigation and process lifetime management logic should be placed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
|
||||||
/// property provides the group to be displayed.</param>
|
|
||||||
public void OnNavigatedFrom(NavigationEventArgs e)
|
|
||||||
{
|
|
||||||
var frameState = SuspensionManager.SessionStateForFrame(this.Frame);
|
|
||||||
var pageState = new Dictionary<String, Object>();
|
|
||||||
if (this.SaveState != null)
|
|
||||||
{
|
|
||||||
this.SaveState(this, new SaveStateEventArgs(pageState));
|
|
||||||
}
|
|
||||||
frameState[_pageKey] = pageState;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Represents the method that will handle the <see cref="NavigationHelper.LoadState"/>event
|
|
||||||
/// </summary>
|
|
||||||
public delegate void LoadStateEventHandler(object sender, LoadStateEventArgs e);
|
|
||||||
/// <summary>
|
|
||||||
/// Represents the method that will handle the <see cref="NavigationHelper.SaveState"/>event
|
|
||||||
/// </summary>
|
|
||||||
public delegate void SaveStateEventHandler(object sender, SaveStateEventArgs e);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Class used to hold the event data required when a page attempts to load state.
|
|
||||||
/// </summary>
|
|
||||||
public class LoadStateEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
|
||||||
/// when this page was initially requested.
|
|
||||||
/// </summary>
|
|
||||||
public Object NavigationParameter { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
/// A dictionary of state preserved by this page during an earlier
|
|
||||||
/// session. This will be null the first time a page is visited.
|
|
||||||
/// </summary>
|
|
||||||
public Dictionary<string, Object> PageState { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="LoadStateEventArgs"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="navigationParameter">
|
|
||||||
/// The parameter value passed to <see cref="Frame.Navigate(Type, Object)"/>
|
|
||||||
/// when this page was initially requested.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="pageState">
|
|
||||||
/// A dictionary of state preserved by this page during an earlier
|
|
||||||
/// session. This will be null the first time a page is visited.
|
|
||||||
/// </param>
|
|
||||||
public LoadStateEventArgs(Object navigationParameter, Dictionary<string, Object> pageState)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
this.NavigationParameter = navigationParameter;
|
|
||||||
this.PageState = pageState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Class used to hold the event data required when a page attempts to save state.
|
|
||||||
/// </summary>
|
|
||||||
public class SaveStateEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An empty dictionary to be populated with serializable state.
|
|
||||||
/// </summary>
|
|
||||||
public Dictionary<string, Object> PageState { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="SaveStateEventArgs"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pageState">An empty dictionary to be populated with serializable state.</param>
|
|
||||||
public SaveStateEventArgs(Dictionary<string, Object> pageState)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
this.PageState = pageState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,141 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Windows.Foundation.Collections;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation of IObservableMap that supports reentrancy for use as a default view
|
|
||||||
/// model.
|
|
||||||
/// </summary>
|
|
||||||
public class ObservableDictionary : IObservableMap<string, object>
|
|
||||||
{
|
|
||||||
private class ObservableDictionaryChangedEventArgs : IMapChangedEventArgs<string>
|
|
||||||
{
|
|
||||||
public ObservableDictionaryChangedEventArgs(CollectionChange change, string key)
|
|
||||||
{
|
|
||||||
CollectionChange = change;
|
|
||||||
Key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CollectionChange CollectionChange { get; private set; }
|
|
||||||
public string Key { get; private set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();
|
|
||||||
public event MapChangedEventHandler<string, object> MapChanged;
|
|
||||||
|
|
||||||
private void InvokeMapChanged(CollectionChange change, string key)
|
|
||||||
{
|
|
||||||
var eventHandler = MapChanged;
|
|
||||||
if (eventHandler != null)
|
|
||||||
{
|
|
||||||
eventHandler(this, new ObservableDictionaryChangedEventArgs(change, key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(string key, object value)
|
|
||||||
{
|
|
||||||
_dictionary.Add(key, value);
|
|
||||||
InvokeMapChanged(CollectionChange.ItemInserted, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(KeyValuePair<string, object> item)
|
|
||||||
{
|
|
||||||
Add(item.Key, item.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRange(IEnumerable<KeyValuePair<string, object>> values)
|
|
||||||
{
|
|
||||||
foreach (var value in values)
|
|
||||||
{
|
|
||||||
Add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(string key)
|
|
||||||
{
|
|
||||||
if (_dictionary.Remove(key))
|
|
||||||
{
|
|
||||||
InvokeMapChanged(CollectionChange.ItemRemoved, key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Remove(KeyValuePair<string, object> item)
|
|
||||||
{
|
|
||||||
object currentValue;
|
|
||||||
if (_dictionary.TryGetValue(item.Key, out currentValue) &&
|
|
||||||
Equals(item.Value, currentValue) && _dictionary.Remove(item.Key))
|
|
||||||
{
|
|
||||||
InvokeMapChanged(CollectionChange.ItemRemoved, item.Key);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object this[string key]
|
|
||||||
{
|
|
||||||
get => _dictionary[key];
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_dictionary[key] = value;
|
|
||||||
InvokeMapChanged(CollectionChange.ItemChanged, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
var priorKeys = _dictionary.Keys.ToArray();
|
|
||||||
_dictionary.Clear();
|
|
||||||
foreach (var key in priorKeys)
|
|
||||||
{
|
|
||||||
InvokeMapChanged(CollectionChange.ItemRemoved, key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICollection<string> Keys => _dictionary.Keys;
|
|
||||||
|
|
||||||
public bool ContainsKey(string key)
|
|
||||||
{
|
|
||||||
return _dictionary.ContainsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetValue(string key, out object value)
|
|
||||||
{
|
|
||||||
return _dictionary.TryGetValue(key, out value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICollection<object> Values => _dictionary.Values;
|
|
||||||
|
|
||||||
public bool Contains(KeyValuePair<string, object> item)
|
|
||||||
{
|
|
||||||
return _dictionary.Contains(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count => _dictionary.Count;
|
|
||||||
|
|
||||||
public bool IsReadOnly => false;
|
|
||||||
|
|
||||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
|
||||||
{
|
|
||||||
return _dictionary.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return _dictionary.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
|
||||||
{
|
|
||||||
int arraySize = array.Length;
|
|
||||||
foreach (var pair in _dictionary)
|
|
||||||
{
|
|
||||||
if (arrayIndex >= arraySize) break;
|
|
||||||
array[arrayIndex++] = pair;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,78 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Windows.Input;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A command whose sole purpose is to relay its functionality
|
|
||||||
/// to other objects by invoking delegates.
|
|
||||||
/// The default return value for the CanExecute method is 'true'.
|
|
||||||
/// <see cref="RaiseCanExecuteChanged"/> needs to be called whenever
|
|
||||||
/// <see cref="CanExecute"/> is expected to return a different value.
|
|
||||||
/// </summary>
|
|
||||||
public class RelayCommand : ICommand
|
|
||||||
{
|
|
||||||
private readonly Action _execute;
|
|
||||||
private readonly Func<bool> _canExecute;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when RaiseCanExecuteChanged is called.
|
|
||||||
/// </summary>
|
|
||||||
public event EventHandler CanExecuteChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new command that can always execute.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="execute">The execution logic.</param>
|
|
||||||
public RelayCommand(Action execute)
|
|
||||||
: this(execute, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new command.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="execute">The execution logic.</param>
|
|
||||||
/// <param name="canExecute">The execution status logic.</param>
|
|
||||||
public RelayCommand(Action execute, Func<bool> canExecute)
|
|
||||||
{
|
|
||||||
if (execute == null)
|
|
||||||
throw new ArgumentNullException(nameof(execute));
|
|
||||||
_execute = execute;
|
|
||||||
_canExecute = canExecute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines whether this <see cref="RelayCommand"/> can execute in its current state.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameter">
|
|
||||||
/// Data used by the command. If the command does not require data to be passed, this object can be set to null.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>true if this command can be executed; otherwise, false.</returns>
|
|
||||||
public bool CanExecute(object parameter)
|
|
||||||
{
|
|
||||||
return _canExecute?.Invoke() ?? true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Executes the <see cref="RelayCommand"/> on the current command target.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameter">
|
|
||||||
/// Data used by the command. If the command does not require data to be passed, this object can be set to null.
|
|
||||||
/// </param>
|
|
||||||
public void Execute(object parameter)
|
|
||||||
{
|
|
||||||
_execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Method used to raise the <see cref="CanExecuteChanged"/> event
|
|
||||||
/// to indicate that the return value of the <see cref="CanExecute"/>
|
|
||||||
/// method has changed.
|
|
||||||
/// </summary>
|
|
||||||
public void RaiseCanExecuteChanged()
|
|
||||||
{
|
|
||||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
using Windows.ApplicationModel.Resources;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
public class ResourceHelper
|
|
||||||
{
|
|
||||||
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,260 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SuspensionManager captures global session state to simplify process lifetime management
|
|
||||||
/// for an application. Note that session state will be automatically cleared under a variety
|
|
||||||
/// of conditions and should only be used to store information that would be convenient to
|
|
||||||
/// carry across sessions, but that should be discarded when an application crashes or is
|
|
||||||
/// upgraded.
|
|
||||||
/// </summary>
|
|
||||||
internal static class SuspensionManager
|
|
||||||
{
|
|
||||||
private static Dictionary<string, object> _sessionState = new Dictionary<string, object>();
|
|
||||||
private static readonly List<Type> _knownTypes = new List<Type>();
|
|
||||||
private const string sessionStateFilename = "_sessionState.xml";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides access to global session state for the current session. This state is
|
|
||||||
/// serialized by <see cref="SaveAsync"/> and restored by
|
|
||||||
/// <see cref="RestoreAsync"/>, so values must be serializable by
|
|
||||||
/// <see cref="DataContractSerializer"/> and should be as compact as possible. Strings
|
|
||||||
/// and other self-contained data types are strongly recommended.
|
|
||||||
/// </summary>
|
|
||||||
public static Dictionary<string, object> SessionState => _sessionState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// List of custom types provided to the <see cref="DataContractSerializer"/> when
|
|
||||||
/// reading and writing session state. Initially empty, additional types may be
|
|
||||||
/// added to customize the serialization process.
|
|
||||||
/// </summary>
|
|
||||||
public static List<Type> KnownTypes => _knownTypes;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Save the current <see cref="SessionState"/>. Any <see cref="Frame"/> instances
|
|
||||||
/// registered with <see cref="RegisterFrame"/> will also preserve their current
|
|
||||||
/// navigation stack, which in turn gives their active <see cref="Page"/> an opportunity
|
|
||||||
/// to save its state.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An asynchronous task that reflects when session state has been saved.</returns>
|
|
||||||
public static async Task SaveAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Save the navigation state for all registered frames
|
|
||||||
foreach (var weakFrameReference in _registeredFrames)
|
|
||||||
{
|
|
||||||
Frame frame;
|
|
||||||
if (weakFrameReference.TryGetTarget(out frame))
|
|
||||||
{
|
|
||||||
SaveFrameNavigationState(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize the session state synchronously to avoid asynchronous access to shared
|
|
||||||
// state
|
|
||||||
MemoryStream sessionData = new MemoryStream();
|
|
||||||
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
|
|
||||||
serializer.WriteObject(sessionData, _sessionState);
|
|
||||||
|
|
||||||
// Get an output stream for the SessionState file and write the state asynchronously
|
|
||||||
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
|
|
||||||
using (Stream fileStream = await file.OpenStreamForWriteAsync())
|
|
||||||
{
|
|
||||||
sessionData.Seek(0, SeekOrigin.Begin);
|
|
||||||
await sessionData.CopyToAsync(fileStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new SuspensionManagerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Restores previously saved <see cref="SessionState"/>. Any <see cref="Frame"/> instances
|
|
||||||
/// registered with <see cref="RegisterFrame"/> will also restore their prior navigation
|
|
||||||
/// state, which in turn gives their active <see cref="Page"/> an opportunity restore its
|
|
||||||
/// state.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sessionBaseKey">An optional key that identifies the type of session.
|
|
||||||
/// This can be used to distinguish between multiple application launch scenarios.</param>
|
|
||||||
/// <returns>An asynchronous task that reflects when session state has been read. The
|
|
||||||
/// content of <see cref="SessionState"/> should not be relied upon until this task
|
|
||||||
/// completes.</returns>
|
|
||||||
public static async Task RestoreAsync(String sessionBaseKey = null)
|
|
||||||
{
|
|
||||||
_sessionState = new Dictionary<String, Object>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Get the input stream for the SessionState file
|
|
||||||
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
|
|
||||||
using (IInputStream inStream = await file.OpenSequentialReadAsync())
|
|
||||||
{
|
|
||||||
// Deserialize the Session State
|
|
||||||
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
|
|
||||||
_sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore any registered frames to their saved state
|
|
||||||
foreach (var weakFrameReference in _registeredFrames)
|
|
||||||
{
|
|
||||||
Frame frame;
|
|
||||||
if (weakFrameReference.TryGetTarget(out frame) && (string)frame.GetValue(FrameSessionBaseKeyProperty) == sessionBaseKey)
|
|
||||||
{
|
|
||||||
frame.ClearValue(FrameSessionStateProperty);
|
|
||||||
RestoreFrameNavigationState(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
throw new SuspensionManagerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DependencyProperty FrameSessionStateKeyProperty =
|
|
||||||
DependencyProperty.RegisterAttached("_FrameSessionStateKey", typeof(String), typeof(SuspensionManager), null);
|
|
||||||
private static DependencyProperty FrameSessionBaseKeyProperty =
|
|
||||||
DependencyProperty.RegisterAttached("_FrameSessionBaseKeyParams", typeof(String), typeof(SuspensionManager), null);
|
|
||||||
private static DependencyProperty FrameSessionStateProperty =
|
|
||||||
DependencyProperty.RegisterAttached("_FrameSessionState", typeof(Dictionary<String, Object>), typeof(SuspensionManager), null);
|
|
||||||
private static List<WeakReference<Frame>> _registeredFrames = new List<WeakReference<Frame>>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to
|
|
||||||
/// and restored from <see cref="SessionState"/>. Frames should be registered once
|
|
||||||
/// immediately after creation if they will participate in session state management. Upon
|
|
||||||
/// registration if state has already been restored for the specified key
|
|
||||||
/// the navigation history will immediately be restored. Subsequent invocations of
|
|
||||||
/// <see cref="RestoreAsync"/> will also restore navigation history.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="frame">An instance whose navigation history should be managed by
|
|
||||||
/// <see cref="SuspensionManager"/></param>
|
|
||||||
/// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to
|
|
||||||
/// store navigation-related information.</param>
|
|
||||||
/// <param name="sessionBaseKey">An optional key that identifies the type of session.
|
|
||||||
/// This can be used to distinguish between multiple application launch scenarios.</param>
|
|
||||||
public static void RegisterFrame(Frame frame, String sessionStateKey, String sessionBaseKey = null)
|
|
||||||
{
|
|
||||||
if (frame.GetValue(FrameSessionStateKeyProperty) != null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Frames can only be registered to one session state key");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame.GetValue(FrameSessionStateProperty) != null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Frames must be either be registered before accessing frame session state, or not registered at all");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(sessionBaseKey))
|
|
||||||
{
|
|
||||||
frame.SetValue(FrameSessionBaseKeyProperty, sessionBaseKey);
|
|
||||||
sessionStateKey = sessionBaseKey + "_" + sessionStateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use a dependency property to associate the session key with a frame, and keep a list of frames whose
|
|
||||||
// navigation state should be managed
|
|
||||||
frame.SetValue(FrameSessionStateKeyProperty, sessionStateKey);
|
|
||||||
_registeredFrames.Add(new WeakReference<Frame>(frame));
|
|
||||||
|
|
||||||
// Check to see if navigation state can be restored
|
|
||||||
RestoreFrameNavigationState(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/>
|
|
||||||
/// from <see cref="SessionState"/>. Any navigation state previously captured will be
|
|
||||||
/// removed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="frame">An instance whose navigation history should no longer be
|
|
||||||
/// managed.</param>
|
|
||||||
public static void UnregisterFrame(Frame frame)
|
|
||||||
{
|
|
||||||
// Remove session state and remove the frame from the list of frames whose navigation
|
|
||||||
// state will be saved (along with any weak references that are no longer reachable)
|
|
||||||
SessionState.Remove((String)frame.GetValue(FrameSessionStateKeyProperty));
|
|
||||||
_registeredFrames.RemoveAll((weakFrameReference) =>
|
|
||||||
{
|
|
||||||
Frame testFrame;
|
|
||||||
return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides storage for session state associated with the specified <see cref="Frame"/>.
|
|
||||||
/// Frames that have been previously registered with <see cref="RegisterFrame"/> have
|
|
||||||
/// their session state saved and restored automatically as a part of the global
|
|
||||||
/// <see cref="SessionState"/>. Frames that are not registered have transient state
|
|
||||||
/// that can still be useful when restoring pages that have been discarded from the
|
|
||||||
/// navigation cache.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Apps may choose to rely on <see cref="NavigationHelper"/> to manage
|
|
||||||
/// page-specific state instead of working with frame session state directly.</remarks>
|
|
||||||
/// <param name="frame">The instance for which session state is desired.</param>
|
|
||||||
/// <returns>A collection of state subject to the same serialization mechanism as
|
|
||||||
/// <see cref="SessionState"/>.</returns>
|
|
||||||
public static Dictionary<String, Object> SessionStateForFrame(Frame frame)
|
|
||||||
{
|
|
||||||
var frameState = (Dictionary<String, Object>)frame.GetValue(FrameSessionStateProperty);
|
|
||||||
|
|
||||||
if (frameState == null)
|
|
||||||
{
|
|
||||||
var frameSessionKey = (String)frame.GetValue(FrameSessionStateKeyProperty);
|
|
||||||
if (frameSessionKey != null)
|
|
||||||
{
|
|
||||||
// Registered frames reflect the corresponding session state
|
|
||||||
if (!_sessionState.ContainsKey(frameSessionKey))
|
|
||||||
{
|
|
||||||
_sessionState[frameSessionKey] = new Dictionary<String, Object>();
|
|
||||||
}
|
|
||||||
frameState = (Dictionary<String, Object>)_sessionState[frameSessionKey];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Frames that aren't registered have transient state
|
|
||||||
frameState = new Dictionary<String, Object>();
|
|
||||||
}
|
|
||||||
frame.SetValue(FrameSessionStateProperty, frameState);
|
|
||||||
}
|
|
||||||
return frameState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RestoreFrameNavigationState(Frame frame)
|
|
||||||
{
|
|
||||||
var frameState = SessionStateForFrame(frame);
|
|
||||||
if (frameState.ContainsKey("Navigation"))
|
|
||||||
{
|
|
||||||
frame.SetNavigationState((String)frameState["Navigation"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SaveFrameNavigationState(Frame frame)
|
|
||||||
{
|
|
||||||
var frameState = SessionStateForFrame(frame);
|
|
||||||
frameState["Navigation"] = frame.GetNavigationState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class SuspensionManagerException : Exception
|
|
||||||
{
|
|
||||||
public SuspensionManagerException()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SuspensionManagerException(Exception e)
|
|
||||||
: base("SuspensionManager failed", e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,53 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.Data.Json;
|
|
||||||
using Windows.Data.Xml.Dom;
|
|
||||||
using Windows.UI.Notifications;
|
|
||||||
using ModernKeePass.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
|
||||||
{
|
|
||||||
public static class ToastNotificationHelper
|
|
||||||
{
|
|
||||||
public static void ShowMovedToast(Entity entity, string action, string text)
|
|
||||||
{
|
|
||||||
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
|
||||||
var toastElements = notificationXml.GetElementsByTagName("text");
|
|
||||||
toastElements[0].AppendChild(notificationXml.CreateTextNode($"{action} {entity.Name}"));
|
|
||||||
toastElements[1].AppendChild(notificationXml.CreateTextNode(text));
|
|
||||||
var toastNode = notificationXml.SelectSingleNode("/toast");
|
|
||||||
|
|
||||||
// This is useful only for Windows 10 UWP
|
|
||||||
var launch = new JsonObject
|
|
||||||
{
|
|
||||||
{"entityType", JsonValue.CreateStringValue(entity.GetType().Name)},
|
|
||||||
{"entityId", JsonValue.CreateStringValue(entity.Id)}
|
|
||||||
};
|
|
||||||
((XmlElement)toastNode)?.SetAttribute("launch", launch.Stringify());
|
|
||||||
|
|
||||||
var toast = new ToastNotification(notificationXml)
|
|
||||||
{
|
|
||||||
ExpirationTime = DateTime.Now.AddSeconds(5)
|
|
||||||
};
|
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowGenericToast(string title, string text)
|
|
||||||
{
|
|
||||||
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
|
||||||
var toastElements = notificationXml.GetElementsByTagName("text");
|
|
||||||
toastElements[0].AppendChild(notificationXml.CreateTextNode(title));
|
|
||||||
toastElements[1].AppendChild(notificationXml.CreateTextNode(text));
|
|
||||||
|
|
||||||
var toast = new ToastNotification(notificationXml)
|
|
||||||
{
|
|
||||||
ExpirationTime = DateTime.Now.AddSeconds(5)
|
|
||||||
};
|
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowErrorToast(Exception exception)
|
|
||||||
{
|
|
||||||
ShowGenericToast(exception.Source, exception.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
|
||||||
using ModernKeePass.Domain.Interfaces;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Controls
|
|
||||||
{
|
|
||||||
public class ListViewWithDisable: ListView
|
|
||||||
{
|
|
||||||
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
|
|
||||||
{
|
|
||||||
base.PrepareContainerForItemOverride(element, item);
|
|
||||||
|
|
||||||
var binaryItem = item as IIsEnabled;
|
|
||||||
if (!(element is ListViewItem container) || binaryItem == null) return;
|
|
||||||
container.IsEnabled = binaryItem.IsEnabled;
|
|
||||||
container.IsHitTestVisible = binaryItem.IsEnabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,56 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Controls
|
|
||||||
{
|
|
||||||
public class TextBoxWithButton : TextBox
|
|
||||||
{
|
|
||||||
public event EventHandler<RoutedEventArgs> ButtonClick;
|
|
||||||
|
|
||||||
public string ButtonSymbol
|
|
||||||
{
|
|
||||||
get => (string)GetValue(ButtonSymbolProperty);
|
|
||||||
set => SetValue(ButtonSymbolProperty, value);
|
|
||||||
}
|
|
||||||
public static readonly DependencyProperty ButtonSymbolProperty =
|
|
||||||
DependencyProperty.Register(
|
|
||||||
"ButtonSymbol",
|
|
||||||
typeof(string),
|
|
||||||
typeof(TextBoxWithButton),
|
|
||||||
new PropertyMetadata("", (o, args) => { }));
|
|
||||||
|
|
||||||
public string ButtonTooltip
|
|
||||||
{
|
|
||||||
get => (string)GetValue(ButtonTooltipProperty);
|
|
||||||
set => SetValue(ButtonTooltipProperty, value);
|
|
||||||
}
|
|
||||||
public static readonly DependencyProperty ButtonTooltipProperty =
|
|
||||||
DependencyProperty.Register(
|
|
||||||
"ButtonTooltip",
|
|
||||||
typeof(string),
|
|
||||||
typeof(TextBoxWithButton),
|
|
||||||
new PropertyMetadata(string.Empty, (o, args) => { }));
|
|
||||||
|
|
||||||
public bool IsButtonEnabled
|
|
||||||
{
|
|
||||||
get => (bool)GetValue(IsButtonEnabledProperty);
|
|
||||||
set => SetValue(IsButtonEnabledProperty, value);
|
|
||||||
}
|
|
||||||
public static readonly DependencyProperty IsButtonEnabledProperty =
|
|
||||||
DependencyProperty.Register(
|
|
||||||
"IsButtonEnabled",
|
|
||||||
typeof(bool),
|
|
||||||
typeof(TextBoxWithButton),
|
|
||||||
new PropertyMetadata(true, (o, args) => { }));
|
|
||||||
|
|
||||||
protected override void OnApplyTemplate()
|
|
||||||
{
|
|
||||||
base.OnApplyTemplate();
|
|
||||||
if (GetTemplateChild("ActionButton") is Button actionButton)
|
|
||||||
{
|
|
||||||
actionButton.Click += (sender, e) => ButtonClick?.Invoke(sender, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
[Obsolete]
|
|
||||||
public class BooleanToVisibilityConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var boolean = value as bool? ?? false;
|
|
||||||
return boolean ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to implement this
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var visibility = value as Visibility? ?? Visibility.Visible;
|
|
||||||
switch (visibility)
|
|
||||||
{
|
|
||||||
case Visibility.Visible: return true;
|
|
||||||
case Visibility.Collapsed: return false;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,22 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class ColorToBrushConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var color = value is Color color1 ? color1 : default(Color);
|
|
||||||
if (color == default(Color) && parameter is SolidColorBrush) return (SolidColorBrush) parameter;
|
|
||||||
return new SolidColorBrush(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
return (value as SolidColorBrush)?.Color ?? new Color();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class DiscreteIntToSolidColorBrushConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var status = System.Convert.ToInt32(value);
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case 1: return new SolidColorBrush(Colors.Red);
|
|
||||||
case 3: return new SolidColorBrush(Colors.Yellow);
|
|
||||||
case 5: return new SolidColorBrush(Colors.Green);
|
|
||||||
default: return new SolidColorBrush(Colors.Black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using Windows.UI.Xaml.Media;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class DoubleToSolidColorBrushConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var currentValue = (double) value;
|
|
||||||
var maxValue = double.Parse(parameter as string);
|
|
||||||
var green = System.Convert.ToByte(currentValue / maxValue * byte.MaxValue);
|
|
||||||
var red = (byte) (byte.MaxValue - green);
|
|
||||||
return new SolidColorBrush(Color.FromArgb(255, red, green, 0));
|
|
||||||
}
|
|
||||||
catch (OverflowException)
|
|
||||||
{
|
|
||||||
return new SolidColorBrush(Color.FromArgb(255, 0, byte.MaxValue, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
class EmptyStringToVisibilityConverter: IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var text = value is string ? value.ToString() : string.Empty;
|
|
||||||
return string.IsNullOrEmpty(text) ? Visibility.Collapsed : Visibility.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,122 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
using ModernKeePass.Domain.Enums;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class IconToSymbolConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var icon = (Icon) value;
|
|
||||||
switch (icon)
|
|
||||||
{
|
|
||||||
case Icon.Delete: return Symbol.Delete;
|
|
||||||
case Icon.Edit: return Symbol.Edit;
|
|
||||||
case Icon.Save: return Symbol.Save;
|
|
||||||
case Icon.Cancel: return Symbol.Cancel;
|
|
||||||
case Icon.Accept: return Symbol.Accept;
|
|
||||||
case Icon.Home: return Symbol.Home;
|
|
||||||
case Icon.Camera: return Symbol.Camera;
|
|
||||||
case Icon.Setting: return Symbol.Setting;
|
|
||||||
case Icon.Mail: return Symbol.Mail;
|
|
||||||
case Icon.Find: return Symbol.Find;
|
|
||||||
case Icon.Help: return Symbol.Help;
|
|
||||||
case Icon.Clock: return Symbol.Clock;
|
|
||||||
case Icon.Crop: return Symbol.Crop;
|
|
||||||
case Icon.World: return Symbol.World;
|
|
||||||
case Icon.Flag: return Symbol.Flag;
|
|
||||||
case Icon.PreviewLink: return Symbol.PreviewLink;
|
|
||||||
case Icon.Document: return Symbol.Document;
|
|
||||||
case Icon.ProtectedDocument: return Symbol.ProtectedDocument;
|
|
||||||
case Icon.ContactInfo: return Symbol.ContactInfo;
|
|
||||||
case Icon.ViewAll: return Symbol.ViewAll;
|
|
||||||
case Icon.Rotate: return Symbol.Rotate;
|
|
||||||
case Icon.List: return Symbol.List;
|
|
||||||
case Icon.Shop: return Symbol.Shop;
|
|
||||||
case Icon.BrowsePhotos: return Symbol.BrowsePhotos;
|
|
||||||
case Icon.Caption: return Symbol.Caption;
|
|
||||||
case Icon.Repair: return Symbol.Repair;
|
|
||||||
case Icon.Page: return Symbol.Page2;
|
|
||||||
case Icon.Paste: return Symbol.Paste;
|
|
||||||
case Icon.Important: return Symbol.Important;
|
|
||||||
case Icon.SlideShow: return Symbol.SlideShow;
|
|
||||||
case Icon.MapDrive: return Symbol.MapDrive;
|
|
||||||
case Icon.ContactPresence: return Symbol.ContactPresence;
|
|
||||||
case Icon.Contact: return Symbol.Contact2;
|
|
||||||
case Icon.Folder: return Symbol.Folder;
|
|
||||||
case Icon.View: return Symbol.View;
|
|
||||||
case Icon.Permissions: return Symbol.Permissions;
|
|
||||||
case Icon.Map: return Symbol.Map;
|
|
||||||
case Icon.CellPhone: return Symbol.CellPhone;
|
|
||||||
case Icon.OutlineStar: return Symbol.OutlineStar;
|
|
||||||
case Icon.Calculator: return Symbol.Calculator;
|
|
||||||
case Icon.Library: return Symbol.Library;
|
|
||||||
case Icon.SyncFolder: return Symbol.SyncFolder;
|
|
||||||
case Icon.GoToStart: return Symbol.GoToStart;
|
|
||||||
case Icon.ZeroBars: return Symbol.ZeroBars;
|
|
||||||
case Icon.FourBars: return Symbol.FourBars;
|
|
||||||
case Icon.Scan: return Symbol.Scan;
|
|
||||||
case Icon.ReportHacked: return Symbol.ReportHacked;
|
|
||||||
default: return Symbol.Stop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var symbol = (Symbol) value;
|
|
||||||
switch (symbol)
|
|
||||||
{
|
|
||||||
case Symbol.Delete: return Icon.Delete;
|
|
||||||
case Symbol.Edit: return Icon.Edit;
|
|
||||||
case Symbol.Save: return Icon.Save;
|
|
||||||
case Symbol.Cancel: return Icon.Cancel;
|
|
||||||
case Symbol.Accept: return Icon.Accept;
|
|
||||||
case Symbol.Home: return Icon.Home;
|
|
||||||
case Symbol.Camera: return Icon.Camera;
|
|
||||||
case Symbol.Setting: return Icon.Setting;
|
|
||||||
case Symbol.Mail: return Icon.Mail;
|
|
||||||
case Symbol.Find: return Icon.Find;
|
|
||||||
case Symbol.Help: return Icon.Help;
|
|
||||||
case Symbol.Clock: return Icon.Clock;
|
|
||||||
case Symbol.Crop: return Icon.Crop;
|
|
||||||
case Symbol.World: return Icon.World;
|
|
||||||
case Symbol.Flag: return Icon.Flag;
|
|
||||||
case Symbol.PreviewLink: return Icon.PreviewLink;
|
|
||||||
case Symbol.Document: return Icon.Document;
|
|
||||||
case Symbol.ProtectedDocument: return Icon.ProtectedDocument;
|
|
||||||
case Symbol.ContactInfo: return Icon.ContactInfo;
|
|
||||||
case Symbol.ViewAll: return Icon.ViewAll;
|
|
||||||
case Symbol.Rotate: return Icon.Rotate;
|
|
||||||
case Symbol.List: return Icon.List;
|
|
||||||
case Symbol.Shop: return Icon.Shop;
|
|
||||||
case Symbol.BrowsePhotos: return Icon.BrowsePhotos;
|
|
||||||
case Symbol.Caption: return Icon.Caption;
|
|
||||||
case Symbol.Repair: return Icon.Repair;
|
|
||||||
case Symbol.Page2: return Icon.Page;
|
|
||||||
case Symbol.Paste: return Icon.Paste;
|
|
||||||
case Symbol.Important: return Icon.Important;
|
|
||||||
case Symbol.SlideShow: return Icon.SlideShow;
|
|
||||||
case Symbol.MapDrive: return Icon.MapDrive;
|
|
||||||
case Symbol.ContactPresence: return Icon.ContactPresence;
|
|
||||||
case Symbol.Contact2: return Icon.Contact;
|
|
||||||
case Symbol.Folder: return Icon.Folder;
|
|
||||||
case Symbol.View: return Icon.View;
|
|
||||||
case Symbol.Permissions: return Icon.Permissions;
|
|
||||||
case Symbol.Map: return Icon.Map;
|
|
||||||
case Symbol.CellPhone: return Icon.CellPhone;
|
|
||||||
case Symbol.OutlineStar: return Icon.OutlineStar;
|
|
||||||
case Symbol.Calculator: return Icon.Calculator;
|
|
||||||
case Symbol.Library: return Icon.Library;
|
|
||||||
case Symbol.SyncFolder: return Icon.SyncFolder;
|
|
||||||
case Symbol.GoToStart: return Icon.GoToStart;
|
|
||||||
case Symbol.ZeroBars: return Icon.ZeroBars;
|
|
||||||
case Symbol.FourBars: return Icon.FourBars;
|
|
||||||
case Symbol.Scan: return Icon.Scan;
|
|
||||||
case Symbol.ReportHacked: return Icon.ReportHacked;
|
|
||||||
default: return Icon.Stop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class InverseBooleanToVisibilityConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var boolean = value as bool? ?? false;
|
|
||||||
return boolean ? Visibility.Collapsed : Visibility.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to implement this
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var visibility = value as Visibility? ?? Visibility.Visible;
|
|
||||||
switch (visibility)
|
|
||||||
{
|
|
||||||
case Visibility.Visible: return false;
|
|
||||||
case Visibility.Collapsed: return true;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class NullToBooleanConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
return value != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class PluralizationConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var pluralizationOptionString = parameter as string;
|
|
||||||
var pluralizationOptions = pluralizationOptionString?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (pluralizationOptions == null || pluralizationOptions.Length != 2) return string.Empty;
|
|
||||||
var count = value is int ? (int) value : 0;
|
|
||||||
var text = count == 1 ? pluralizationOptions[0] : pluralizationOptions[1];
|
|
||||||
return $"{count} {text}";
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to implement this
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class ProgressBarLegalValuesConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var legalValuesOptionString = parameter as string;
|
|
||||||
var legalValuesOptions = legalValuesOptionString?.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (legalValuesOptions == null || legalValuesOptions.Length != 2) return 0;
|
|
||||||
|
|
||||||
var minValue = double.Parse(legalValuesOptions[0]);
|
|
||||||
var maxValue = double.Parse(legalValuesOptions[1]);
|
|
||||||
var count = value is double ? (double)value : 0;
|
|
||||||
if (count > maxValue) return maxValue;
|
|
||||||
if (count < minValue) return minValue;
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Windows.UI.Xaml.Data;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Converters
|
|
||||||
{
|
|
||||||
public class TextToWidthConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
var fontSize = double.Parse(parameter as string);
|
|
||||||
var text = value as string;
|
|
||||||
return text?.Length * fontSize ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using ModernKeePass.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Events
|
|
||||||
{
|
|
||||||
public class PasswordEventArgs: EventArgs
|
|
||||||
{
|
|
||||||
public GroupEntity RootGroupEntity { get; set; }
|
|
||||||
|
|
||||||
public PasswordEventArgs(GroupEntity groupEntity)
|
|
||||||
{
|
|
||||||
RootGroupEntity = groupEntity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.UI.Core;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Extensions
|
|
||||||
{
|
|
||||||
public static class DispatcherTaskExtensions
|
|
||||||
{
|
|
||||||
public static async Task<T> RunTaskAsync<T>(this CoreDispatcher dispatcher,
|
|
||||||
Func<Task<T>> func, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal)
|
|
||||||
{
|
|
||||||
var taskCompletionSource = new TaskCompletionSource<T>();
|
|
||||||
await dispatcher.RunAsync(priority, async () =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
taskCompletionSource.SetResult(await func());
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
taskCompletionSource.SetException(ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return await taskCompletionSource.Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is no TaskCompletionSource<void> so we use a bool that we throw away.
|
|
||||||
public static async Task RunTaskAsync(this CoreDispatcher dispatcher,
|
|
||||||
Func<Task> func, CoreDispatcherPriority priority = CoreDispatcherPriority.Normal) =>
|
|
||||||
await RunTaskAsync(dispatcher, async () => { await func(); return false; }, priority);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
|
|
||||||
namespace ModernKeePass.TemplateSelectors
|
|
||||||
{
|
|
||||||
public class FirstItemDataTemplateSelector: DataTemplateSelector
|
|
||||||
{
|
|
||||||
public DataTemplate FirstItem { get; set; }
|
|
||||||
public DataTemplate OtherItem { get; set; }
|
|
||||||
|
|
||||||
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
|
|
||||||
{
|
|
||||||
var itemsControl = ItemsControl.ItemsControlFromItemContainer(container);
|
|
||||||
var returnTemplate = itemsControl?.IndexFromContainer(container) == 0 ? FirstItem : OtherItem;
|
|
||||||
return returnTemplate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
using Windows.UI.Xaml;
|
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using ModernKeePass.Application.Common.Interfaces;
|
|
||||||
using ModernKeePass.Domain.Interfaces;
|
|
||||||
|
|
||||||
namespace ModernKeePass.TemplateSelectors
|
|
||||||
{
|
|
||||||
public class SelectableDataTemplateSelector: DataTemplateSelector
|
|
||||||
{
|
|
||||||
public DataTemplate TrueItem { get; set; }
|
|
||||||
public DataTemplate FalseItem { get; set; }
|
|
||||||
|
|
||||||
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
|
|
||||||
{
|
|
||||||
return item is ISelectableModel isSelectableItem && isSelectableItem.IsSelected ? TrueItem : FalseItem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -94,16 +94,9 @@
|
|||||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Actions\ClipboardAction.cs" />
|
|
||||||
<Compile Include="Actions\DeleteEntityAction.cs" />
|
|
||||||
<Compile Include="Actions\NavigateToUrlAction.cs" />
|
|
||||||
<Compile Include="Actions\SetupFocusAction.cs" />
|
|
||||||
<Compile Include="Actions\ToastAction.cs" />
|
|
||||||
<Compile Include="App.xaml.cs">
|
<Compile Include="App.xaml.cs">
|
||||||
<DependentUpon>App.xaml</DependentUpon>
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Common\ResourceHelper.cs" />
|
|
||||||
<Compile Include="Converters\IconToSymbolConverter.cs" />
|
|
||||||
<Compile Include="ViewModels\UserControls\UpdateCredentialsViewModel.cs" />
|
<Compile Include="ViewModels\UserControls\UpdateCredentialsViewModel.cs" />
|
||||||
<Compile Include="Views\UserControls\UpdateCredentialsUserControl.xaml.cs">
|
<Compile Include="Views\UserControls\UpdateCredentialsUserControl.xaml.cs">
|
||||||
<DependentUpon>UpdateCredentialsUserControl.xaml</DependentUpon>
|
<DependentUpon>UpdateCredentialsUserControl.xaml</DependentUpon>
|
||||||
@@ -114,7 +107,6 @@
|
|||||||
<Compile Include="ViewModels\EntriesViewModel.cs" />
|
<Compile Include="ViewModels\EntriesViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ListItems\EntryItemViewModel.cs" />
|
<Compile Include="ViewModels\ListItems\EntryItemViewModel.cs" />
|
||||||
<Compile Include="ViewModels\GroupsViewModel.cs" />
|
<Compile Include="ViewModels\GroupsViewModel.cs" />
|
||||||
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
|
||||||
<Compile Include="ViewModels\ListItems\GroupItemViewModel.cs" />
|
<Compile Include="ViewModels\ListItems\GroupItemViewModel.cs" />
|
||||||
<Compile Include="ViewModels\ListItems\SettingsSaveViewModel.cs" />
|
<Compile Include="ViewModels\ListItems\SettingsSaveViewModel.cs" />
|
||||||
<Compile Include="ViewModels\SettingsViewModel.cs" />
|
<Compile Include="ViewModels\SettingsViewModel.cs" />
|
||||||
@@ -133,16 +125,6 @@
|
|||||||
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
<Compile Include="Views\MainPageFrames\DonatePage.xaml.cs">
|
||||||
<DependentUpon>DonatePage.xaml</DependentUpon>
|
<DependentUpon>DonatePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Common\MessageDialogHelper.cs" />
|
|
||||||
<Compile Include="Common\NavigationHelper.cs" />
|
|
||||||
<Compile Include="Common\ObservableDictionary.cs" />
|
|
||||||
<Compile Include="Common\RelayCommand.cs" />
|
|
||||||
<Compile Include="Common\SuspensionManager.cs" />
|
|
||||||
<Compile Include="Common\ToastNotificationHelper.cs" />
|
|
||||||
<Compile Include="Converters\DiscreteIntToSolidColorBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\EmptyStringToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
|
||||||
<Compile Include="Extensions\DispatcherTaskExtensions.cs" />
|
|
||||||
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
<Compile Include="Views\BasePages\LayoutAwarePageBase.cs" />
|
||||||
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs">
|
<Compile Include="Views\MainPageFrames\ImportExportPage.xaml.cs">
|
||||||
<DependentUpon>ImportExportPage.xaml</DependentUpon>
|
<DependentUpon>ImportExportPage.xaml</DependentUpon>
|
||||||
@@ -165,8 +147,6 @@
|
|||||||
<Compile Include="Views\SettingsPageFrames\SettingsWelcomePage.xaml.cs">
|
<Compile Include="Views\SettingsPageFrames\SettingsWelcomePage.xaml.cs">
|
||||||
<DependentUpon>SettingsWelcomePage.xaml</DependentUpon>
|
<DependentUpon>SettingsWelcomePage.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="TemplateSelectors\FirstItemDataTemplateSelector.cs" />
|
|
||||||
<Compile Include="Controls\ListViewWithDisable.cs" />
|
|
||||||
<Compile Include="Views\UserControls\BreadCrumbUserControl.xaml.cs">
|
<Compile Include="Views\UserControls\BreadCrumbUserControl.xaml.cs">
|
||||||
<DependentUpon>BreadCrumbUserControl.xaml</DependentUpon>
|
<DependentUpon>BreadCrumbUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -176,15 +156,6 @@
|
|||||||
<Compile Include="Views\UserControls\CredentialsUserControl.xaml.cs">
|
<Compile Include="Views\UserControls\CredentialsUserControl.xaml.cs">
|
||||||
<DependentUpon>CredentialsUserControl.xaml</DependentUpon>
|
<DependentUpon>CredentialsUserControl.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Controls\TextBoxWithButton.cs" />
|
|
||||||
<Compile Include="Converters\BooleanToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\ColorToBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\DoubleToSolidColorBrushConverter.cs" />
|
|
||||||
<Compile Include="Converters\InverseBooleanToVisibilityConverter.cs" />
|
|
||||||
<Compile Include="Converters\PluralizationConverter.cs" />
|
|
||||||
<Compile Include="Converters\ProgressBarLegalValuesConverter.cs" />
|
|
||||||
<Compile Include="Converters\TextToWidthConverter.cs" />
|
|
||||||
<Compile Include="Events\PasswordEventArgs.cs" />
|
|
||||||
<Content Include="Views\Old\MainPage.xaml.cs">
|
<Content Include="Views\Old\MainPage.xaml.cs">
|
||||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||||
</Content>
|
</Content>
|
||||||
@@ -513,6 +484,7 @@
|
|||||||
<Name>Infrastructure</Name>
|
<Name>Infrastructure</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<Import Project="..\WinAppCommon\WinAppCommon.projitems" Label="Shared" />
|
||||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
42
WinAppCommon/WinAppCommon.projitems
Normal file
42
WinAppCommon/WinAppCommon.projitems
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||||
|
<HasSharedItems>true</HasSharedItems>
|
||||||
|
<SharedGUID>a66b7a53-1d8f-41e2-a8ab-840c81b1aa92</SharedGUID>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Configuration">
|
||||||
|
<Import_RootNamespace>ModernKeePass</Import_RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Actions\ClipboardAction.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Actions\NavigateToUrlAction.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Actions\SetupFocusAction.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Actions\ToastAction.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\Constants.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\MessageDialogHelper.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\NavigationHelper.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\ObservableDictionary.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\RelayCommand.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\SuspensionManager.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Common\ToastNotificationHelper.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Controls\ListViewWithDisable.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Controls\TextBoxWithButton.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\BooleanToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\ColorToBrushConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\DiscreteIntToSolidColorBrushConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\DoubleToSolidColorBrushConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\EmptyStringToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\IconToSymbolConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\InverseBooleanToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\NullToBooleanConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\PluralizationConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\ProgressBarLegalValuesConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Converters\TextToWidthConverter.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Events\PasswordEventArgs.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ColorExtensions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DispatcherTaskExtensions.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\FirstItemDataTemplateSelector.cs" />
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)TemplateSelectors\SelectableDataTemplateSelector.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
13
WinAppCommon/WinAppCommon.shproj
Normal file
13
WinAppCommon/WinAppCommon.shproj
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>a66b7a53-1d8f-41e2-a8ab-840c81b1aa92</ProjectGuid>
|
||||||
|
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
|
||||||
|
<PropertyGroup />
|
||||||
|
<Import Project="WinAppCommon.projitems" Label="Shared" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
|
||||||
|
</Project>
|
Reference in New Issue
Block a user