Display a big database size warning

Auto rename additional field when it matches standard
Treated all fields as new Field class
Added the Is Protected property
This commit is contained in:
Geoffroy BONNEVILLE
2020-05-12 17:14:30 +02:00
parent d6dc6a74a3
commit f8f7c19f65
34 changed files with 300 additions and 159 deletions

View File

@@ -276,4 +276,10 @@
<data name="CompositeKeyFileNameSuggestion" xml:space="preserve">
<value>Key</value>
</data>
<data name="DatabaseTooBigDescription" xml:space="preserve">
<value>Database size is too big for auto-save on suspend. Please save your changes before closing the app !</value>
</data>
<data name="DatabaseTooBigTitle" xml:space="preserve">
<value>Attention</value>
</data>
</root>

View File

@@ -376,7 +376,7 @@
<value>New group</value>
</data>
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
<value>Navigation</value>
<value>Groups</value>
</data>
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
<value>History</value>
@@ -546,4 +546,16 @@
<data name="EntryAdditionalFieldNameReserved.Text" xml:space="preserve">
<value>Invalid field name</value>
</data>
<data name="EntryEnableFieldProtection.Header" xml:space="preserve">
<value>Enable protection ?</value>
</data>
<data name="EntryEnableFieldProtection.OffContent" xml:space="preserve">
<value>No</value>
</data>
<data name="EntryEnableFieldProtection.OnContent" xml:space="preserve">
<value>Yes</value>
</data>
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
<value>Restore</value>
</data>
</root>

View File

@@ -279,4 +279,10 @@
<data name="EntryAddAdditionalField.Text" xml:space="preserve">
<value>Ajouter un champ</value>
</data>
<data name="DatabaseTooBigDescription" xml:space="preserve">
<value>La base de données est trop grosse pour sauvegarder automatiquement lors de la suspension. Pensez à bien sauvegarder vos changements avant de fermer l'app !</value>
</data>
<data name="DatabaseTooBigTitle" xml:space="preserve">
<value>Attention</value>
</data>
</root>

View File

@@ -379,7 +379,7 @@
<value>Nouveau groupe</value>
</data>
<data name="GroupsLeftListView.HeaderLabel" xml:space="preserve">
<value>Navigation</value>
<value>Groupes</value>
</data>
<data name="HistoryLeftListView.HeaderLabel" xml:space="preserve">
<value>Historique</value>
@@ -543,4 +543,16 @@
<data name="EntryAdditionalFieldNameReserved.Text" xml:space="preserve">
<value>Nom de champ invalide</value>
</data>
<data name="EntryEnableFieldProtection.Header" xml:space="preserve">
<value>Activer la protection ?</value>
</data>
<data name="EntryEnableFieldProtection.OffContent" xml:space="preserve">
<value>Non</value>
</data>
<data name="EntryEnableFieldProtection.OnContent" xml:space="preserve">
<value>Oui</value>
</data>
<data name="TopMenuRestoreButton.Content" xml:space="preserve">
<value>Restaurer</value>
</data>
</root>

View File

