diff --git a/Source/LibationAvalonia/Views/ProductsDisplay.axaml b/Source/LibationAvalonia/Views/ProductsDisplay.axaml index f93e5abb..62207098 100644 --- a/Source/LibationAvalonia/Views/ProductsDisplay.axaml +++ b/Source/LibationAvalonia/Views/ProductsDisplay.axaml @@ -142,6 +142,16 @@ + + + + + + + + + + diff --git a/Source/LibationFileManager/Configuration.PersistentSettings.cs b/Source/LibationFileManager/Configuration.PersistentSettings.cs index 846277d3..cb9e8d2f 100644 --- a/Source/LibationFileManager/Configuration.PersistentSettings.cs +++ b/Source/LibationFileManager/Configuration.PersistentSettings.cs @@ -142,8 +142,15 @@ namespace LibationFileManager [Description("Lame target VBR quality [10,100]")] public int LameVBRQuality { get => GetNonString(defaultValue: 2); set => SetNonString(value); } + private static readonly EquatableDictionary DefaultColumns = new( + new KeyValuePair[] + { + new ("SeriesOrder", false), + new ("LastDownload", false) + }); + [Description("A Dictionary of GridView data property names and bool indicating its column's visibility in ProductsGrid")] - public Dictionary GridColumnsVisibilities { get => GetNonString(defaultValue: new EquatableDictionary()).Clone(); set => SetNonString(value); } + public Dictionary GridColumnsVisibilities { get => GetNonString(defaultValue: DefaultColumns).Clone(); set => SetNonString(value); } [Description("A Dictionary of GridView data property names and int indicating its column's display index in ProductsGrid")] public Dictionary GridColumnsDisplayIndices { get => GetNonString(defaultValue: new EquatableDictionary()).Clone(); set => SetNonString(value); } diff --git a/Source/LibationUiBase/GridView/GridEntry[TStatus].cs b/Source/LibationUiBase/GridView/GridEntry[TStatus].cs index 4aa8fdde..905a9e68 100644 --- a/Source/LibationUiBase/GridView/GridEntry[TStatus].cs +++ b/Source/LibationUiBase/GridView/GridEntry[TStatus].cs @@ -40,6 +40,7 @@ namespace LibationUiBase.GridView private LastDownloadStatus _lastDownload; private object _cover; private string _series; + private SeriesOrder _seriesOrder; private string _title; private string _authors; private string _narrators; @@ -57,6 +58,7 @@ namespace LibationUiBase.GridView public LastDownloadStatus LastDownload { get => _lastDownload; protected set => RaiseAndSetIfChanged(ref _lastDownload, value); } public object Cover { get => _cover; private set => RaiseAndSetIfChanged(ref _cover, value); } public string Series { get => _series; private set => RaiseAndSetIfChanged(ref _series, value); } + public SeriesOrder SeriesOrder { get => _seriesOrder; private set => RaiseAndSetIfChanged(ref _seriesOrder, value); } public string Title { get => _title; private set => RaiseAndSetIfChanged(ref _title, value); } public string Authors { get => _authors; private set => RaiseAndSetIfChanged(ref _authors, value); } public string Narrators { get => _narrators; private set => RaiseAndSetIfChanged(ref _narrators, value); } @@ -105,6 +107,7 @@ namespace LibationUiBase.GridView Title = Book.Title; Series = Book.SeriesNames(includeIndex: true); + SeriesOrder = new SeriesOrder(Book.SeriesLink); Length = GetBookLengthString(); //Ratings are changed using Update(), which is a problem for Avalonia data bindings because //the reference doesn't change. Clone the rating so that it updates within Avalonia properly. @@ -200,6 +203,7 @@ namespace LibationUiBase.GridView { nameof(Remove), () => Remove.HasValue ? Remove.Value ? RemoveStatus.Removed : RemoveStatus.NotRemoved : RemoveStatus.SomeRemoved }, { nameof(Title), () => Book.TitleSortable() }, { nameof(Series), () => Book.SeriesSortable() }, + { nameof(SeriesOrder), () => SeriesOrder }, { nameof(Length), () => GetLengthInMinutes() }, { nameof(MyRating), () => Book.UserDefinedItem.Rating }, { nameof(PurchaseDate), () => GetPurchaseDate() }, @@ -233,6 +237,7 @@ namespace LibationUiBase.GridView { typeof(Rating), new ObjectComparer() }, { typeof(DateTime), new ObjectComparer() }, { typeof(EntryStatus), new ObjectComparer() }, + { typeof(SeriesOrder), new ObjectComparer() }, { typeof(LastDownloadStatus), new ObjectComparer() }, }; diff --git a/Source/LibationUiBase/GridView/IGridEntry.cs b/Source/LibationUiBase/GridView/IGridEntry.cs index a90c3436..f9aaacb5 100644 --- a/Source/LibationUiBase/GridView/IGridEntry.cs +++ b/Source/LibationUiBase/GridView/IGridEntry.cs @@ -20,6 +20,7 @@ namespace LibationUiBase.GridView string Length { get; } LastDownloadStatus LastDownload { get; } string Series { get; } + SeriesOrder SeriesOrder { get; } string Title { get; } string Authors { get; } string Narrators { get; } diff --git a/Source/LibationUiBase/GridView/SeriesOrder.cs b/Source/LibationUiBase/GridView/SeriesOrder.cs new file mode 100644 index 00000000..944df92e --- /dev/null +++ b/Source/LibationUiBase/GridView/SeriesOrder.cs @@ -0,0 +1,41 @@ +using DataLayer; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace LibationUiBase.GridView +{ + public class SeriesOrder : IComparable + { + private float[] Orders { get; } + public string OrderString { get; } + + public SeriesOrder(IEnumerable seriesBooks) + { + var orderstrings = seriesBooks + .Where(s => s.Index > 0) + .Select(s => s.Order == "-1" ? "-" : $"#{s.Order}") + .ToList(); + OrderString = string.Join(", ", orderstrings); + + Orders = seriesBooks.Where(s => s.Index > 0).Select(s => s.Index).ToArray(); + } + public override string ToString() => OrderString; + + public int CompareTo(object obj) + { + if (obj is not SeriesOrder other) return 1; + + int count = int.Min(Orders.Length, other.Orders.Length); + for (int i = 0; i < count; i++) + { + var compare = Orders[i].CompareTo(other.Orders[i]); + if (compare != 0) return compare; + } + + if (Orders.Length < other.Orders.Length) return 1; + if (Orders.Length > other.Orders.Length) return -1; + return 0; + } + } +} \ No newline at end of file diff --git a/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs index 3bc46638..433eee3c 100644 --- a/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs @@ -41,6 +41,7 @@ namespace LibationWinForms.GridView this.narratorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.lengthGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.seriesGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.seriesOrderGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.descriptionGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.categoryGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.productRatingGVColumn = new LibationWinForms.GridView.MyRatingGridViewColumn(); @@ -72,7 +73,8 @@ namespace LibationWinForms.GridView this.narratorsGVColumn, this.lengthGVColumn, this.seriesGVColumn, - this.descriptionGVColumn, + this.seriesOrderGVColumn, + this.descriptionGVColumn, this.categoryGVColumn, this.productRatingGVColumn, this.purchaseDateGVColumn, @@ -173,6 +175,15 @@ namespace LibationWinForms.GridView this.seriesGVColumn.Name = "seriesGVColumn"; this.seriesGVColumn.ReadOnly = true; // + // seriesOrderGVColumn + // + this.seriesOrderGVColumn.DataPropertyName = "SeriesOrder"; + this.seriesOrderGVColumn.HeaderText = "Series\r\nOrder"; + this.seriesOrderGVColumn.Name = "seriesOrderGVColumn"; + this.seriesOrderGVColumn.Width = 60; + this.seriesOrderGVColumn.ReadOnly = true; + this.seriesOrderGVColumn.DefaultCellStyle.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter; + // // descriptionGVColumn // this.descriptionGVColumn.DataPropertyName = "Description"; @@ -275,6 +286,7 @@ namespace LibationWinForms.GridView private System.Windows.Forms.DataGridViewTextBoxColumn narratorsGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn lengthGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn seriesGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn seriesOrderGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn descriptionGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn categoryGVColumn; private MyRatingGridViewColumn productRatingGVColumn;