Auto create new recycle bin if needed

Entries now also make use of the recycle bin
New path indication below groups and entries title
Password generator now has custom characters back (working thanks to lib 2.37)
This commit is contained in:
2017-10-31 12:14:26 +01:00
committed by BONNEVILLE Geoffroy
parent 699452667c
commit d32f312d60
8 changed files with 504 additions and 58 deletions

View File

@@ -116,5 +116,10 @@ namespace ModernKeePass.Common
_pwDatabase?.Close();
Status = DatabaseStatus.Closed;
}
public void AddDeletedItem(PwUuid id)
{
_pwDatabase.DeletedObjects.Add(new PwDeletedObject(id, DateTime.UtcNow));
}
}
}

View File

@@ -9,6 +9,7 @@ namespace ModernKeePass.Interfaces
Symbol IconSymbol { get; }
string Id { get; }
string Name { get; set; }
string Path { get; }
bool IsEditMode { get; }
/// <summary>

View File

@@ -78,5 +78,400 @@ namespace ModernKeePass.Mappings
default: return Symbol.Stop;
}
}
public static PwIcon GetIconFromSymbol(Symbol symbol)
{
switch (symbol)
{
/*case Symbol.Previous:
break;
case Symbol.Next:
break;
case Symbol.Play:
break;
case Symbol.Pause:
break;
case Symbol.Edit:
break;
case Symbol.Save:
break;
case Symbol.Clear:
break;*/
case Symbol.Delete:
return PwIcon.TrashBin;
/*case Symbol.Remove:
break;
case Symbol.Add:
break;
case Symbol.Cancel:
break;
case Symbol.Accept:
break;
case Symbol.More:
break;
case Symbol.Redo:
break;
case Symbol.Undo:
break;
case Symbol.Home:
break;
case Symbol.Up:
break;
case Symbol.Forward:
break;
case Symbol.Back:
break;
case Symbol.Favorite:
break;
case Symbol.Camera:
break;
case Symbol.Setting:
break;
case Symbol.Video:
break;
case Symbol.Sync:
break;
case Symbol.Download:
break;
case Symbol.Mail:
break;
case Symbol.Find:
break;
case Symbol.Help:
break;
case Symbol.Upload:
break;
case Symbol.Emoji:
break;
case Symbol.TwoPage:
break;
case Symbol.LeaveChat:
break;
case Symbol.MailForward:
break;
case Symbol.Clock:
break;
case Symbol.Send:
break;
case Symbol.Crop:
break;
case Symbol.RotateCamera:
break;
case Symbol.People:
break;
case Symbol.OpenPane:
break;
case Symbol.ClosePane:
break;
case Symbol.World:
break;
case Symbol.Flag:
break;
case Symbol.PreviewLink:
break;
case Symbol.Globe:
break;
case Symbol.Trim:
break;
case Symbol.AttachCamera:
break;
case Symbol.ZoomIn:
break;
case Symbol.Bookmarks:
break;
case Symbol.Document:
break;
case Symbol.ProtectedDocument:
break;
case Symbol.Page:
break;
case Symbol.Bullets:
break;
case Symbol.Comment:
break;
case Symbol.MailFilled:
break;
case Symbol.ContactInfo:
break;
case Symbol.HangUp:
break;
case Symbol.ViewAll:
break;
case Symbol.MapPin:
break;
case Symbol.Phone:
break;
case Symbol.VideoChat:
break;
case Symbol.Switch:
break;
case Symbol.Contact:
break;
case Symbol.Rename:
break;
case Symbol.Pin:
break;
case Symbol.MusicInfo:
break;
case Symbol.Go:
break;
case Symbol.Keyboard:
break;
case Symbol.DockLeft:
break;
case Symbol.DockRight:
break;
case Symbol.DockBottom:
break;
case Symbol.Remote:
break;
case Symbol.Refresh:
break;
case Symbol.Rotate:
break;
case Symbol.Shuffle:
break;
case Symbol.List:
break;
case Symbol.Shop:
break;
case Symbol.SelectAll:
break;
case Symbol.Orientation:
break;
case Symbol.Import:
break;
case Symbol.ImportAll:
break;
case Symbol.BrowsePhotos:
break;
case Symbol.WebCam:
break;
case Symbol.Pictures:
break;
case Symbol.SaveLocal:
break;
case Symbol.Caption:
break;
case Symbol.Stop:
break;
case Symbol.ShowResults:
break;
case Symbol.Volume:
break;
case Symbol.Repair:
break;
case Symbol.Message:
break;
case Symbol.Page2:
break;
case Symbol.CalendarDay:
break;
case Symbol.CalendarWeek:
break;
case Symbol.Calendar:
break;
case Symbol.Character:
break;
case Symbol.MailReplyAll:
break;
case Symbol.Read:
break;
case Symbol.Link:
break;
case Symbol.Account:
break;
case Symbol.ShowBcc:
break;
case Symbol.HideBcc:
break;
case Symbol.Cut:
break;
case Symbol.Attach:
break;
case Symbol.Paste:
break;
case Symbol.Filter:
break;
case Symbol.Copy:
break;
case Symbol.Emoji2:
break;
case Symbol.Important:
break;
case Symbol.MailReply:
break;
case Symbol.SlideShow:
break;
case Symbol.Sort:
break;
case Symbol.Manage:
break;
case Symbol.AllApps:
break;
case Symbol.DisconnectDrive:
break;
case Symbol.MapDrive:
break;
case Symbol.NewWindow:
break;
case Symbol.OpenWith:
break;
case Symbol.ContactPresence:
break;
case Symbol.Priority:
break;
case Symbol.GoToToday:
break;
case Symbol.Font:
break;
case Symbol.FontColor:
break;
case Symbol.Contact2:
break;
case Symbol.Folder:
break;
case Symbol.Audio:
break;
case Symbol.Placeholder:
break;
case Symbol.View:
break;
case Symbol.SetLockScreen:
break;
case Symbol.SetTile:
break;
case Symbol.ClosedCaption:
break;
case Symbol.StopSlideShow:
break;
case Symbol.Permissions:
break;
case Symbol.Highlight:
break;
case Symbol.DisableUpdates:
break;
case Symbol.UnFavorite:
break;
case Symbol.UnPin:
break;
case Symbol.OpenLocal:
break;
case Symbol.Mute:
break;
case Symbol.Italic:
break;
case Symbol.Underline:
break;
case Symbol.Bold:
break;
case Symbol.MoveToFolder:
break;
case Symbol.LikeDislike:
break;
case Symbol.Dislike:
break;
case Symbol.Like:
break;
case Symbol.AlignRight:
break;
case Symbol.AlignCenter:
break;
case Symbol.AlignLeft:
break;
case Symbol.Zoom:
break;
case Symbol.ZoomOut:
break;
case Symbol.OpenFile:
break;
case Symbol.OtherUser:
break;
case Symbol.Admin:
break;
case Symbol.Street:
break;
case Symbol.Map:
break;
case Symbol.ClearSelection:
break;
case Symbol.FontDecrease:
break;
case Symbol.FontIncrease:
break;
case Symbol.FontSize:
break;
case Symbol.CellPhone:
break;
case Symbol.ReShare:
break;
case Symbol.Tag:
break;
case Symbol.RepeatOne:
break;
case Symbol.RepeatAll:
break;
case Symbol.OutlineStar:
break;
case Symbol.SolidStar:
break;
case Symbol.Calculator:
break;
case Symbol.Directions:
break;
case Symbol.Target:
break;
case Symbol.Library:
break;
case Symbol.PhoneBook:
break;
case Symbol.Memo:
break;
case Symbol.Microphone:
break;
case Symbol.PostUpdate:
break;
case Symbol.BackToWindow:
break;
case Symbol.FullScreen:
break;
case Symbol.NewFolder:
break;
case Symbol.CalendarReply:
break;
case Symbol.UnSyncFolder:
break;
case Symbol.ReportHacked:
break;
case Symbol.SyncFolder:
break;
case Symbol.BlockContact:
break;
case Symbol.SwitchApps:
break;
case Symbol.AddFriend:
break;
case Symbol.TouchPointer:
break;
case Symbol.GoToStart:
break;
case Symbol.ZeroBars:
break;
case Symbol.OneBar:
break;
case Symbol.TwoBars:
break;
case Symbol.ThreeBars:
break;
case Symbol.FourBars:
break;
case Symbol.Scan:
break;
case Symbol.Preview:
break;*/
default:
return PwIcon.Folder;
}
}
}
}