@@ -68,7 +68,7 @@ namespace ModernKeePass.ViewModels
}
public ObservableCollection<EntryVm> History { get; private set; }
public ObservableCollection<FieldVm> AdditionalFields { get; private set; }
public ObservableCollection<EntryFieldVm> AdditionalFields { get; private set; }
public ObservableCollection<Attachment> Attachments { get; private set; }
/// <summary>
@@ -85,8 +85,8 @@ namespace ModernKeePass.ViewModels
if (value != null)
{
AdditionalFields =
new ObservableCollection<FieldVm>(
SelectedItem.AdditionalFields.Select(f => new FieldVm(f.Key, f.Value)));
new ObservableCollection<EntryFieldVm>(
SelectedItem.AdditionalFields.Select(f => new EntryFieldVm(f.Name, f.Value, f.IsProtected)));
Attachments = new ObservableCollection<Attachment>(SelectedItem.Attachments.Select(f => new Attachment
{
Name = f.Key,
@@ -131,32 +131,32 @@ namespace ModernKeePass.ViewModels
public string Title
{
get { return SelectedItem.Title; }
get { return SelectedItem.Title.Value; }
set
{
SelectedItem.Title = value;
SetFieldValue(nameof(Title), value).Wait();
SelectedItem.Title.Value = value;
SetFieldValue(nameof(Title), value, true).Wait();
}
}
public string UserName
{
get { return SelectedItem.Username; }
get { return SelectedItem.Username.Value; }
set
{
SelectedItem.Username = value;
SetFieldValue(nameof(UserName), value).Wait();
SelectedItem.Username.Value = value;
SetFieldValue(nameof(UserName), value, true).Wait();
RaisePropertyChanged(nameof(UserName));
}
}
public string Password
{
get { return SelectedItem.Password; }
get { return SelectedItem.Password.Value; }
set
{
SelectedItem.Password = value;
SetFieldValue(nameof(Password), value).Wait();
SelectedItem.Password.Value = value;
SetFieldValue(nameof(Password), value, true).Wait();
RaisePropertyChanged(nameof(Password));
RaisePropertyChanged(nameof(PasswordComplexityIndicator));
}
@@ -164,22 +164,22 @@ namespace ModernKeePass.ViewModels
public string Url
{
get { return SelectedItem.Url; }
get { return SelectedItem.Url.Value; }
set
{
SelectedItem.Url = value;
SetFieldValue(nameof(Url), value).Wait();
SelectedItem.Url.Value = value;
SetFieldValue(nameof(Url), value, true).Wait();
RaisePropertyChanged(nameof(Url));
}
}
public string Notes
{
get { return SelectedItem.Notes; }
get { return SelectedItem.Notes.Value; }
set
{
SelectedItem.Notes = value;
SetFieldValue(nameof(Notes), value).Wait();
SelectedItem.Notes.Value = value;
SetFieldValue(nameof(Notes), value, true).Wait();
}
}
@@ -189,7 +189,7 @@ namespace ModernKeePass.ViewModels
set
{
SelectedItem.Icon = (Icon)Enum.Parse(typeof(Icon), value.ToString());
SetFieldValue(nameof(Icon), SelectedItem.Icon).Wait();
SetFieldValue(nameof(Icon), SelectedItem.Icon, true).Wait();
}
}
@@ -201,7 +201,7 @@ namespace ModernKeePass.ViewModels
if (!HasExpirationDate) return;
SelectedItem.ExpirationDate = value.Date;
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate, true).Wait();
}
}
@@ -213,7 +213,7 @@ namespace ModernKeePass.ViewModels
if (!HasExpirationDate) return;
SelectedItem.ExpirationDate = SelectedItem.ExpirationDate.Date.Add(value);
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate).Wait();
SetFieldValue("ExpirationDate", SelectedItem.ExpirationDate, true).Wait();
}
}
@@ -223,7 +223,7 @@ namespace ModernKeePass.ViewModels
set
{
SelectedItem.HasExpirationDate = value;
SetFieldValue(nameof(HasExpirationDate), value).Wait();
SetFieldValue(nameof(HasExpirationDate), value, true).Wait();
RaisePropertyChanged(nameof(HasExpirationDate));
}
}
@@ -234,7 +234,7 @@ namespace ModernKeePass.ViewModels
set
{
SelectedItem.BackgroundColor = value.ToColor();
SetFieldValue(nameof(BackgroundColor), SelectedItem.BackgroundColor).Wait();
SetFieldValue(nameof(BackgroundColor), SelectedItem.BackgroundColor, true).Wait();
}
}
@@ -244,7 +244,7 @@ namespace ModernKeePass.ViewModels
set
{
SelectedItem.ForegroundColor = value.ToColor();
SetFieldValue(nameof(ForegroundColor), SelectedItem.ForegroundColor).Wait();
SetFieldValue(nameof(ForegroundColor), SelectedItem.ForegroundColor, true).Wait();
}
}
@@ -269,7 +269,7 @@ namespace ModernKeePass.ViewModels
public RelayCommand GoBackCommand { get; }
public RelayCommand GoToParentCommand { get; set; }
public RelayCommand AddAdditionalField { get; set; }
public RelayCommand<FieldVm> DeleteAdditionalField { get; set; }
public RelayCommand<EntryFieldVm> DeleteAdditionalField { get; set; }
public RelayCommand<Attachment> OpenAttachmentCommand { get; set; }
public RelayCommand AddAttachmentCommand { get; set; }
public RelayCommand<Attachment> DeleteAttachmentCommand { get; set; }
@@ -308,14 +308,14 @@ namespace ModernKeePass.ViewModels
GoBackCommand = new RelayCommand(() => _navigation.GoBack());
GoToParentCommand = new RelayCommand(() => GoToGroup(_parent.Id));
AddAdditionalField = new RelayCommand(AddField, () => IsCurrentEntry);
DeleteAdditionalField = new RelayCommand<FieldVm>(async field => await DeleteField(field), field => field != null && IsCurrentEntry);
DeleteAdditionalField = new RelayCommand<EntryFieldVm>(async field => await DeleteField(field), field => field != null && IsCurrentEntry);
OpenAttachmentCommand = new RelayCommand<Attachment>(async attachment => await OpenAttachment(attachment));
AddAttachmentCommand = new RelayCommand(async () => await AddAttachment(), () => IsCurrentEntry);
DeleteAttachmentCommand = new RelayCommand<Attachment>(async attachment => await DeleteAttachment(attachment), _ => IsCurrentEntry);
MessengerInstance.Register<DatabaseSavedMessage>(this, _ => SaveCommand.RaiseCanExecuteChanged());
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue));
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value));
MessengerInstance.Register<EntryFieldValueChangedMessage>(this, async message => await SetFieldValue(message.FieldName, message.FieldValue, message.IsProtected));
MessengerInstance.Register<EntryFieldNameChangedMessage>(this, async message => await UpdateFieldName(message.OldName, message.NewName, message.Value, message.IsProtected));
}
public async Task Initialize(string entryId)
@@ -348,6 +348,7 @@ namespace ModernKeePass.ViewModels
});
RaisePropertyChanged(nameof(IsRevealPasswordEnabled));
}
public async Task AddHistory()
{
if (_isDirty) await _mediator.Send(new AddHistoryCommand { Entry = History[0] });
@@ -365,26 +366,26 @@ namespace ModernKeePass.ViewModels
GoToGroup(destination);
}
private async Task SetFieldValue(string fieldName, object value)
private async Task SetFieldValue(string fieldName, object value, bool isProtected)
{
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value });
await _mediator.Send(new UpsertFieldCommand { EntryId = Id, FieldName = fieldName, FieldValue = value, IsProtected = isProtected});
SaveCommand.RaiseCanExecuteChanged();
_isDirty = true;
}
private async Task UpdateFieldName(string oldName, string newName, string value)
private async Task UpdateFieldName(string oldName, string newName, string value, bool isProtected)
{
if (!string.IsNullOrEmpty(oldName)) await _mediator.Send(new DeleteFieldCommand { EntryId = Id, FieldName = oldName });
await SetFieldValue(newName, value);
await SetFieldValue(newName, value, isProtected);
}
private void AddField()
{
AdditionalFields.Add(new FieldVm(string.Empty, string.Empty));
AdditionalFields.Add(new EntryFieldVm(string.Empty, string.Empty, false));
AdditionalFieldSelectedIndex = AdditionalFields.Count - 1;
}
private async Task DeleteField(FieldVm field)
private async Task DeleteField(EntryFieldVm field)
{
AdditionalFields.Remove(field);
if (!string.IsNullOrEmpty(field.Name))

View File

@@ -43,7 +43,7 @@ namespace ModernKeePass.ViewModels
public bool IsNotRoot => Database.RootGroupId != _group.Id;
public IOrderedEnumerable<IGrouping<char, EntryVm>> EntriesZoomedOut => from e in Entries
group e by e.Title.ToUpper().FirstOrDefault() into grp
group e by e.Title.Name.ToUpper().FirstOrDefault() into grp
orderby grp.Key
select grp;

View File

@@ -441,8 +441,8 @@
</ToolTipService.ToolTip>
</SymbolIcon>
<StackPanel Grid.Column="1" x:Name="ExpirationDatePanel" Orientation="Vertical" Visibility="{Binding HasExpirationDate, Converter={StaticResource BooleanToVisibilityConverter}}">
<DatePicker Margin="0,0,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" />
<TimePicker Margin="0,10,0,0" Time="{Binding ExpiryTime, Mode=TwoWay}" />
<DatePicker Margin="10,5,20,0" Date="{Binding ExpiryDate, Mode=TwoWay}" />
<TimePicker Margin="10,10,0,0" Time="{Binding ExpiryTime, Mode=TwoWay}" />
</StackPanel>
</Grid>
</StackPanel>
@@ -481,40 +481,51 @@
</HubSection>
<HubSection x:Uid="EntryHubAdditional">
<DataTemplate>
<StackPanel Orientation="Vertical">
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Add" />
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
</HyperlinkButton>
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
<local:SelectableTemplateListView
ItemsSource="{Binding AdditionalFields}"
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
<local:SelectableTemplateListView.SelectedItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<TextBox Text="{Binding Name, Mode=TwoWay}" Width="350"
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
<TextBox HorizontalAlignment="Left" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350" Margin="0,5,0,0"
Text="{Binding Value, Mode=TwoWay}"
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
<Button x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
</StackPanel>
</DataTemplate>
</local:SelectableTemplateListView.SelectedItemTemplate>
<local:SelectableTemplateListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Style="{StaticResource EntryTextBlockStyle}"/>
</StackPanel>
</DataTemplate>
</local:SelectableTemplateListView.ItemTemplate>
</local:SelectableTemplateListView>
</StackPanel>
<local:SelectableTemplateListView
ItemsSource="{Binding AdditionalFields}"
SelectedIndex="{Binding AdditionalFieldSelectedIndex, Mode=TwoWay}"
ItemContainerStyle="{StaticResource ListViewLeftIndicatorItemExpanded}">
<local:SelectableTemplateListView.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<HyperlinkButton Command="{Binding Path=DataContext.AddAdditionalField, ElementName=Page}">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="Add" />
<TextBlock x:Uid="EntryAddAdditionalField" VerticalAlignment="Center" Margin="10,0,0,0" />
</StackPanel>
</HyperlinkButton>
<Border BorderBrush="DarkGray" BorderThickness="0,0,0,1" />
</StackPanel>
</DataTemplate>
</local:SelectableTemplateListView.HeaderTemplate>
<local:SelectableTemplateListView.SelectedItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Name, Mode=TwoWay}" Width="350"
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
<TextBox Grid.Row="1" AcceptsReturn="True" Height="100" TextWrapping="Wrap" Width="350" Margin="0,5,0,0"
Text="{Binding Value, Mode=TwoWay}"
IsEnabled="{Binding Path=DataContext.IsCurrentEntry, ElementName=Page}" />
<ToggleSwitch Grid.Row="2" x:Uid="EntryEnableFieldProtection" HorizontalAlignment="Left" IsOn="{Binding IsProtected, Mode=TwoWay}" />
<Button Grid.Row="2" x:Uid="EntryDeleteAdditionalField" HorizontalAlignment="Right" Margin="0,15,0,0" Command="{Binding Path=DataContext.DeleteAdditionalField, ElementName=Page}" CommandParameter="{Binding}" />
</Grid>
</DataTemplate>
</local:SelectableTemplateListView.SelectedItemTemplate>
<local:SelectableTemplateListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<TextBlock Text="{Binding Name}" Style="{StaticResource EntryTextBlockStyle}" FontWeight="SemiBold" />
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="*****" Visibility="{Binding IsProtected, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBlockStyle}"/>
<TextBlock HorizontalAlignment="Left" MaxLines="3" FontSize="12" Margin="2,0,2,5" Text="{Binding Value}" Visibility="{Binding IsProtected, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Style="{StaticResource EntryTextBlockStyle}"/>
</StackPanel>
</DataTemplate>
</local:SelectableTemplateListView.ItemTemplate>
</local:SelectableTemplateListView>
</DataTemplate>
</HubSection>
<HubSection x:Uid="EntryHubAttachments" Foreground="{StaticResource HubSectionBrush}">

