diff --git a/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml
new file mode 100644
index 00000000..cc93bafa
--- /dev/null
+++ b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs
new file mode 100644
index 00000000..ded5f227
--- /dev/null
+++ b/Source/LibationWinForms/AvaloniaUI/Controls/DirectorySelectControl.axaml.cs
@@ -0,0 +1,146 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Dinah.Core;
+using LibationFileManager;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using ReactiveUI;
+using Avalonia.Controls.Primitives;
+using System.Collections;
+using Avalonia.Data.Converters;
+using System;
+using System.Globalization;
+using Avalonia.Data;
+
+namespace LibationWinForms.AvaloniaUI.Controls
+{
+ public class TextCaseConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ if (value is Configuration.KnownDirectories dir)
+ {
+
+ }
+ return new BindingNotification(new InvalidCastException(), BindingErrorType.Error);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ public partial class DirectorySelectControl : TemplatedControl
+ {
+ private static readonly List defaultList = new List()
+ {
+ Configuration.KnownDirectories.WinTemp,
+ Configuration.KnownDirectories.UserProfile,
+ Configuration.KnownDirectories.AppDir,
+ Configuration.KnownDirectories.MyDocs,
+ Configuration.KnownDirectories.LibationFiles
+ };
+ public static readonly StyledProperty SelectedirectoryProperty =
+ AvaloniaProperty.Register(nameof(Selectedirectory), defaultList[0]);
+
+ public static readonly StyledProperty> KnownDirectoriesProperty =
+ AvaloniaProperty.Register>(nameof(KnownDirectories), defaultList);
+
+ public static readonly StyledProperty SubdirectoryProperty =
+ AvaloniaProperty.Register(nameof(Subdirectory), "subdir");
+
+ DirectorySelectViewModel DirectorySelect { get; } = new();
+ public DirectorySelectControl()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnInitialized()
+ {
+ DirectorySelect.Directories.Clear();
+
+ int insertIndex = 0;
+ foreach (var kd in KnownDirectories.Distinct())
+ DirectorySelect.Directories.Insert(insertIndex++, new(this, kd));
+
+ DataContext = DirectorySelect;
+ base.OnInitialized();
+ }
+
+ public List KnownDirectories
+ {
+ get { return GetValue(KnownDirectoriesProperty); }
+ set
+ {
+ SetValue(KnownDirectoriesProperty, value);
+ //SetDirectoryItems(KnownDirectories);
+ }
+ }
+
+
+ public Configuration.KnownDirectories? Selectedirectory
+ {
+ get { return GetValue(SelectedirectoryProperty); }
+ set
+ {
+ SetValue(SelectedirectoryProperty, value);
+
+ if (value is null or Configuration.KnownDirectories.None)
+ return;
+
+ // set default
+ var item = DirectorySelect.Directories.SingleOrDefault(item => item.Value == value.Value);
+ if (item is null)
+ return;
+
+ DirectorySelect.SelectedDirectory = item;
+ }
+ }
+
+
+ public string? Subdirectory
+ {
+ get { return GetValue(SubdirectoryProperty); }
+ set
+ {
+ SetValue(SubdirectoryProperty, value);
+ }
+ }
+
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+ }
+
+ public class DirectorySelectViewModel : ViewModels.ViewModelBase
+ {
+ public class DirectoryComboBoxItem
+ {
+ private readonly DirectorySelectControl _parentControl;
+ public string Description { get; }
+ public Configuration.KnownDirectories Value { get; }
+
+ public string FullPath => AddSubDirectoryToPath(Configuration.GetKnownDirectoryPath(Value));
+
+ /// Displaying relative paths is confusing. UI should display absolute equivalent
+ public string UiDisplayPath => Value == Configuration.KnownDirectories.AppDir ? AddSubDirectoryToPath(Configuration.AppDir_Absolute) : FullPath;
+
+ public DirectoryComboBoxItem(DirectorySelectControl parentControl, Configuration.KnownDirectories knownDirectory)
+ {
+ _parentControl = parentControl;
+ Value = knownDirectory;
+ Description = Value.GetDescription();
+ }
+
+ internal string AddSubDirectoryToPath(string path) => string.IsNullOrWhiteSpace(_parentControl.Subdirectory) ? path : System.IO.Path.Combine(path, _parentControl.Subdirectory);
+
+ public override string ToString() => Description;
+ }
+ public ObservableCollection Directories { get; } = new(new());
+ private DirectoryComboBoxItem _selectedDirectory;
+ public DirectoryComboBoxItem SelectedDirectory { get => _selectedDirectory; set => this.RaiseAndSetIfChanged(ref _selectedDirectory, value); }
+ }
+}
diff --git a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
index d27209d5..f8b9fafd 100644
--- a/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
+++ b/Source/LibationWinForms/AvaloniaUI/ViewModels/ProductsDisplayViewModel.cs
@@ -86,10 +86,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
GridEntries = new GridEntryCollection(CreateGridEntries(dbBooks));
GridEntries.CollapseAll();
- int bookEntryCount = GridEntries.BookEntries().Count();
-
InitialLoaded?.Invoke(this, EventArgs.Empty);
- VisibleCountChanged?.Invoke(this, bookEntryCount);
+ VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count());
RegisterCollectionChanged();
}
@@ -112,7 +110,12 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
var existingSeriesEntries = GridEntries.AllItems().SeriesEntries().ToList();
- await Dispatcher.UIThread.InvokeAsync(() => GridEntries.ReplaceList(newEntries));
+ await Dispatcher.UIThread.InvokeAsync(() =>
+ {
+ GridEntries.ReplaceList(newEntries);
+ GridEntries.Filter = existingFilter;
+ ReSort();
+ });
//We're replacing the list, so preserve usere's existing collapse/expand
//state. When resetting a list, default state is open.
@@ -122,11 +125,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
if (sEntry is SeriesEntry se && !series.Liberate.Expanded)
await Dispatcher.UIThread.InvokeAsync(() => GridEntries.CollapseItem(se));
}
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- GridEntries.Filter = existingFilter;
- ReSort();
- });
+
+ await Dispatcher.UIThread.InvokeAsync(() => VisibleCountChanged?.Invoke(this, GridEntries.BookEntries().Count()));
}
catch (Exception ex)
{
diff --git a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml
index 70e8ff87..0942c6f6 100644
--- a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml
+++ b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/AccountsDialog.axaml
@@ -36,6 +36,7 @@
Width="60"
Height="30"
Content="X"
+ IsEnabled="{Binding !IsDefault}"
Click="DeleteButton_Clicked" />
@@ -50,6 +51,7 @@
Width="60"
Height="30"
Content="Export"
+ IsEnabled="{Binding !IsDefault}"
ToolTip.Tip="Export account authorization to audible-cli"
Click="ExportButton_Clicked" />
@@ -71,13 +73,13 @@
-
@@ -101,25 +103,11 @@
Margin="10"
ColumnDefinitions="*,Auto" >
-
-
-
-
-
-
-
+ Height="30"
+ Content="Import from audible-cli"
+ Click="ImportButton_Clicked" />