View File

@@ -348,6 +348,8 @@
<CheckBox IsChecked="{Binding SpacePatternSelected, Mode=TwoWay}" Content="Space ( )"/>
<CheckBox IsChecked="{Binding SpecialPatternSelected, Mode=TwoWay}" Content="Special (!, $, %, ...)"/>
<CheckBox IsChecked="{Binding BracketsPatternSelected, Mode=TwoWay}" Content="Brackets ([], {}, (), ...)"/>
<TextBlock Text="Also add these characters:" Margin="0,5,0,0"/>
<TextBox Text="{Binding CustomChars, Mode=TwoWay}" />
<Button Content="Generate">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Click">
@@ -404,7 +406,7 @@
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
@@ -450,7 +452,7 @@
<Button Grid.Column="0"
x:Name="BackButton"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="40"
Height="50"
Width="50"
VerticalAlignment="Center"
AutomationProperties.Name="Back"
@@ -459,25 +461,27 @@
Style="{StaticResource NoBorderButtonStyle}">
<SymbolIcon Symbol="Back" />
</Button>
<TextBox
Grid.Column="1"
x:Name="TitleTextBox"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
Background="Transparent"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="24"
FontWeight="SemiBold"
TextWrapping="NoWrap"
VerticalAlignment="Center"
PlaceholderText="New group name...">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding IsEditMode}" Value="True">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<StackPanel Grid.Column="1" >
<TextBox
x:Name="TitleTextBox"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
Background="Transparent"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="20"
FontWeight="SemiBold"
TextWrapping="NoWrap"
VerticalAlignment="Center"
PlaceholderText="New entry name...">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding IsEditMode}" Value="True">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<TextBlock FontSize="12" Text="{Binding Path}" />
</StackPanel>
</Grid>
</Grid>
</Page>

