This commit is contained in:
2018-09-09 20:02:02 +02:00
20 changed files with 154 additions and 63 deletions

View File

@@ -99,7 +99,7 @@ namespace ModernKeePass
#if DEBUG #if DEBUG
if (System.Diagnostics.Debugger.IsAttached) if (System.Diagnostics.Debugger.IsAttached)
{ {
DebugSettings.EnableFrameRateCounter = true; //DebugSettings.EnableFrameRateCounter = true;
} }
#endif #endif

View File

@@ -75,6 +75,7 @@ namespace ModernKeePass.Converters
public object ConvertBack(object value, Type targetType, object parameter, string language) public object ConvertBack(object value, Type targetType, object parameter, string language)
{ {
var symbol = (Symbol) value; var symbol = (Symbol) value;
var defaultIcon = (int?) parameter ?? -1;
switch (symbol) switch (symbol)
{ {
case Symbol.Delete: return (int)PwIcon.TrashBin; case Symbol.Delete: return (int)PwIcon.TrashBin;
@@ -123,7 +124,7 @@ namespace ModernKeePass.Converters
case Symbol.ZeroBars: return (int) PwIcon.Energy; case Symbol.ZeroBars: return (int) PwIcon.Energy;
case Symbol.FourBars: return (int) PwIcon.EnergyCareful; case Symbol.FourBars: return (int) PwIcon.EnergyCareful;
case Symbol.Scan: return (int) PwIcon.Scanner; case Symbol.Scan: return (int) PwIcon.Scanner;
default: return (int) PwIcon.Key; default: return defaultIcon;
} }
} }
} }

View File

@@ -0,0 +1,9 @@
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IFormat
{
IPwEntity Import(IStorageFile source);
}
}

View File

@@ -0,0 +1,9 @@
using Windows.Storage;
namespace ModernKeePass.Interfaces
{
public interface IImportService<in T> where T: IFormat
{
void Import(T format, IStorageFile source, IDatabaseService database);
}
}

View File

@@ -117,10 +117,13 @@
</Compile> </Compile>
<Compile Include="Converters\IntToSymbolConverter.cs" /> <Compile Include="Converters\IntToSymbolConverter.cs" />
<Compile Include="Exceptions\NavigationException.cs" /> <Compile Include="Exceptions\NavigationException.cs" />
<Compile Include="Interfaces\IFormat.cs" />
<Compile Include="Interfaces\IImportService.cs" />
<Compile Include="Interfaces\IProxyInvocationHandler.cs" /> <Compile Include="Interfaces\IProxyInvocationHandler.cs" />
<Compile Include="Interfaces\IRecentService.cs" /> <Compile Include="Interfaces\IRecentService.cs" />
<Compile Include="Interfaces\IRecentItem.cs" /> <Compile Include="Interfaces\IRecentItem.cs" />
<Compile Include="Interfaces\IResourceService.cs" /> <Compile Include="Interfaces\IResourceService.cs" />
<Compile Include="Services\ImportService.cs" />
<Compile Include="Services\SingletonServiceBase.cs" /> <Compile Include="Services\SingletonServiceBase.cs" />
<Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" /> <Compile Include="TemplateSelectors\SelectableDataTemplateSelector.cs" />
<Compile Include="ViewModels\Items\SettingsSaveVm.cs" /> <Compile Include="ViewModels\Items\SettingsSaveVm.cs" />

View File

