Address comments
This commit is contained in:
parent
43d6ea82cd
commit
e26deb9092
@ -27,6 +27,7 @@ namespace LibationWinForms.GridView
|
||||
}
|
||||
public new bool InvokeRequired => base.InvokeRequired;
|
||||
public abstract DateTime DateAdded { get; }
|
||||
public abstract float SeriesIndex { get; }
|
||||
public abstract string ProductRating { get; protected set; }
|
||||
public abstract string PurchaseDate { get; protected set; }
|
||||
public abstract string MyRating { get; protected set; }
|
||||
@ -40,10 +41,21 @@ namespace LibationWinForms.GridView
|
||||
public abstract string Description { get; protected set; }
|
||||
public abstract string DisplayTags { get; }
|
||||
public abstract LiberateButtonStatus Liberate { get; }
|
||||
public abstract object GetMemberValue(string memberName);
|
||||
#endregion
|
||||
|
||||
#region Sorting
|
||||
|
||||
public GridEntry() => _memberValues = CreateMemberValueDictionary();
|
||||
private Dictionary<string, Func<object>> _memberValues { get; set; }
|
||||
protected abstract Dictionary<string, Func<object>> CreateMemberValueDictionary();
|
||||
|
||||
// These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
|
||||
// Used by GridEntryBindingList for all sorting
|
||||
public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
|
||||
public IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
|
||||
|
||||
#endregion
|
||||
|
||||
protected void LoadCover()
|
||||
{
|
||||
// Get cover art. If it's default, subscribe to PictureCached
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using ApplicationServices;
|
||||
using Dinah.Core.DataBinding;
|
||||
using LibationSearchEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@ -21,15 +22,13 @@ namespace LibationWinForms.GridView
|
||||
*/
|
||||
internal class GridEntryBindingList : BindingList<GridEntry>, IBindingListView
|
||||
{
|
||||
private bool isSorted;
|
||||
private ListSortDirection listSortDirection;
|
||||
private PropertyDescriptor propertyDescriptor;
|
||||
|
||||
public GridEntryBindingList() : base(new List<GridEntry>()) { }
|
||||
public GridEntryBindingList(IEnumerable<GridEntry> enumeration) : base(new List<GridEntry>(enumeration)) { }
|
||||
|
||||
/// <returns>All items in the list, including those filtered out.</returns>
|
||||
public List<GridEntry> AllItems() => Items.Concat(FilterRemoved).ToList();
|
||||
public bool SupportsFiltering => true;
|
||||
public string Filter { get => FilterString; set => ApplyFilter(value); }
|
||||
|
||||
protected MemberComparer<GridEntry> Comparer { get; } = new();
|
||||
protected override bool SupportsSortingCore => true;
|
||||
@ -37,15 +36,14 @@ namespace LibationWinForms.GridView
|
||||
protected override bool IsSortedCore => isSorted;
|
||||
protected override PropertyDescriptor SortPropertyCore => propertyDescriptor;
|
||||
protected override ListSortDirection SortDirectionCore => listSortDirection;
|
||||
public bool SupportsFiltering => true;
|
||||
public string Filter { get => FilterString; set => ApplyFilter(value); }
|
||||
|
||||
/// <summary>
|
||||
/// Items that were removed from the base list due to filtering
|
||||
/// </summary>
|
||||
/// <summary> Items that were removed from the base list due to filtering </summary>
|
||||
private readonly List<GridEntry> FilterRemoved = new();
|
||||
private string FilterString;
|
||||
private LibationSearchEngine.SearchResultSet SearchResults;
|
||||
private SearchResultSet SearchResults;
|
||||
private bool isSorted;
|
||||
private ListSortDirection listSortDirection;
|
||||
private PropertyDescriptor propertyDescriptor;
|
||||
|
||||
|
||||
#region Unused - Advanced Filtering
|
||||
@ -118,11 +116,9 @@ namespace LibationWinForms.GridView
|
||||
if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
|
||||
{
|
||||
FilterRemoved.Remove(episode);
|
||||
Items.Insert(++sindex, episode);
|
||||
InsertItem(++sindex, episode);
|
||||
}
|
||||
}
|
||||
|
||||
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
|
||||
sEntry.Liberate.Expanded = true;
|
||||
}
|
||||
|
||||
@ -137,7 +133,7 @@ namespace LibationWinForms.GridView
|
||||
if (item is SeriesEntry || (item is LibraryBookEntry lbe && (lbe.Parent is null || lbe.Parent.Liberate.Expanded)))
|
||||
{
|
||||
FilterRemoved.Remove(item);
|
||||
base.InsertItem(visibleCount++, item);
|
||||
InsertItem(visibleCount++, item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,35 +171,51 @@ namespace LibationWinForms.GridView
|
||||
{
|
||||
var itemsList = (List<GridEntry>)Items;
|
||||
|
||||
var sortedItems = Items.OrderBy(ge => ge, Comparer).ToList();
|
||||
var children = itemsList.LibraryBooks().Where(i => i.Parent is not null).ToList();
|
||||
|
||||
var children = sortedItems.LibraryBooks().Where(i => i.Parent is not null).ToList();
|
||||
var sortedItems = itemsList.Except(children).OrderBy(ge => ge, Comparer).ToList();
|
||||
|
||||
itemsList.Clear();
|
||||
|
||||
//Only add parentless items at this stage. After these items are added in the
|
||||
//correct sorting order, go back and add the children beneath their parents.
|
||||
itemsList.AddRange(sortedItems.Except(children));
|
||||
itemsList.AddRange(sortedItems);
|
||||
|
||||
foreach (var parent in children.Select(c => c.Parent).Distinct())
|
||||
{
|
||||
var pIndex = itemsList.IndexOf(parent);
|
||||
foreach (var c in children.Where(c => c.Parent == parent))
|
||||
|
||||
//children should always be sorted by series index.
|
||||
foreach (var c in children.Where(c => c.Parent == parent).OrderBy(c => c.SeriesIndex))
|
||||
itemsList.Insert(++pIndex, c);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnListChanged(ListChangedEventArgs e)
|
||||
{
|
||||
if (isSorted && e.ListChangedType == ListChangedType.ItemChanged && e.PropertyDescriptor == SortPropertyCore)
|
||||
if (e.ListChangedType == ListChangedType.ItemChanged)
|
||||
{
|
||||
if (Items[e.NewIndex] is LibraryBookEntry lbItem)
|
||||
{
|
||||
SearchResults = SearchEngineCommands.Search(FilterString);
|
||||
if (!SearchResults.Docs.Any(d => d.ProductId == lbItem.AudibleProductId))
|
||||
{
|
||||
FilterRemoved.Add(lbItem);
|
||||
base.Remove(lbItem);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSorted && e.PropertyDescriptor == SortPropertyCore)
|
||||
{
|
||||
var item = Items[e.NewIndex];
|
||||
Sort();
|
||||
var newIndex = Items.IndexOf(item);
|
||||
|
||||
base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
base.OnListChanged(e);
|
||||
}
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ namespace LibationWinForms.GridView
|
||||
{
|
||||
public LiberatedStatus BookStatus { get; set; }
|
||||
public LiberatedStatus? PdfStatus { get; set; }
|
||||
public bool IsSeries { get; init; }
|
||||
public bool Expanded { get; set; }
|
||||
public bool IsSeries { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the Liberate column's sorting behavior
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using DataLayer;
|
||||
using Dinah.Core.Windows.Forms;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
@ -15,12 +16,18 @@ namespace LibationWinForms.GridView
|
||||
|
||||
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
|
||||
{
|
||||
private static readonly Color SERIES_BG_COLOR = Color.LightSkyBlue;
|
||||
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
|
||||
{
|
||||
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
|
||||
|
||||
if (value is LiberateButtonStatus status)
|
||||
{
|
||||
if (rowIndex >= 0 && DataGridView.GetBoundItem<GridEntry>(rowIndex) is LibraryBookEntry lbEntry && lbEntry.Parent is not null)
|
||||
{
|
||||
DataGridView.Rows[rowIndex].DefaultCellStyle.BackColor = SERIES_BG_COLOR;
|
||||
}
|
||||
|
||||
if (status.IsSeries)
|
||||
{
|
||||
var imageName = status.Expanded ? "minus" : "plus";
|
||||
|
||||
@ -32,6 +32,7 @@ namespace LibationWinForms.GridView
|
||||
private LiberatedStatus? _pdfStatus;
|
||||
|
||||
public override DateTime DateAdded => LibraryBook.DateAdded;
|
||||
public override float SeriesIndex => Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
|
||||
public override string ProductRating { get; protected set; }
|
||||
public override string PurchaseDate { get; protected set; }
|
||||
public override string MyRating { get; protected set; }
|
||||
@ -78,7 +79,6 @@ namespace LibationWinForms.GridView
|
||||
private void setLibraryBook(LibraryBook libraryBook)
|
||||
{
|
||||
LibraryBook = libraryBook;
|
||||
_memberValues = CreateMemberValueDictionary();
|
||||
|
||||
LoadCover();
|
||||
|
||||
@ -119,16 +119,19 @@ namespace LibationWinForms.GridView
|
||||
{
|
||||
case nameof(udi.Tags):
|
||||
Book.UserDefinedItem.Tags = udi.Tags;
|
||||
SearchEngineCommands.UpdateBookTags(Book);
|
||||
NotifyPropertyChanged(nameof(DisplayTags));
|
||||
break;
|
||||
case nameof(udi.BookStatus):
|
||||
Book.UserDefinedItem.BookStatus = udi.BookStatus;
|
||||
_bookStatus = udi.BookStatus;
|
||||
SearchEngineCommands.UpdateLiberatedStatus(Book);
|
||||
NotifyPropertyChanged(nameof(Liberate));
|
||||
break;
|
||||
case nameof(udi.PdfStatus):
|
||||
Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
|
||||
_pdfStatus = udi.PdfStatus;
|
||||
SearchEngineCommands.UpdateLiberatedStatus(Book);
|
||||
NotifyPropertyChanged(nameof(Liberate));
|
||||
break;
|
||||
}
|
||||
@ -157,16 +160,9 @@ namespace LibationWinForms.GridView
|
||||
#endregion
|
||||
|
||||
#region Data Sorting
|
||||
// These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
|
||||
// Used by Dinah.Core.DataBinding.SortableBindingList<T> for all sorting
|
||||
public override object GetMemberValue(string memberName) => _memberValues[memberName]();
|
||||
|
||||
private Dictionary<string, Func<object>> _memberValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create getters for all member object values by name
|
||||
/// </summary>
|
||||
private Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
|
||||
/// <summary>Create getters for all member object values by name </summary>
|
||||
protected override Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
|
||||
{
|
||||
{ nameof(Title), () => Book.TitleSortable() },
|
||||
{ nameof(Series), () => Book.SeriesSortable() },
|
||||
|
||||
@ -10,6 +10,7 @@ namespace LibationWinForms.GridView
|
||||
{
|
||||
public List<LibraryBookEntry> Children { get; init; }
|
||||
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
|
||||
public override float SeriesIndex { get; }
|
||||
public override string ProductRating
|
||||
{
|
||||
get
|
||||
@ -47,20 +48,23 @@ namespace LibationWinForms.GridView
|
||||
public override string Description { get; protected set; } = string.Empty;
|
||||
public override string DisplayTags { get; } = string.Empty;
|
||||
|
||||
public override LiberateButtonStatus Liberate => _liberate;
|
||||
public override LiberateButtonStatus Liberate { get; }
|
||||
|
||||
protected override Book Book => SeriesBook.Book;
|
||||
|
||||
private SeriesBook SeriesBook { get; set; }
|
||||
|
||||
private LiberateButtonStatus _liberate = new LiberateButtonStatus { IsSeries = true };
|
||||
|
||||
public SeriesEntry(SeriesBook seriesBook, IEnumerable<LibraryBook> children)
|
||||
private SeriesEntry(SeriesBook seriesBook)
|
||||
{
|
||||
Children = children.Select(c => new LibraryBookEntry(c) { Parent = this }).ToList();
|
||||
Liberate = new LiberateButtonStatus { IsSeries = true };
|
||||
SeriesIndex = seriesBook.Index;
|
||||
}
|
||||
public SeriesEntry(SeriesBook seriesBook, IEnumerable<LibraryBook> children) : this(seriesBook)
|
||||
{
|
||||
Children = children.Select(c => new LibraryBookEntry(c) { Parent = this }).OrderBy(c => c.SeriesIndex).ToList();
|
||||
SetSeriesBook(seriesBook);
|
||||
}
|
||||
public SeriesEntry(SeriesBook seriesBook, LibraryBook child)
|
||||
public SeriesEntry(SeriesBook seriesBook, LibraryBook child) : this(seriesBook)
|
||||
{
|
||||
Children = new() { new LibraryBookEntry(child) { Parent = this } };
|
||||
SetSeriesBook(seriesBook);
|
||||
@ -69,7 +73,6 @@ namespace LibationWinForms.GridView
|
||||
private void SetSeriesBook(SeriesBook seriesBook)
|
||||
{
|
||||
SeriesBook = seriesBook;
|
||||
_memberValues = CreateMemberValueDictionary();
|
||||
LoadCover();
|
||||
|
||||
// Immutable properties
|
||||
@ -83,16 +86,9 @@ namespace LibationWinForms.GridView
|
||||
}
|
||||
}
|
||||
|
||||
// These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
|
||||
// Used by Dinah.Core.DataBinding.SortableBindingList<T> for all sorting
|
||||
public override object GetMemberValue(string memberName) => _memberValues[memberName]();
|
||||
|
||||
private Dictionary<string, Func<object>> _memberValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create getters for all member object values by name
|
||||
/// </summary>
|
||||
private Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
|
||||
/// <summary>Create getters for all member object values by name</summary>
|
||||
protected override Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
|
||||
{
|
||||
{ nameof(Title), () => Book.SeriesSortable() },
|
||||
{ nameof(Series), () => Book.SeriesSortable() },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user