mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 23:50:18 -04:00
Recycle bin restore function (actually implemented a move functionality, for later)
This commit is contained in:
@@ -20,7 +20,6 @@ namespace ModernKeePass
|
|||||||
sealed partial class App
|
sealed partial class App
|
||||||
{
|
{
|
||||||
public DatabaseHelper Database { get; set; } = new DatabaseHelper();
|
public DatabaseHelper Database { get; set; } = new DatabaseHelper();
|
||||||
public Dictionary<string, IPwEntity> PendingDeleteEntities = new Dictionary<string, IPwEntity>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the singleton application object. This is the first line of authored code
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
@@ -89,11 +88,11 @@ namespace ModernKeePass
|
|||||||
// parameter
|
// parameter
|
||||||
rootFrame.Navigate(typeof(Pages.MainPage), lauchActivatedEventArgs.Arguments);
|
rootFrame.Navigate(typeof(Pages.MainPage), lauchActivatedEventArgs.Arguments);
|
||||||
}
|
}
|
||||||
else
|
/*else
|
||||||
{
|
{
|
||||||
// App is "launched" via the Toast Activation event
|
// App is "launched" via the Toast Activation event
|
||||||
UndoEntityDelete(lauchActivatedEventArgs.Arguments);
|
UndoEntityDelete(lauchActivatedEventArgs.Arguments);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
// This is only available on Windows 10...
|
// This is only available on Windows 10...
|
||||||
/*else if (e is ToastNotificationActivatedEventArgs)
|
/*else if (e is ToastNotificationActivatedEventArgs)
|
||||||
@@ -145,14 +144,5 @@ namespace ModernKeePass
|
|||||||
Window.Current.Activate();
|
Window.Current.Activate();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void UndoEntityDelete(string arguments)
|
|
||||||
{
|
|
||||||
if (arguments == null) return;
|
|
||||||
var args = JsonObject.Parse(arguments);
|
|
||||||
var entity = PendingDeleteEntities[args["entityId"].GetString()];
|
|
||||||
PendingDeleteEntities.Remove(args["entityId"].GetString());
|
|
||||||
entity.UndoDelete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Windows.Storage;
|
using Windows.Storage;
|
||||||
|
using Windows.UI.Xaml;
|
||||||
using ModernKeePass.ViewModels;
|
using ModernKeePass.ViewModels;
|
||||||
using ModernKeePassLib;
|
using ModernKeePassLib;
|
||||||
using ModernKeePassLib.Interfaces;
|
using ModernKeePassLib.Interfaces;
|
||||||
@@ -104,7 +105,14 @@ namespace ModernKeePass.Common
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
if (_pwDatabase != null && _pwDatabase.IsOpen)
|
if (_pwDatabase == null || !_pwDatabase.IsOpen) return;
|
||||||
|
// Commit real changes to DB
|
||||||
|
/*var app = (App) Application.Current;
|
||||||
|
foreach (var entity in app.PendingDeleteEntities)
|
||||||
|
{
|
||||||
|
entity.Value.CommitDelete();
|
||||||
|
}
|
||||||
|
app.PendingDeleteEntities.Clear();*/
|
||||||
_pwDatabase.Save(new NullStatusLogger());
|
_pwDatabase.Save(new NullStatusLogger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,25 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using Windows.UI.Popups;
|
using Windows.UI.Popups;
|
||||||
using Windows.UI.Xaml.Controls;
|
|
||||||
using ModernKeePass.Interfaces;
|
|
||||||
using ModernKeePass.ViewModels;
|
|
||||||
|
|
||||||
namespace ModernKeePass.Common
|
namespace ModernKeePass.Common
|
||||||
{
|
{
|
||||||
public static class MessageDialogHelper
|
public static class MessageDialogHelper
|
||||||
{
|
{
|
||||||
public static async void ShowDeleteConfirmationDialog(string text, IPwEntity model, Frame backFrame)
|
public static async void ShowDeleteConfirmationDialog(string actionText, string contentText, UICommandInvokedHandler action)
|
||||||
{
|
{
|
||||||
// Create the message dialog and set its content
|
// Create the message dialog and set its content
|
||||||
var messageDialog = new MessageDialog(text);
|
var messageDialog = new MessageDialog(contentText);
|
||||||
|
|
||||||
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
// Add commands and set their callbacks; both buttons use the same callback function instead of inline event handlers
|
||||||
messageDialog.Commands.Add(new UICommand("Delete", delete =>
|
messageDialog.Commands.Add(new UICommand(actionText, action));
|
||||||
{
|
|
||||||
ToastNotificationHelper.ShowUndoToast(model);
|
|
||||||
model.MarkForDelete();
|
|
||||||
if (backFrame.CanGoBack) backFrame.GoBack();
|
|
||||||
}));
|
|
||||||
messageDialog.Commands.Add(new UICommand("Cancel"));
|
messageDialog.Commands.Add(new UICommand("Cancel"));
|
||||||
|
|
||||||
// Set the command that will be invoked by default
|
// Set the command that will be invoked by default
|
||||||
|
@@ -10,67 +10,14 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
public static class ToastNotificationHelper
|
public static class ToastNotificationHelper
|
||||||
{
|
{
|
||||||
public static /*async*/ void ShowUndoToast(IPwEntity entity)
|
public static void ShowMovedToast(IPwEntity entity, string action, string text)
|
||||||
{
|
{
|
||||||
// This is for Windows 10
|
var app = (App)Application.Current;
|
||||||
// Construct the visuals of the toast
|
|
||||||
/*var visual = new ToastVisual
|
|
||||||
{
|
|
||||||
BindingGeneric = new ToastBindingGeneric
|
|
||||||
{
|
|
||||||
Children =
|
|
||||||
{
|
|
||||||
new AdaptiveText
|
|
||||||
{
|
|
||||||
Text = $"{entityType} {entity.Name} deleted."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Construct the actions for the toast (inputs and buttons)
|
|
||||||
var actions = new ToastActionsCustom
|
|
||||||
{
|
|
||||||
Buttons =
|
|
||||||
{
|
|
||||||
new ToastButton("Undo", new QueryString
|
|
||||||
{
|
|
||||||
{ "action", "undo" },
|
|
||||||
{ "entityType", entityType },
|
|
||||||
{ "entityId", entity.Id }
|
|
||||||
|
|
||||||
}.ToString())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now we can construct the final toast content
|
|
||||||
var toastContent = new ToastContent
|
|
||||||
{
|
|
||||||
Visual = visual,
|
|
||||||
Actions = actions,
|
|
||||||
// Arguments when the user taps body of toast
|
|
||||||
Launch = new QueryString()
|
|
||||||
{
|
|
||||||
{ "action", "undo" },
|
|
||||||
{ "entityType", "group" },
|
|
||||||
{ "entityId", entity.Id }
|
|
||||||
|
|
||||||
}.ToString()
|
|
||||||
};
|
|
||||||
|
|
||||||
// And create the toast notification
|
|
||||||
var toastXml = new XmlDocument();
|
|
||||||
toastXml.LoadXml(toastContent.GetContent());
|
|
||||||
|
|
||||||
var toast = new ToastNotification(toastXml) {ExpirationTime = DateTime.Now.AddSeconds(5)};
|
|
||||||
toast.Dismissed += Toast_Dismissed;
|
|
||||||
*/
|
|
||||||
|
|
||||||
var entityType = entity is GroupVm ? "Group" : "Entry";
|
var entityType = entity is GroupVm ? "Group" : "Entry";
|
||||||
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
var notificationXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
|
||||||
var toastElements = notificationXml.GetElementsByTagName("text");
|
var toastElements = notificationXml.GetElementsByTagName("text");
|
||||||
toastElements[0].AppendChild(notificationXml.CreateTextNode($"{entityType} {entity.Name} deleted"));
|
toastElements[0].AppendChild(notificationXml.CreateTextNode($"{action} {entityType} {entity.Name}"));
|
||||||
toastElements[1].AppendChild(notificationXml.CreateTextNode("Click me to undo"));
|
toastElements[1].AppendChild(notificationXml.CreateTextNode(text));
|
||||||
var toastNode = notificationXml.SelectSingleNode("/toast");
|
var toastNode = notificationXml.SelectSingleNode("/toast");
|
||||||
|
|
||||||
var launch = new JsonObject
|
var launch = new JsonObject
|
||||||
@@ -84,19 +31,8 @@ namespace ModernKeePass.Common
|
|||||||
{
|
{
|
||||||
ExpirationTime = DateTime.Now.AddSeconds(5)
|
ExpirationTime = DateTime.Now.AddSeconds(5)
|
||||||
};
|
};
|
||||||
toast.Dismissed += Toast_Dismissed;
|
|
||||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Toast_Dismissed(ToastNotification sender, ToastDismissedEventArgs args)
|
|
||||||
{
|
|
||||||
var toastNode = sender.Content.SelectSingleNode("/toast");
|
|
||||||
if (toastNode == null) return;
|
|
||||||
var launchArguments = JsonObject.Parse(((XmlElement)toastNode).GetAttribute("launch"));
|
|
||||||
var app = (App)Application.Current;
|
|
||||||
var entity = app.PendingDeleteEntities[launchArguments["entityId"].GetString()];
|
|
||||||
app.PendingDeleteEntities.Remove(launchArguments["entityId"].GetString());
|
|
||||||
entity.CommitDelete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
ModernKeePass/Converters/NullToBooleanConverter.cs
Normal file
18
ModernKeePass/Converters/NullToBooleanConverter.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,12 +6,18 @@ namespace ModernKeePass.Interfaces
|
|||||||
public interface IPwEntity
|
public interface IPwEntity
|
||||||
{
|
{
|
||||||
GroupVm ParentGroup { get; }
|
GroupVm ParentGroup { get; }
|
||||||
|
GroupVm PreviousGroup { get; }
|
||||||
Symbol IconSymbol { get; }
|
Symbol IconSymbol { get; }
|
||||||
string Id { get; }
|
string Id { get; }
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
string Path { get; }
|
string Path { get; }
|
||||||
bool IsEditMode { get; }
|
bool IsEditMode { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move a entity to the destination group
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="destination">The destination to move the entity to</param>
|
||||||
|
void Move(GroupVm destination);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete from Model
|
/// Delete from Model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -120,6 +120,7 @@
|
|||||||
<Compile Include="Common\RelayCommand.cs" />
|
<Compile Include="Common\RelayCommand.cs" />
|
||||||
<Compile Include="Common\SuspensionManager.cs" />
|
<Compile Include="Common\SuspensionManager.cs" />
|
||||||
<Compile Include="Common\ToastNotificationHelper.cs" />
|
<Compile Include="Common\ToastNotificationHelper.cs" />
|
||||||
|
<Compile Include="Converters\NullToBooleanConverter.cs" />
|
||||||
<Compile Include="Interfaces\IHasSelectableObject.cs" />
|
<Compile Include="Interfaces\IHasSelectableObject.cs" />
|
||||||
<Compile Include="Interfaces\ISelectableModel.cs" />
|
<Compile Include="Interfaces\ISelectableModel.cs" />
|
||||||
<Compile Include="Pages\BasePages\LayoutAwarePageBase.cs" />
|
<Compile Include="Pages\BasePages\LayoutAwarePageBase.cs" />
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest">
|
||||||
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.5.0.25" />
|
<Identity Name="wismna.ModernKeePass" Publisher="CN=0719A91A-C322-4EE0-A257-E60733EECF06" Version="1.6.0.25" />
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>ModernKeePass</DisplayName>
|
<DisplayName>ModernKeePass</DisplayName>
|
||||||
<PublisherDisplayName>wismna</PublisherDisplayName>
|
<PublisherDisplayName>wismna</PublisherDisplayName>
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter"/>
|
||||||
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter"/>
|
||||||
<converters:DoubleToForegroungBrushComplexityConverter x:Key="DoubleToForegroungBrushComplexityConverter"/>
|
<converters:DoubleToForegroungBrushComplexityConverter x:Key="DoubleToForegroungBrushComplexityConverter"/>
|
||||||
|
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||||
<Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle">
|
<Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle">
|
||||||
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
|
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
|
||||||
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
|
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
|
||||||
@@ -396,6 +397,13 @@
|
|||||||
</core:EventTriggerBehavior>
|
</core:EventTriggerBehavior>
|
||||||
</interactivity:Interaction.Behaviors>
|
</interactivity:Interaction.Behaviors>
|
||||||
</AppBarToggleButton>
|
</AppBarToggleButton>
|
||||||
|
<AppBarButton Icon="Undo" Label="Restore" Visibility="{Binding ParentGroup.IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
|
<core:CallMethodAction MethodName="UndoDelete" TargetObject="{Binding}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</AppBarButton>
|
||||||
<AppBarButton Icon="Delete" Label="Delete" Click="DeleteButton_Click" />
|
<AppBarButton Icon="Delete" Label="Delete" Click="DeleteButton_Click" />
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
</Page.BottomAppBar>
|
</Page.BottomAppBar>
|
||||||
|
@@ -1,7 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.UI.Core;
|
|
||||||
using Windows.UI.Popups;
|
|
||||||
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;
|
||||||
@@ -18,21 +15,19 @@ namespace ModernKeePass.Pages
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class EntryDetailPage
|
public sealed partial class EntryDetailPage
|
||||||
{
|
{
|
||||||
private NavigationHelper navigationHelper;
|
|
||||||
|
|
||||||
public EntryVm Model => (EntryVm) DataContext;
|
public EntryVm Model => (EntryVm) DataContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// NavigationHelper est utilisé sur chaque page pour faciliter la navigation et
|
/// NavigationHelper est utilisé sur chaque page pour faciliter la navigation et
|
||||||
/// gestion de la durée de vie des processus
|
/// gestion de la durée de vie des processus
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NavigationHelper NavigationHelper => navigationHelper;
|
public NavigationHelper NavigationHelper { get; }
|
||||||
|
|
||||||
public EntryDetailPage()
|
public EntryDetailPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
navigationHelper = new NavigationHelper(this);
|
NavigationHelper = new NavigationHelper(this);
|
||||||
navigationHelper.LoadState += navigationHelper_LoadState;
|
NavigationHelper.LoadState += navigationHelper_LoadState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,25 +56,37 @@ namespace ModernKeePass.Pages
|
|||||||
|
|
||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
navigationHelper.OnNavigatedTo(e);
|
NavigationHelper.OnNavigatedTo(e);
|
||||||
if (!(e.Parameter is EntryVm)) return;
|
if (!(e.Parameter is EntryVm)) return;
|
||||||
DataContext = (EntryVm)e.Parameter;
|
DataContext = (EntryVm)e.Parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
navigationHelper.OnNavigatedFrom(e);
|
NavigationHelper.OnNavigatedFrom(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var app = (App)Application.Current;
|
var isRecycleBinEnabled = ((App)Application.Current).Database.RecycleBinEnabled && !Model.ParentGroup.IsSelected;
|
||||||
var message = app.Database.RecycleBinEnabled
|
var message = isRecycleBinEnabled
|
||||||
? "Are you sure you want to send this entry to the recycle bin?"
|
? "Are you sure you want to send this entry to the recycle bin?"
|
||||||
: "Are you sure you want to delete this entry?";
|
: "Are you sure you want to delete this entry?";
|
||||||
MessageDialogHelper.ShowDeleteConfirmationDialog(message, Model, Frame);
|
var text = isRecycleBinEnabled ? "Item moved to the Recycle bin" : "Item permanently removed";
|
||||||
|
MessageDialogHelper.ShowDeleteConfirmationDialog("Delete", message, a =>
|
||||||
|
{
|
||||||
|
ToastNotificationHelper.ShowMovedToast(Model, "Deleting", text);
|
||||||
|
Model.MarkForDelete();
|
||||||
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ToastNotificationHelper.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||||
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void UrlButton_Click(object sender, RoutedEventArgs e)
|
private async void UrlButton_Click(object sender, RoutedEventArgs e)
|
||||||
@@ -94,5 +101,6 @@ namespace ModernKeePass.Pages
|
|||||||
// TODO: Show some error
|
// TODO: Show some error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
<SolidColorBrush x:Key="SystemColor" Color="{StaticResource SystemColorButtonFaceColor}" />
|
<SolidColorBrush x:Key="SystemColor" Color="{StaticResource SystemColorButtonFaceColor}" />
|
||||||
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter"/>
|
||||||
<converters:BooleanToFontStyleConverter x:Key="BooleanToFontStyleConverter"/>
|
<converters:BooleanToFontStyleConverter x:Key="BooleanToFontStyleConverter"/>
|
||||||
|
<converters:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||||
|
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
|
||||||
</Page.Resources>
|
</Page.Resources>
|
||||||
<Page.DataContext>
|
<Page.DataContext>
|
||||||
<viewModels:GroupVm />
|
<viewModels:GroupVm />
|
||||||
@@ -47,6 +49,13 @@
|
|||||||
</core:EventTriggerBehavior>
|
</core:EventTriggerBehavior>
|
||||||
</interactivity:Interaction.Behaviors>
|
</interactivity:Interaction.Behaviors>
|
||||||
</AppBarToggleButton>
|
</AppBarToggleButton>
|
||||||
|
<AppBarButton Icon="Undo" Label="Restore" Visibility="{Binding ShowRestore, Converter={StaticResource BooleanToVisibilityConverter}}" IsEnabled="{Binding PreviousGroup, Converter={StaticResource NullToBooleanConverter}}" Click="RestoreButton_Click">
|
||||||
|
<interactivity:Interaction.Behaviors>
|
||||||
|
<core:EventTriggerBehavior EventName="Click">
|
||||||
|
<core:CallMethodAction MethodName="UndoDelete" TargetObject="{Binding}" />
|
||||||
|
</core:EventTriggerBehavior>
|
||||||
|
</interactivity:Interaction.Behaviors>
|
||||||
|
</AppBarButton>
|
||||||
<AppBarButton Icon="Delete" Label="Delete" IsEnabled="{Binding IsNotRoot}" Click="DeleteButton_Click" />
|
<AppBarButton Icon="Delete" Label="Delete" IsEnabled="{Binding IsNotRoot}" Click="DeleteButton_Click" />
|
||||||
</CommandBar>
|
</CommandBar>
|
||||||
</Page.BottomAppBar>
|
</Page.BottomAppBar>
|
||||||
|
@@ -73,7 +73,6 @@ namespace ModernKeePass.Pages
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region Event Handlers
|
#region Event Handlers
|
||||||
|
|
||||||
private void groups_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void groups_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
@@ -112,11 +111,23 @@ namespace ModernKeePass.Pages
|
|||||||
|
|
||||||
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
private void DeleteButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var app = (App) Application.Current;
|
var isRecycleBinEnabled = ((App)Application.Current).Database.RecycleBinEnabled && !Model.IsSelected && !Model.ParentGroup.IsSelected;
|
||||||
var message = app.Database.RecycleBinEnabled
|
var message = isRecycleBinEnabled
|
||||||
? "Are you sure you want to send the whole group and all its entries to the recycle bin?"
|
? "Are you sure you want to send the whole group and all its entries to the recycle bin?"
|
||||||
: "Are you sure you want to delete the whole group and all its entries?";
|
: "Are you sure you want to delete the whole group and all its entries?";
|
||||||
MessageDialogHelper.ShowDeleteConfirmationDialog(message, Model, Frame);
|
var text = isRecycleBinEnabled ? "Item moved to the Recycle bin" : "Item permanently removed";
|
||||||
|
MessageDialogHelper.ShowDeleteConfirmationDialog("Delete", message, a =>
|
||||||
|
{
|
||||||
|
ToastNotificationHelper.ShowMovedToast(Model, "Deleting", text);
|
||||||
|
Model.MarkForDelete();
|
||||||
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RestoreButton_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ToastNotificationHelper.ShowMovedToast(Model, "Restored", "Item returned to its original group");
|
||||||
|
if (Frame.CanGoBack) Frame.GoBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
|
private void SemanticZoom_ViewChangeStarted(object sender, SemanticZoomViewChangedEventArgs e)
|
||||||
|
@@ -24,6 +24,6 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.5.0.0")]
|
[assembly: AssemblyVersion("1.6.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.5.0.0")]
|
[assembly: AssemblyFileVersion("1.6.0.0")]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
@@ -14,7 +14,9 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
public class EntryVm : INotifyPropertyChanged, IPwEntity
|
public class EntryVm : INotifyPropertyChanged, IPwEntity
|
||||||
{
|
{
|
||||||
public GroupVm ParentGroup { get; }
|
public GroupVm ParentGroup { get; private set; }
|
||||||
|
|
||||||
|
public GroupVm PreviousGroup { get; private set; }
|
||||||
|
|
||||||
public System.Drawing.Color? BackgroundColor => _pwEntry?.BackgroundColor;
|
public System.Drawing.Color? BackgroundColor => _pwEntry?.BackgroundColor;
|
||||||
public System.Drawing.Color? ForegroundColor => _pwEntry?.ForegroundColor;
|
public System.Drawing.Color? ForegroundColor => _pwEntry?.ForegroundColor;
|
||||||
@@ -194,24 +196,36 @@ namespace ModernKeePass.ViewModels
|
|||||||
|
|
||||||
public void MarkForDelete()
|
public void MarkForDelete()
|
||||||
{
|
{
|
||||||
_app.PendingDeleteEntities.Add(Id, this);
|
Move(_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected ? _app.Database.RecycleBin : null);
|
||||||
ParentGroup.Entries.Remove(this);
|
}
|
||||||
if (_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected) _app.Database.RecycleBin.Entries.Add(this);
|
|
||||||
|
public void UndoDelete()
|
||||||
|
{
|
||||||
|
Move(PreviousGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Move(GroupVm destination)
|
||||||
|
{
|
||||||
|
PreviousGroup = ParentGroup;
|
||||||
|
PreviousGroup.Entries.Remove(this);
|
||||||
|
PreviousGroup.RemovePwEntry(_pwEntry);
|
||||||
|
if (destination == null)
|
||||||
|
{
|
||||||
|
_app.Database.AddDeletedItem(IdUuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParentGroup = destination;
|
||||||
|
ParentGroup.Entries.Add(this);
|
||||||
|
ParentGroup.AddPwEntry(_pwEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommitDelete()
|
public void CommitDelete()
|
||||||
{
|
{
|
||||||
_pwEntry.ParentGroup.Entries.Remove(_pwEntry);
|
_pwEntry.ParentGroup.Entries.Remove(_pwEntry);
|
||||||
if (_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected) _app.Database.RecycleBin.AddPwEntry(_pwEntry);
|
if (_app.Database.RecycleBinEnabled && !PreviousGroup.IsSelected) _app.Database.RecycleBin.AddPwEntry(_pwEntry);
|
||||||
else _app.Database.AddDeletedItem(IdUuid);
|
else _app.Database.AddDeletedItem(IdUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UndoDelete()
|
|
||||||
{
|
|
||||||
ParentGroup.Entries.Add(this);
|
|
||||||
if (_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected) _app.Database.RecycleBin.Entries.Remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
_app.Database.Save();
|
_app.Database.Save();
|
||||||
|
@@ -13,7 +13,8 @@ namespace ModernKeePass.ViewModels
|
|||||||
{
|
{
|
||||||
public class GroupVm : NotifyPropertyChangedBase, IPwEntity, ISelectableModel
|
public class GroupVm : NotifyPropertyChangedBase, IPwEntity, ISelectableModel
|
||||||
{
|
{
|
||||||
public GroupVm ParentGroup { get; }
|
public GroupVm ParentGroup { get; private set; }
|
||||||
|
public GroupVm PreviousGroup { get; private set; }
|
||||||
public ObservableCollection<EntryVm> Entries { get; set; } = new ObservableCollection<EntryVm>();
|
public ObservableCollection<EntryVm> Entries { get; set; } = new ObservableCollection<EntryVm>();
|
||||||
|
|
||||||
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
public ObservableCollection<GroupVm> Groups { get; set; } = new ObservableCollection<GroupVm>();
|
||||||
@@ -24,6 +25,8 @@ namespace ModernKeePass.ViewModels
|
|||||||
public PwUuid IdUuid => _pwGroup?.Uuid;
|
public PwUuid IdUuid => _pwGroup?.Uuid;
|
||||||
public string Id => IdUuid?.ToHexString();
|
public string Id => IdUuid?.ToHexString();
|
||||||
public bool IsNotRoot => ParentGroup != null;
|
public bool IsNotRoot => ParentGroup != null;
|
||||||
|
|
||||||
|
public bool ShowRestore => IsNotRoot && ParentGroup.IsSelected;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is the Group the database Recycle Bin?
|
/// Is the Group the database Recycle Bin?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -123,26 +126,44 @@ namespace ModernKeePass.ViewModels
|
|||||||
_pwGroup.AddEntry(entry, true);
|
_pwGroup.AddEntry(entry, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RemovePwEntry(PwEntry entry)
|
||||||
|
{
|
||||||
|
_pwGroup.Entries.Remove(entry);
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkForDelete()
|
public void MarkForDelete()
|
||||||
{
|
{
|
||||||
_app.PendingDeleteEntities.Add(Id, this);
|
Move(_app.Database.RecycleBinEnabled && !IsSelected ? _app.Database.RecycleBin : null);
|
||||||
ParentGroup.Groups.Remove(this);
|
}
|
||||||
if (_app.Database.RecycleBinEnabled && !IsSelected) _app.Database.RecycleBin.Groups.Add(this);
|
|
||||||
|
|
||||||
|
public void UndoDelete()
|
||||||
|
{
|
||||||
|
Move(PreviousGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Move(GroupVm destination)
|
||||||
|
{
|
||||||
|
PreviousGroup = ParentGroup;
|
||||||
|
PreviousGroup.Groups.Remove(this);
|
||||||
|
PreviousGroup._pwGroup.Groups.Remove(_pwGroup);
|
||||||
|
if (destination == null)
|
||||||
|
{
|
||||||
|
_app.Database.AddDeletedItem(IdUuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParentGroup = destination;
|
||||||
|
ParentGroup.Groups.Add(this);
|
||||||
|
ParentGroup._pwGroup.AddGroup(_pwGroup, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommitDelete()
|
public void CommitDelete()
|
||||||
{
|
{
|
||||||
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
|
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
|
||||||
if (_app.Database.RecycleBinEnabled && !IsSelected) _app.Database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
|
if (_app.Database.RecycleBinEnabled && !PreviousGroup.IsSelected) _app.Database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
|
||||||
else _app.Database.AddDeletedItem(IdUuid);
|
else _app.Database.AddDeletedItem(IdUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UndoDelete()
|
|
||||||
{
|
|
||||||
ParentGroup.Groups.Add(this);
|
|
||||||
if (_app.Database.RecycleBinEnabled && !IsSelected) _app.Database.RecycleBin.Groups.Remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
_app.Database.Save();
|
_app.Database.Save();
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
public static bool IsRequired(int i)
|
public static bool IsRequired(int i)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user