@@ -5,11 +5,9 @@ using ModernKeePass.Exceptions;
using ModernKeePass.Interfaces; using ModernKeePass.Interfaces;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
using ModernKeePassLib; using ModernKeePassLib;
using ModernKeePassLib.Collections;
using ModernKeePassLib.Cryptography.KeyDerivation; using ModernKeePassLib.Cryptography.KeyDerivation;
using ModernKeePassLib.Interfaces; using ModernKeePassLib.Interfaces;
using ModernKeePassLib.Keys; using ModernKeePassLib.Keys;
using ModernKeePassLib.Security;
using ModernKeePassLib.Serialization; using ModernKeePassLib.Serialization;
namespace ModernKeePass.Services namespace ModernKeePass.Services
@@ -101,8 +99,6 @@ namespace ModernKeePass.Services
{ {
_pwDatabase.New(ioConnection, key); _pwDatabase.New(ioConnection, key);
//Get settings default values
if (_settings.GetSetting<bool>("Sample")) CreateSampleData();
var fileFormat = _settings.GetSetting<string>("DefaultFileFormat"); var fileFormat = _settings.GetSetting<string>("DefaultFileFormat");
switch (fileFormat) switch (fileFormat)
{ {
@@ -190,37 +186,5 @@ namespace ModernKeePass.Services
_compositeKey = newCompositeKey; _compositeKey = newCompositeKey;
_pwDatabase.MasterKey = newCompositeKey; _pwDatabase.MasterKey = newCompositeKey;
} }
private void CreateSampleData()
{
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Banking", PwIcon.Count), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Email", PwIcon.EMail), true);
_pwDatabase.RootGroup.AddGroup(new PwGroup(true, true, "Internet", PwIcon.World), true);
var pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Username"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HomepageUrl));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"Password"));
pe.Strings.Set(PwDefs.NotesField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectNotes,
"You may safely delete this sample"));
_pwDatabase.RootGroup.AddEntry(pe, true);
pe = new PwEntry(true, true);
pe.Strings.Set(PwDefs.TitleField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectTitle,
"Sample Entry #2"));
pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUserName,
"Michael321"));
pe.Strings.Set(PwDefs.UrlField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectUrl,
PwDefs.HelpUrl + "kb/testform.html"));
pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(_pwDatabase.MemoryProtection.ProtectPassword,
"12345"));
pe.AutoType.Add(new AutoTypeAssociation("*Test Form - KeePass*", string.Empty));
_pwDatabase.RootGroup.AddEntry(pe, true);
}
} }
} }

View File

@@ -0,0 +1,24 @@
using ModernKeePass.Interfaces;
using Windows.Storage;
using ModernKeePass.ViewModels;
namespace ModernKeePass.Services
{
public class ImportService : IImportService<IFormat>
{
public void Import(IFormat format, IStorageFile source, IDatabaseService databaseService)
{
var entities = (GroupVm)format.Import(source);
foreach (var entry in entities.Entries)
{
databaseService.RootGroup.Entries.Add(entry);
}
foreach (var subGroup in entities.Groups)
{
databaseService.RootGroup.Groups.Add(subGroup);
}
}
}
}

View File

@@ -483,4 +483,7 @@
<data name="RestoreGroupCommand.Message" xml:space="preserve"> <data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Group restored to its original position</value> <value>Group restored to its original position</value>
</data> </data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Import existing data</value>
</data>
</root> </root>

View File

@@ -483,4 +483,7 @@
<data name="RestoreGroupCommand.Message" xml:space="preserve"> <data name="RestoreGroupCommand.Message" xml:space="preserve">
<value>Groupe replacée à son emplacement d'origine</value> <value>Groupe replacée à son emplacement d'origine</value>
</data> </data>
<data name="NewImportCheckbox.Content" xml:space="preserve">
<value>Importer des données existantes</value>
</data>
</root> </root>

View File

@@ -1,7 +1,49 @@
namespace ModernKeePass.ViewModels using Windows.Storage;
using Windows.UI.Xaml.Controls;
using ModernKeePass.Interfaces;
using ModernKeePassLib;
namespace ModernKeePass.ViewModels
{ {
public class NewVm : OpenVm public class NewVm : OpenVm
{ {
public string Password { get; set; } public string Password { get; set; }
public bool IsImportChecked { get; set; }
public IStorageFile ImportFile { get; set; }
public IFormat ImportFormat { get; set; }
public void PopulateInitialData(IDatabaseService database, ISettingsService settings, IImportService<IFormat> importService)
{
if (settings.GetSetting<bool>("Sample") && !IsImportChecked) CreateSampleData(database);
else if (IsImportChecked && ImportFile != null) importService.Import(ImportFormat, ImportFile, database);
}
private void CreateSampleData(IDatabaseService database)
{
var bankingGroup = database.RootGroup.AddNewGroup("Banking");
bankingGroup.IconId = (int) Symbol.Calculator;
var emailGroup = database.RootGroup.AddNewGroup("Email");
emailGroup.IconId = (int) Symbol.Mail;
var internetGroup = database.RootGroup.AddNewGroup("Internet");
internetGroup.IconId = (int) Symbol.World;
var sample1 = database.RootGroup.AddNewEntry();
sample1.Name = "Sample Entry";
sample1.UserName = "Username";
sample1.Url = PwDefs.HomepageUrl;
sample1.Password = "Password";
sample1.Notes = "You may safely delete this sample";
var sample2 = database.RootGroup.AddNewEntry();
sample2.Name = "Sample Entry #2";
sample2.UserName = "Michael321";
sample2.Url = PwDefs.HelpUrl + "kb/testform.html";
sample2.Password = "12345";
}
} }
} }