View File

@@ -221,7 +221,7 @@ namespace ModernKeePass.Views.UserControls
var results = (await Model.Search(args.QueryText)).Take(5);
foreach (var result in results)
{
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Title, result.ParentGroupName, result.Id, imageUri, string.Empty);
args.Request.SearchSuggestionCollection.AppendResultSuggestion(result.Title.Value, result.ParentGroupName, result.Id, imageUri, string.Empty);
}
}

View File

@@ -372,8 +372,8 @@
<HintPath>..\packages\HockeySDK.WINRT.4.1.6\lib\portable-win81\Microsoft.HockeyApp.Kit.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ModernKeePassLib, Version=2.44.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ModernKeePassLib.2.44.3\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
<Reference Include="ModernKeePassLib, Version=2.45.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ModernKeePassLib.2.45.1\lib\netstandard1.2\ModernKeePassLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SixLabors.Core, Version=0.1.0.0, Culture=neutral, processorArchitecture=MSIL">

View File

@@ -1,4 +1,5 @@
Support for additional fields
Support for attachments
Ability to manually reorder groups
Design changes
Design changes
Update to KeePassLib version 2.45

View File

@@ -1,4 +1,5 @@
Ajout des champs additionnels
Ajout des pi<70>ces-jointes
Possibilite de reorganiser les groupes manuellement
Quelques changements de design
Quelques changements de design
Mise a jour de la KeePassLib version 2.45

View File

@@ -14,7 +14,7 @@
<package id="Microsoft.NETCore.Platforms" version="2.1.1" targetFramework="win81" />
<package id="Microsoft.NETCore.Portable.Compatibility" version="1.0.1" targetFramework="win81" />
<package id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.1.7" targetFramework="win81" />
<package id="ModernKeePassLib" version="2.44.3" targetFramework="win81" />
<package id="ModernKeePassLib" version="2.45.1" targetFramework="win81" />
<package id="MvvmLight" version="5.4.1.1" targetFramework="win81" />
<package id="MvvmLightLibs" version="5.4.1.1" targetFramework="win81" />
<package id="NETStandard.Library" version="2.0.3" targetFramework="win81" />