View File

@@ -71,7 +71,7 @@
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
@@ -259,7 +259,7 @@
<Button Grid.Column="0"
x:Name="BackButton"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=PageRoot}"
Height="40"
Height="50"
Width="50"
VerticalAlignment="Center"
AutomationProperties.Name="Back"
@@ -268,25 +268,27 @@
Style="{StaticResource NoBorderButtonStyle}">
<SymbolIcon Symbol="Back" />
</Button>
<TextBox
Grid.Column="1"
x:Name="TitleTextBox"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
Background="Transparent"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="24"
FontWeight="SemiBold"
TextWrapping="NoWrap"
VerticalAlignment="Center"
PlaceholderText="New group name...">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding IsEditMode}" Value="True">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<StackPanel Grid.Column="1" >
<TextBox
x:Name="TitleTextBox"
Text="{Binding Name, Mode=TwoWay}"
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}"
Background="Transparent"
IsHitTestVisible="{Binding IsEditMode}"
BorderThickness="0"
FontSize="20"
FontWeight="SemiBold"
TextWrapping="NoWrap"
VerticalAlignment="Center"
PlaceholderText="New group name...">
<interactivity:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="{Binding IsEditMode}" Value="True">
<actions:SetupFocusAction TargetObject="{Binding ElementName=TitleTextBox}" />
</core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBox>
<TextBlock FontSize="12" Text="{Binding Path}" />
</StackPanel>
<SearchBox Grid.Column="2" PlaceholderText="Search..." Width="350" Background="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" BorderThickness="0" FontSize="18" SuggestionsRequested="SearchBox_OnSuggestionsRequested" SearchHistoryEnabled="False" ResultSuggestionChosen="SearchBox_OnResultSuggestionChosen" />
</Grid>
</Grid>

View File

@@ -84,7 +84,7 @@ namespace ModernKeePass.Pages
case -1:
return;
case 0:
group = Model.CreateNewGroup();
group = Model.AddNewGroup();
break;
default:
group = LeftListView.SelectedItem as GroupVm;
@@ -101,7 +101,7 @@ namespace ModernKeePass.Pages
case -1:
return;
case 0:
entry = Model.CreateNewEntry();
entry = Model.AddNewEntry();
break;
default:
entry = GridView.SelectedItem as EntryVm;

View File