View File

@@ -19,7 +19,6 @@
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" /> <converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter" /> <converters:ProgressBarLegalValuesConverter x:Key="ProgressBarLegalValuesConverter" />
<converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushComplexityConverter" /> <converters:DoubleToSolidColorBrushConverter x:Key="DoubleToForegroungBrushComplexityConverter" />
<converters:NullToBooleanConverter x:Key="NullToBooleanConverter" />
<converters:ColorToBrushConverter x:Key="ColorToBrushConverter" /> <converters:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<converters:IntToSymbolConverter x:Key="IntToSymbolConverter" /> <converters:IntToSymbolConverter x:Key="IntToSymbolConverter" />
<Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle"> <Style TargetType="PasswordBox" x:Name="PasswordBoxWithButtonStyle">
@@ -499,7 +498,7 @@
<RowDefinition Height="20" /> <RowDefinition Height="20" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}"> <Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, Mode=TwoWay}" /> <userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=0, Mode=TwoWay}" />
</Viewbox> </Viewbox>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}"> <Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" /> <SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" />

View File

@@ -105,7 +105,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="{Binding BackgroundColor, ConverterParameter={StaticResource MainColor}, Converter={StaticResource ColorToBrushConverter}}"> <Border Grid.Column="0" Background="{Binding BackgroundColor, ConverterParameter={StaticResource MainColor}, Converter={StaticResource ColorToBrushConverter}}">
<Viewbox MaxHeight="50" Width="100"> <Viewbox MaxHeight="50" Width="100">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Foreground="{StaticResource TextColor}" /> <SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=0}" Foreground="{StaticResource TextColor}" />
</Viewbox> </Viewbox>
</Border> </Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,10,0,0" > <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,10,0,0" >
@@ -207,7 +207,7 @@
<RowDefinition Height="20" /> <RowDefinition Height="20" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}"> <Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource BooleanToVisibilityConverter}}">
<userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, Mode=TwoWay}" /> <userControls:SymbolPickerUserControl Width="80" Height="40" SelectedSymbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=48, Mode=TwoWay}" />
</Viewbox> </Viewbox>
<Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}"> <Viewbox MaxHeight="30" Width="50" Grid.Column="0" Grid.Row="0" Visibility="{Binding IsEditMode, Converter={StaticResource InverseBooleanToVisibilityConverter}}">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" /> <SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Width="80" Height="40" />

View File

@@ -23,7 +23,9 @@
<HyperlinkButton Grid.Column="0" Grid.Row="1" Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" /> <HyperlinkButton Grid.Column="0" Grid.Row="1" Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" />
<StackPanel Grid.Column="1" Grid.Row="1" > <StackPanel Grid.Column="1" Grid.Row="1" >
<TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" /> <TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />
<ComboBox Style="{StaticResource MainColorComboBox}" /> <ComboBox Style="{StaticResource MainColorComboBox}">
<ComboBoxItem>CSV</ComboBoxItem>
</ComboBox>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" Grid.Row="1" > <StackPanel Grid.Column="2" Grid.Row="1" >
<TextBlock Text="Import into..." Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" /> <TextBlock Text="Import into..." Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />

View File

@@ -23,13 +23,19 @@
<Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}"> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsFileSelected, Converter={StaticResource BooleanToVisibilityConverter}}">
<StackPanel Margin="25,0,25,0"> <StackPanel Margin="25,0,25,0">
<TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Name}" />
<userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}"> <userControls:CompositeKeyUserControl x:Uid="CompositeKeyNewButton" CreateNew="True" DatabaseFile="{Binding DatabaseFile}" ValidationChecked="CompositeKeyUserControl_OnValidationChecked" />
<interactivity:Interaction.Behaviors> </StackPanel>
<core:EventTriggerBehavior EventName="ValidationChecked"> </Border>
<core:NavigateToPageAction TargetPage="ModernKeePass.Views.GroupDetailPage" /> <CheckBox x:Name="CheckBox" x:Uid="NewImportCheckbox" IsChecked="{Binding IsImportChecked}" />
</core:EventTriggerBehavior> <Border HorizontalAlignment="Left" BorderThickness="1" BorderBrush="AliceBlue" Width="550" Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=CheckBox}">
</interactivity:Interaction.Behaviors> <StackPanel Margin="25,0,25,0">
</userControls:CompositeKeyUserControl> <HyperlinkButton Content="Select file..." Style="{StaticResource MainColorHyperlinkButton}" Click="ImportFileButton_OnClick" />
<StackPanel>
<TextBlock Text="Format" Style="{StaticResource BodyTextBlockStyle}" Margin="0,0,0,10" />
<ComboBox Style="{StaticResource MainColorComboBox}" SelectedItem="{Binding ImportFormat}">
<ComboBoxItem>CSV</ComboBoxItem>
</ComboBox>
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</StackPanel> </StackPanel>

View File

@@ -2,6 +2,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using Windows.Storage.Pickers; using Windows.Storage.Pickers;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using ModernKeePass.Events;
using ModernKeePass.Services;
using ModernKeePass.ViewModels; using ModernKeePass.ViewModels;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
@@ -33,5 +35,25 @@ namespace ModernKeePass.Views
if (file == null) return; if (file == null) return;
Model.OpenFile(file); Model.OpenFile(file);
} }
private async void ImportFileButton_OnClick(object sender, RoutedEventArgs e)
{
var picker =
new FileOpenPicker
{
ViewMode = PickerViewMode.List,
SuggestedStartLocation = PickerLocationId.DocumentsLibrary
};
picker.FileTypeFilter.Add(".csv");
// Application now has read/write access to the picked file
Model.ImportFile = await picker.PickSingleFileAsync();
}
private void CompositeKeyUserControl_OnValidationChecked(object sender, PasswordEventArgs e)
{
Model.PopulateInitialData(DatabaseService.Instance, new SettingsService());
Frame.Navigate(typeof(GroupDetailPage));
}
} }
} }

View File

@@ -26,7 +26,7 @@
<x:Double x:Key="HamburgerMenuSize">300</x:Double> <x:Double x:Key="HamburgerMenuSize">300</x:Double>
<DataTemplate x:Name="IsSpecial"> <DataTemplate x:Name="IsSpecial">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="7,15,0,15"> <SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=48}" Margin="7,15,0,15">
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" /> <ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>
@@ -36,7 +36,7 @@
</DataTemplate> </DataTemplate>
<DataTemplate x:Name="IsNormal"> <DataTemplate x:Name="IsNormal">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}}" Margin="7,15,0,15"> <SymbolIcon Symbol="{Binding IconId, Converter={StaticResource IntToSymbolConverter}, ConverterParameter=48}" Margin="7,15,0,15">
<ToolTipService.ToolTip> <ToolTipService.ToolTip>
<ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" /> <ToolTip Content="{Binding Path={Binding DisplayMemberPath, ElementName=UserControl}}" />
</ToolTipService.ToolTip> </ToolTipService.ToolTip>

View File

@@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls;
using ModernKeePass.Converters;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236 // The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
@@ -9,7 +11,7 @@ namespace ModernKeePass.Views.UserControls
{ {
public sealed partial class SymbolPickerUserControl public sealed partial class SymbolPickerUserControl
{ {
public Symbol[] Symbols { get; } public IEnumerable<Symbol> Symbols { get; }
public Symbol SelectedSymbol public Symbol SelectedSymbol
{ {
@@ -26,8 +28,8 @@ namespace ModernKeePass.Views.UserControls
public SymbolPickerUserControl() public SymbolPickerUserControl()
{ {
InitializeComponent(); InitializeComponent();
var converter = new IntToSymbolConverter();
Symbols = (Symbol[])Enum.GetValues(typeof(Symbol)); Symbols = Enum.GetValues(typeof(Symbol)).Cast<Symbol>().Where(s => (int)converter.ConvertBack(s, null, null, string.Empty) != -1);
} }
private void ComboBox_OnLoaded(object sender, RoutedEventArgs e) private void ComboBox_OnLoaded(object sender, RoutedEventArgs e)

View File

@@ -2,3 +2,4 @@ Improved search box
Changing entry icon creates a new history entry Changing entry icon creates a new history entry
Corrected startup crash on some versions of Windows Corrected startup crash on some versions of Windows
Entry delete button now shows up correctly Entry delete button now shows up correctly
List of icons now only displays valid values

View File

@@ -2,3 +2,4 @@ Amelioration de la recherche
Changer l'icone d'une entree cree un historique Changer l'icone d'une entree cree un historique
Correction de crash lors du lancement avec certaines versions de Windows Correction de crash lors du lancement avec certaines versions de Windows
Le bouton de suppression d'une entree apparait bien desormais Le bouton de suppression d'une entree apparait bien desormais
La liste des icones n'affiche desormais que des valeurs valables