@@ -1,12 +1,13 @@
using System.ComponentModel;
using System;
using System.ComponentModel;
using System.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Interfaces;
using ModernKeePass.Mappings;
using ModernKeePassLib;
using ModernKeePassLib.Cryptography.PasswordGenerator;
using ModernKeePassLib.Security;
using System;
using Windows.UI.Xaml;
using ModernKeePassLib.Cryptography;
namespace ModernKeePass.ViewModels
@@ -32,6 +33,7 @@ namespace ModernKeePass.ViewModels
public bool SpecialPatternSelected { get; set; }
public bool BracketsPatternSelected { get; set; }
public string CustomChars { get; set; } = string.Empty;
public PwUuid IdUuid => _pwEntry?.Uuid;
public string Name
{
@@ -122,9 +124,20 @@ namespace ModernKeePass.ViewModels
}
}
public string Path
{
get
{
var path = new StringBuilder(ParentGroup.Path);
path.Append($" > {ParentGroup.Name}");
return path.ToString();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private readonly PwEntry _pwEntry;
private readonly App _app = (App)Application.Current;
private bool _isEditMode;
private bool _isRevealPassword;
@@ -139,8 +152,7 @@ namespace ModernKeePass.ViewModels
_pwEntry = entry;
ParentGroup = parent;
}
public void GeneratePassword()
{
var pwProfile = new PwProfile()
@@ -182,24 +194,27 @@ namespace ModernKeePass.ViewModels
public void MarkForDelete()
{
var app = (App)Application.Current;
app.PendingDeleteEntities.Add(Id, this);
_app.PendingDeleteEntities.Add(Id, this);
ParentGroup.Entries.Remove(this);
if (_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected) _app.Database.RecycleBin.Entries.Add(this);
}
public void CommitDelete()
{
_pwEntry.ParentGroup.Entries.Remove(_pwEntry);
if (_app.Database.RecycleBinEnabled && !ParentGroup.IsSelected) _app.Database.RecycleBin.AddPwEntry(_pwEntry);
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()
{
var app = (App)Application.Current;
app.Database.Save();
_app.Database.Save();
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@@ -31,8 +32,13 @@ namespace ModernKeePass.ViewModels
get { return _app.Database.RecycleBinEnabled && _app.Database.RecycleBin.Id == Id; }
set
{
// TODO: if _pwGroup is null, create a new group
if (value && _pwGroup != null) _app.Database.RecycleBin = this;
else if (value && _pwGroup == null)
{
var recycleBin = _app.Database.RootGroup.AddNewGroup("Recycle bin");
recycleBin.IsSelected = true;
recycleBin.IconSymbol = Symbol.Delete;
}
}
}
@@ -56,6 +62,7 @@ namespace ModernKeePass.ViewModels
var result = PwIconToSegoeMapping.GetSymbolFromIcon(_pwGroup.IconId);
return result == Symbol.More ? Symbol.Folder : result;
}
set { _pwGroup.IconId = PwIconToSegoeMapping.GetIconFromSymbol(value); }
}
public bool IsEditMode
@@ -64,6 +71,17 @@ namespace ModernKeePass.ViewModels
set { SetProperty(ref _isEditMode, value); }
}
public string Path
{
get
{
if (ParentGroup == null) return string.Empty;
var path = new StringBuilder(ParentGroup.Path);
path.Append($" > {ParentGroup.Name}");
return path.ToString();
}
}
private readonly PwGroup _pwGroup;
private readonly App _app = (App)Application.Current;
private bool _isEditMode;
@@ -82,16 +100,16 @@ namespace ModernKeePass.ViewModels
Groups.Insert(0, new GroupVm ());
}
public GroupVm CreateNewGroup()
public GroupVm AddNewGroup(string name = "")
{
var pwGroup = new PwGroup(true, true, string.Empty, PwIcon.Folder);
var pwGroup = new PwGroup(true, true, name, PwIcon.Folder);
_pwGroup.AddGroup(pwGroup, true);
var newGroup = new GroupVm(pwGroup, this) {IsEditMode = true};
var newGroup = new GroupVm(pwGroup, this) {Name = name, IsEditMode = string.IsNullOrEmpty(name)};
Groups.Add(newGroup);
return newGroup;
}
public EntryVm CreateNewEntry()
public EntryVm AddNewEntry()
{
var pwEntry = new PwEntry(true, true);
_pwGroup.AddEntry(pwEntry, true);
@@ -99,6 +117,11 @@ namespace ModernKeePass.ViewModels
Entries.Add(newEntry);
return newEntry;
}
public void AddPwEntry(PwEntry entry)
{
_pwGroup.AddEntry(entry, true);
}
public void MarkForDelete()
{
@@ -111,6 +134,7 @@ namespace ModernKeePass.ViewModels
{
_pwGroup.ParentGroup.Groups.Remove(_pwGroup);
if (_app.Database.RecycleBinEnabled && !IsSelected) _app.Database.RecycleBin._pwGroup.AddGroup(_pwGroup, true);
else _app.Database.AddDeletedItem(IdUuid);
}
public void UndoDelete()