From 3cb43e5d3ee9b5c36e2b9d3cbda2bbc561b60d33 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Sun, 22 May 2022 20:00:06 -0600
Subject: [PATCH 01/15] Improve display
---
.../ProcessQueue/VirtualFlowControl.Designer.cs | 13 ++++++++++++-
.../ProcessQueue/VirtualFlowControl.cs | 14 +++-----------
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs
index 77f793fc..dfcedef8 100644
--- a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs
+++ b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs
@@ -29,6 +29,7 @@
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
+ this.vScrollBar1 = new System.Windows.Forms.VScrollBar();
this.SuspendLayout();
//
// panel1
@@ -39,12 +40,21 @@
this.panel1.BackColor = System.Drawing.SystemColors.ControlDark;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(377, 505);
+ this.panel1.Size = new System.Drawing.Size(357, 505);
this.panel1.TabIndex = 0;
//
+ // vScrollBar1
+ //
+ this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right;
+ this.vScrollBar1.Location = new System.Drawing.Point(360, 0);
+ this.vScrollBar1.Name = "vScrollBar1";
+ this.vScrollBar1.Size = new System.Drawing.Size(17, 505);
+ this.vScrollBar1.TabIndex = 0;
+ //
// VirtualFlowControl
//
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.Controls.Add(this.vScrollBar1);
this.Controls.Add(this.panel1);
this.Name = "VirtualFlowControl";
this.Size = new System.Drawing.Size(377, 505);
@@ -55,5 +65,6 @@
#endregion
private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.VScrollBar vScrollBar1;
}
}
diff --git a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
index d031d191..296e34bf 100644
--- a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
@@ -75,7 +75,6 @@ namespace LibationWinForms.ProcessQueue
///
private readonly int TopMargin;
- private readonly VScrollBar vScrollBar1;
private readonly List BookControls = new();
#endregion
@@ -101,16 +100,6 @@ namespace LibationWinForms.ProcessQueue
{
InitializeComponent();
- vScrollBar1 = new VScrollBar
- {
- Minimum = 0,
- Value = 0,
- Dock = DockStyle.Right
- };
- Controls.Add(vScrollBar1);
-
- vScrollBar1.Scroll += (_, s) => SetScrollPosition(s.NewValue);
- panel1.Width -= vScrollBar1.Width + panel1.Margin.Right;
panel1.Resize += (_, _) =>
{
AdjustScrollBar();
@@ -135,6 +124,7 @@ namespace LibationWinForms.ProcessQueue
panel1.Controls.Add(control);
}
+ vScrollBar1.Scroll += (_, s) => SetScrollPosition(s.NewValue);
vScrollBar1.SmallChange = SmallScrollChange;
panel1.Height += NUM_BLANK_SPACES_AT_BOTTOM * VirtualControlHeight;
}
@@ -227,6 +217,8 @@ namespace LibationWinForms.ProcessQueue
///
private void SetScrollPosition(int value)
{
+ if (!vScrollBar1.Enabled) return;
+
int newPos = (int)Math.Round((double)value / SmallScrollChange) * SmallScrollChange;
if (vScrollBar1.Value != newPos)
{
From e8a320dac97e545767f5386c4b474bb47ddda497 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Sun, 22 May 2022 20:00:41 -0600
Subject: [PATCH 02/15] Add grid categories
---
Source/AppScaffolding/AppScaffolding.csproj | 2 +-
Source/DataLayer/EfClasses/Rating.cs | 2 +-
.../Dialogs/RemoveBooksDialog.cs | 11 +-
Source/LibationWinForms/Form1.cs | 4 +-
.../LibationWinForms/LibationWinForms.csproj | 6 +
.../Properties/Resources.Designer.cs | 20 ++
.../Properties/Resources.resx | 6 +
Source/LibationWinForms/Resources/minus.png | Bin 0 -> 425 bytes
Source/LibationWinForms/Resources/plus.png | Bin 0 -> 689 bytes
.../grid/FilterableSortableBindingList.cs | 75 ++++-
Source/LibationWinForms/grid/GridEntry.cs | 271 +++---------------
.../LiberateDataGridViewImageButtonColumn.cs | 22 +-
.../LibationWinForms/grid/LibraryBookEntry.cs | 253 ++++++++++++++++
.../grid/MasterDataGridView.cs | 26 ++
.../grid/ProductsDisplay.Designer.cs | 46 +++
.../LibationWinForms/grid/ProductsDisplay.cs | 152 ++++++++++
.../grid/ProductsDisplay.resx | 63 ++++
.../grid/ProductsGrid.Designer.cs | 28 +-
Source/LibationWinForms/grid/ProductsGrid.cs | 193 +++++++------
.../LibationWinForms/grid/ProductsGrid.resx | 6 -
Source/LibationWinForms/grid/SeriesEntry.cs | 90 ++++++
.../grid/SortableBindingList1.cs | 111 +++++++
22 files changed, 1008 insertions(+), 379 deletions(-)
create mode 100644 Source/LibationWinForms/Resources/minus.png
create mode 100644 Source/LibationWinForms/Resources/plus.png
create mode 100644 Source/LibationWinForms/grid/LibraryBookEntry.cs
create mode 100644 Source/LibationWinForms/grid/MasterDataGridView.cs
create mode 100644 Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
create mode 100644 Source/LibationWinForms/grid/ProductsDisplay.cs
create mode 100644 Source/LibationWinForms/grid/ProductsDisplay.resx
create mode 100644 Source/LibationWinForms/grid/SeriesEntry.cs
create mode 100644 Source/LibationWinForms/grid/SortableBindingList1.cs
diff --git a/Source/AppScaffolding/AppScaffolding.csproj b/Source/AppScaffolding/AppScaffolding.csproj
index 37d7e6ca..db37ad59 100644
--- a/Source/AppScaffolding/AppScaffolding.csproj
+++ b/Source/AppScaffolding/AppScaffolding.csproj
@@ -3,7 +3,7 @@
net6.0-windows
- 7.7.1.1
+ 7.7.0.14
diff --git a/Source/DataLayer/EfClasses/Rating.cs b/Source/DataLayer/EfClasses/Rating.cs
index 761633be..18b0cd05 100644
--- a/Source/DataLayer/EfClasses/Rating.cs
+++ b/Source/DataLayer/EfClasses/Rating.cs
@@ -12,7 +12,7 @@ namespace DataLayer
public float StoryRating { get; private set; }
private Rating() { }
- internal Rating(float overallRating, float performanceRating, float storyRating)
+ public Rating(float overallRating, float performanceRating, float storyRating)
{
OverallRating = overallRating;
PerformanceRating = performanceRating;
diff --git a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
index ecd56188..bb1759dc 100644
--- a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
+++ b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
@@ -121,10 +121,8 @@ namespace LibationWinForms.Dialogs
}
}
- internal class RemovableGridEntry : GridEntry
+ internal class RemovableGridEntry : LibraryBookEntry
{
- private static readonly IComparer BoolComparer = new ObjectComparer();
-
private bool _remove = false;
public RemovableGridEntry(LibraryBook libraryBook) : base(libraryBook) { }
@@ -147,12 +145,5 @@ namespace LibationWinForms.Dialogs
return Remove;
return base.GetMemberValue(memberName);
}
-
- public override IComparer GetMemberComparer(Type memberType)
- {
- if (memberType == typeof(bool))
- return BoolComparer;
- return base.GetMemberComparer(memberType);
- }
}
}
diff --git a/Source/LibationWinForms/Form1.cs b/Source/LibationWinForms/Form1.cs
index 04150167..0c2f3ce1 100644
--- a/Source/LibationWinForms/Form1.cs
+++ b/Source/LibationWinForms/Form1.cs
@@ -12,7 +12,7 @@ namespace LibationWinForms
{
public partial class Form1 : Form
{
- private ProductsGrid productsGrid { get; }
+ private ProductsDisplay productsGrid { get; }
public Form1()
{
@@ -26,7 +26,7 @@ namespace LibationWinForms
// Failed to create component 'ProductsGrid'. The error message follows:
// 'Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Object reference not set to an instance of an object.
// Since the designer's choking on it, I'm keeping it below the DesignMode check to be safe
- productsGrid = new ProductsGrid { Dock = DockStyle.Fill };
+ productsGrid = new ProductsDisplay { Dock = DockStyle.Fill };
gridPanel.Controls.Add(productsGrid);
}
diff --git a/Source/LibationWinForms/LibationWinForms.csproj b/Source/LibationWinForms/LibationWinForms.csproj
index 2ecd019b..979db0ff 100644
--- a/Source/LibationWinForms/LibationWinForms.csproj
+++ b/Source/LibationWinForms/LibationWinForms.csproj
@@ -45,6 +45,9 @@
+
+ UserControl
+
True
True
@@ -53,6 +56,9 @@
+
+ Designer
+
ResXFileCodeGenerator
Resources.Designer.cs
diff --git a/Source/LibationWinForms/Properties/Resources.Designer.cs b/Source/LibationWinForms/Properties/Resources.Designer.cs
index 468d9e4d..f3e881e2 100644
--- a/Source/LibationWinForms/Properties/Resources.Designer.cs
+++ b/Source/LibationWinForms/Properties/Resources.Designer.cs
@@ -229,5 +229,25 @@ namespace LibationWinForms.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap minus {
+ get {
+ object obj = ResourceManager.GetObject("minus", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap plus {
+ get {
+ object obj = ResourceManager.GetObject("plus", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
}
}
diff --git a/Source/LibationWinForms/Properties/Resources.resx b/Source/LibationWinForms/Properties/Resources.resx
index 0a1ae67a..95b3b8a0 100644
--- a/Source/LibationWinForms/Properties/Resources.resx
+++ b/Source/LibationWinForms/Properties/Resources.resx
@@ -169,4 +169,10 @@
..\Resources\liberate_yellow_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\minus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\plus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/Source/LibationWinForms/Resources/minus.png b/Source/LibationWinForms/Resources/minus.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfc2cf4abc65ecbd5ac663ccf26584d356818814
GIT binary patch
literal 425
zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GG!XV7ZFl&wkP*5S+
zBgmJ5p-Pp3p`n?9;pcxK{gQ#9)PRBERRRNp)eHs(@%%~gN8K1081+3}978H@y}4=V
zci2I|;o|w$z5E2+II)LiOI_s3muj?ww!P_=H)F*;mrLYpJ|UCeg?qu<@w|S{tuv+bcHU-fW7@+c{XpA$&9{y-rIUB^
zzhmMpsCStDK&*m!Uc>8kWjB^{Z#m%XSC^5yK{keQ@qd9&LLzv*An>66$ajXYck|g#
T{9jWB3}yyTS3j3^P6Z9gktZjYPrOP?j1FFJAGKiK|}SEq(q{#f~j35QNyI>IO9)6v_Ms3UX2lW&J@
zzw5U&A*PtNH}|%0-fV3D+@(b;y0>dKqX7fk0S1W%t>|RgW~=A#8pJNJv^j*kth;VB
zeM0Mm;&);@82TDxV;l4n81^vqD-{VBv&>;$eqi6aeatL3n9IHt`nkyl<`fe%>pk
ze|FW~XTSAIJXI(s^M-%eKXLiJ`&QQlGG#D%9y_~SQRS7mDnt0D`Bxc1Rx&UrFz_@0
z?f);=P<(E+P{{umN(v_p<9z=Vf$2@a>Anae6tJ%OKsja!;tdv%j$+VniLwli{?fd#|k4rt&
zT>tbYQ>0PY#jqPs&oFWxePWnjxptcJo6RXY_osip!W?t3aL?1NsgXYoM87$`pb8Yut(
literal 0
HcmV?d00001
diff --git a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
index 1e896e0b..e3bcaad0 100644
--- a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
+++ b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
@@ -19,14 +19,16 @@ namespace LibationWinForms
* Remove is overridden to ensure that removed items are removed from
* the base list (visible items) as well as the FilterRemoved list.
*/
- internal class FilterableSortableBindingList : SortableBindingList, IBindingListView
+ internal class FilterableSortableBindingList : SortableBindingList1, IBindingListView
{
///
/// Items that were removed from the base list due to filtering
///
private readonly List FilterRemoved = new();
private string FilterString;
+ private LibationSearchEngine.SearchResultSet SearchResults;
public FilterableSortableBindingList(IEnumerable enumeration) : base(enumeration) { }
+ public FilterableSortableBindingList() : base(new List()) { }
public bool SupportsFiltering => true;
public string Filter { get => FilterString; set => ApplyFilter(value); }
@@ -48,7 +50,14 @@ namespace LibationWinForms
}
/// All items in the list, including those filtered out.
- public List AllItems() => Items.Concat(FilterRemoved).ToList();
+ public List AllItems()
+ {
+ var allItems = Items.Concat(FilterRemoved);
+
+ var series = allItems.Where(i => i is SeriesEntry).Cast().SelectMany(s => s.Children);
+
+ return series.Concat(allItems).ToList();
+ }
private void ApplyFilter(string filterString)
{
@@ -57,18 +66,49 @@ namespace LibationWinForms
FilterString = filterString;
- var searchResults = SearchEngineCommands.Search(filterString);
- var filteredOut = Items.ExceptBy(searchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId);
+ SearchResults = SearchEngineCommands.Search(filterString);
+ var filteredOut = Items.Where(i => i is LibraryBookEntry).Cast().ExceptBy(SearchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId).Cast().ToList();
- for (int i = Items.Count - 1; i >= 0; i--)
+ var parents = Items.Where(i => i is SeriesEntry).Cast();
+
+ foreach (var p in parents)
{
- if (filteredOut.Contains(Items[i]))
+ if (p.Children.Cast().ExceptBy(SearchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId).Count() == p.Children.Count)
{
- FilterRemoved.Add(Items[i]);
- Items.RemoveAt(i);
- base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, i));
+ //Don't show series whose episodes have all been filtered out
+ filteredOut.Add(p);
}
}
+
+ for (int i = 0; i < filteredOut.Count; i++)
+ {
+ FilterRemoved.Add(filteredOut[i]);
+ base.Remove(filteredOut[i]);
+ }
+ }
+
+ public void CollapseItem(SeriesEntry sEntry)
+ {
+ foreach (var item in Items.Where(b => b is LibraryBookEntry).Cast().Where(b => b.Parent == sEntry).ToList())
+ base.Remove(item);
+
+ sEntry.Liberate.Expanded = false;
+ }
+
+ public void ExpandItem(SeriesEntry sEntry)
+ {
+ var sindex = Items.IndexOf(sEntry);
+ var children = sEntry.Children.Cast().ToList();
+ for (int i = 0; i < children.Count; i++)
+ {
+ if (SearchResults is null || SearchResults.Docs.Any(d=> d.ProductId == children[i].AudibleProductId))
+ Insert(++sindex, children[i]);
+ else
+ {
+ FilterRemoved.Add(children[i]);
+ }
+ }
+ sEntry.Liberate.Expanded = true;
}
public void RemoveFilter()
@@ -77,18 +117,27 @@ namespace LibationWinForms
int visibleCount = Items.Count;
for (int i = 0; i < FilterRemoved.Count; i++)
- base.InsertItem(i + visibleCount, FilterRemoved[i]);
- OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+ {
+ if (FilterRemoved[i].Parent is null || FilterRemoved[i].Parent.Liberate.Expanded)
+ base.InsertItem(i + visibleCount, FilterRemoved[i]);
+ }
FilterRemoved.Clear();
if (IsSortedCore)
Sort();
else
- //No user-defined sort is applied, so do default sorting by date added, descending
- ((List)Items).Sort((i1, i2) => i2.LibraryBook.DateAdded.CompareTo(i1.LibraryBook.DateAdded));
+ //No user sort is applied, so do default sorting by PurchaseDate, descending
+ {
+ Comparer.PropertyName = nameof(GridEntry.DateAdded);
+ Comparer.Direction = ListSortDirection.Descending;
+ Sort();
+ }
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
FilterString = null;
+ SearchResults = null;
}
}
}
diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs
index 3e02dc93..a9d86b41 100644
--- a/Source/LibationWinForms/grid/GridEntry.cs
+++ b/Source/LibationWinForms/grid/GridEntry.cs
@@ -1,101 +1,65 @@
-using System;
+using DataLayer;
+using Dinah.Core.DataBinding;
+using Dinah.Core.Drawing;
+using LibationFileManager;
+using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
-using System.Linq;
-using ApplicationServices;
-using DataLayer;
-using Dinah.Core.DataBinding;
-using Dinah.Core;
-using Dinah.Core.Drawing;
-using LibationFileManager;
-using System.Threading.Tasks;
namespace LibationWinForms
{
- ///
- /// The View Model for a LibraryBook
- ///
- internal class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
+ public interface IHierarchical where T : class
{
- #region implementation properties NOT exposed to the view
- // hide from public fields from Data Source GUI with [Browsable(false)]
+ T Parent { get; }
+ List Children { get; }
+ }
+ internal class LiberateStatus
+ {
+ public LiberatedStatus BookStatus;
+ public LiberatedStatus? PdfStatus;
+ public bool IsSeries;
+ public bool Expanded;
+ }
- [Browsable(false)]
- public string AudibleProductId => Book.AudibleProductId;
- [Browsable(false)]
- public LibraryBook LibraryBook { get; private set; }
- [Browsable(false)]
- public string LongDescription { get; private set; }
- #endregion
+ internal abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable, IHierarchical
+ {
+ protected abstract Book Book { get; }
- #region Model properties exposed to the view
private Image _cover;
-
- private DateTime lastStatusUpdate = default;
- private LiberatedStatus _bookStatus;
- private LiberatedStatus? _pdfStatus;
+ #region Model properties exposed to the view
public Image Cover
{
get => _cover;
- private set
+ protected set
{
_cover = value;
NotifyPropertyChanged();
}
}
-
- public string ProductRating { get; private set; }
- public string PurchaseDate { get; private set; }
- public string MyRating { get; private set; }
- public string Series { get; private set; }
- public string Title { get; private set; }
- public string Length { get; private set; }
- public string Authors { get; private set; }
- public string Narrators { get; private set; }
- public string Category { get; private set; }
- public string Misc { get; private set; }
- public string Description { get; private set; }
- public string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
-
- // these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
- public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate
- {
- get
- {
- //Cache these statuses for faster sorting.
- if ((DateTime.Now - lastStatusUpdate).TotalSeconds > 2)
- {
- _bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book);
- _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
- lastStatusUpdate = DateTime.Now;
- }
- return (_bookStatus, _pdfStatus);
- }
- }
+ public GridEntry Parent { get; set; }
+ public List Children { get; set; }
+ public abstract string ProductRating { get; protected set; }
+ public abstract string PurchaseDate { get; protected set; }
+ public abstract DateTime DateAdded { get; }
+ public abstract string MyRating { get; protected set; }
+ public abstract string Series { get; protected set; }
+ public abstract string Title { get; protected set; }
+ public abstract string Length { get; protected set; }
+ public abstract string Authors { get; protected set; }
+ public abstract string Narrators { get; protected set; }
+ public abstract string Category { get; protected set; }
+ public abstract string Misc { get; protected set; }
+ public abstract string Description { get; protected set; }
+ public abstract string DisplayTags { get; }
+ public abstract LiberateStatus Liberate { get; }
+ public abstract object GetMemberValue(string memberName);
#endregion
+ public IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
- // alias
- private Book Book => LibraryBook.Book;
-
- public GridEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
-
- public void UpdateLibraryBook(LibraryBook libraryBook)
+ protected void LoadCover()
{
- if (AudibleProductId != libraryBook.Book.AudibleProductId)
- throw new Exception("Invalid grid entry update. IDs must match");
-
- setLibraryBook(libraryBook);
-
- NotifyPropertyChanged();
- }
-
- private void setLibraryBook(LibraryBook libraryBook)
- {
- LibraryBook = libraryBook;
- _memberValues = CreateMemberValueDictionary();
-
// Get cover art. If it's default, subscribe to PictureCached
{
(bool isDefault, byte[] picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80));
@@ -106,24 +70,6 @@ namespace LibationWinForms
// Mutable property. Set the field so PropertyChanged isn't fired.
_cover = ImageReader.ToImage(picture);
}
-
- // Immutable properties
- {
- Title = Book.Title;
- Series = Book.SeriesNames();
- Length = Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min";
- MyRating = Book.UserDefinedItem.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
- PurchaseDate = libraryBook.DateAdded.ToString("d");
- ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
- Authors = Book.AuthorNames();
- Narrators = Book.NarratorNames();
- Category = string.Join(" > ", Book.CategoriesNames());
- Misc = GetMiscDisplay(libraryBook);
- LongDescription = GetDescriptionDisplay(Book);
- Description = TrimTextToWord(LongDescription, 62);
- }
-
- UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged;
}
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)
@@ -135,154 +81,19 @@ namespace LibationWinForms
}
}
- #region detect changes to the model, update the view, and save to database.
-
- ///
- /// This event handler receives notifications from the model that it has changed.
- /// Save to the database and notify the view that it's changed.
- ///
- private void UserDefinedItem_ItemChanged(object sender, string itemName)
- {
- var udi = sender as UserDefinedItem;
-
- if (udi.Book.AudibleProductId != Book.AudibleProductId)
- return;
-
- switch (itemName)
- {
- case nameof(udi.Tags):
- Book.UserDefinedItem.Tags = udi.Tags;
- NotifyPropertyChanged(nameof(DisplayTags));
- break;
- case nameof(udi.BookStatus):
- Book.UserDefinedItem.BookStatus = udi.BookStatus;
- _bookStatus = udi.BookStatus;
- NotifyPropertyChanged(nameof(Liberate));
- break;
- case nameof(udi.PdfStatus):
- Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
- _pdfStatus = udi.PdfStatus;
- NotifyPropertyChanged(nameof(Liberate));
- break;
- }
- }
-
- /// Save edits to the database
- public void Commit(string newTags, LiberatedStatus bookStatus, LiberatedStatus? pdfStatus)
- {
- // validate
- if (DisplayTags.EqualsInsensitive(newTags) &&
- Liberate.BookStatus == bookStatus &&
- Liberate.PdfStatus == pdfStatus)
- return;
-
- // update cache
- _bookStatus = bookStatus;
- _pdfStatus = pdfStatus;
-
- // set + save
- Book.UserDefinedItem.Tags = newTags;
- Book.UserDefinedItem.BookStatus = bookStatus;
- Book.UserDefinedItem.PdfStatus = pdfStatus;
- LibraryCommands.UpdateUserDefinedItem(Book);
- }
-
- #endregion
-
- #region Data Sorting
- // These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
- // Used by Dinah.Core.DataBinding.SortableBindingList for all sorting
- public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
- public virtual IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
-
- private Dictionary> _memberValues { get; set; }
-
- ///
- /// Create getters for all member object values by name
- ///
- private Dictionary> CreateMemberValueDictionary() => new()
- {
- { nameof(Title), () => Book.TitleSortable() },
- { nameof(Series), () => Book.SeriesSortable() },
- { nameof(Length), () => Book.LengthInMinutes },
- { nameof(MyRating), () => Book.UserDefinedItem.Rating.FirstScore() },
- { nameof(PurchaseDate), () => LibraryBook.DateAdded },
- { nameof(ProductRating), () => Book.Rating.FirstScore() },
- { nameof(Authors), () => Authors },
- { nameof(Narrators), () => Narrators },
- { nameof(Description), () => Description },
- { nameof(Category), () => Category },
- { nameof(Misc), () => Misc },
- { nameof(DisplayTags), () => DisplayTags },
- { nameof(Liberate), () => Liberate.BookStatus }
- };
-
// Instantiate comparers for every exposed member object type.
private static readonly Dictionary _memberTypeComparers = new()
{
{ typeof(string), new ObjectComparer() },
{ typeof(int), new ObjectComparer() },
{ typeof(float), new ObjectComparer() },
+ { typeof(bool), new ObjectComparer() },
{ typeof(DateTime), new ObjectComparer() },
{ typeof(LiberatedStatus), new ObjectComparer() },
};
- #endregion
-
- #region Static library display functions
-
- ///
- /// This information should not change during lifetime, so call only once.
- ///
- private static string GetDescriptionDisplay(Book book)
- {
- var doc = new HtmlAgilityPack.HtmlDocument();
- doc.LoadHtml(book?.Description?.Replace("
", "\r\n\r\n") ?? "");
- return doc.DocumentNode.InnerText.Trim();
- }
-
- private static string TrimTextToWord(string text, int maxLength)
- {
- return
- text.Length <= maxLength ?
- text :
- text.Substring(0, maxLength - 3) + "...";
- }
-
- ///
- /// This information should not change during lifetime, so call only once.
- /// Maximum of 5 text rows will fit in 80-pixel row height.
- ///
- private static string GetMiscDisplay(LibraryBook libraryBook)
- {
- var details = new List();
-
- var locale = libraryBook.Book.Locale.DefaultIfNullOrWhiteSpace("[unknown]");
- var acct = libraryBook.Account.DefaultIfNullOrWhiteSpace("[unknown]");
-
- details.Add($"Account: {locale} - {acct}");
-
- if (libraryBook.Book.HasPdf())
- details.Add("Has PDF");
- if (libraryBook.Book.IsAbridged)
- details.Add("Abridged");
- if (libraryBook.Book.DatePublished.HasValue)
- details.Add($"Date pub'd: {libraryBook.Book.DatePublished.Value:MM/dd/yyyy}");
- // this goes last since it's most likely to have a line-break
- if (!string.IsNullOrWhiteSpace(libraryBook.Book.Publisher))
- details.Add($"Pub: {libraryBook.Book.Publisher.Trim()}");
-
- if (!details.Any())
- return "[details not imported]";
-
- return string.Join("\r\n", details);
- }
-
- #endregion
-
~GridEntry()
{
- UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
PictureStorage.PictureCached -= PictureStorage_PictureCached;
}
}
diff --git a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
index e5ab82b8..159b1e4a 100644
--- a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
@@ -20,15 +20,27 @@ namespace LibationWinForms
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
- if (value is (LiberatedStatus, LiberatedStatus) or (LiberatedStatus, null))
+ if (value is LiberateStatus status)
{
- var (bookState, pdfState) = ((LiberatedStatus bookState, LiberatedStatus? pdfState))value;
+ if (status.IsSeries)
+ {
+ var imageName = status.Expanded ? "minus" : "plus";
+ var text = status.Expanded ? "Click to Collpase" : "Click to Expand";
- (string mouseoverText, Bitmap buttonImage) = GetLiberateDisplay(bookState, pdfState);
+ var bmp = (Bitmap)Properties.Resources.ResourceManager.GetObject(imageName);
+ DrawButtonImage(graphics, bmp, cellBounds);
- DrawButtonImage(graphics, buttonImage, cellBounds);
+ ToolTipText = text;
- ToolTipText = mouseoverText;
+ }
+ else
+ {
+ (string mouseoverText, Bitmap buttonImage) = GetLiberateDisplay(status.BookStatus, status.PdfStatus);
+
+ DrawButtonImage(graphics, buttonImage, cellBounds);
+
+ ToolTipText = mouseoverText;
+ }
}
}
diff --git a/Source/LibationWinForms/grid/LibraryBookEntry.cs b/Source/LibationWinForms/grid/LibraryBookEntry.cs
new file mode 100644
index 00000000..e87ae630
--- /dev/null
+++ b/Source/LibationWinForms/grid/LibraryBookEntry.cs
@@ -0,0 +1,253 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using ApplicationServices;
+using DataLayer;
+using Dinah.Core.DataBinding;
+using Dinah.Core;
+using Dinah.Core.Drawing;
+using LibationFileManager;
+using System.Threading.Tasks;
+
+namespace LibationWinForms
+{
+ ///
+ /// The View Model for a LibraryBook
+ ///
+ internal class LibraryBookEntry : GridEntry
+ {
+ #region implementation properties NOT exposed to the view
+ // hide from public fields from Data Source GUI with [Browsable(false)]
+
+ [Browsable(false)]
+ public string AudibleProductId => Book.AudibleProductId;
+ [Browsable(false)]
+ public LibraryBook LibraryBook { get; private set; }
+ [Browsable(false)]
+ public string LongDescription { get; private set; }
+ #endregion
+
+ // alias
+ protected override Book Book => LibraryBook.Book;
+ #region Model properties exposed to the view
+
+ private DateTime lastStatusUpdate = default;
+ private LiberatedStatus _bookStatus;
+ private LiberatedStatus? _pdfStatus;
+
+ public override DateTime DateAdded => LibraryBook.DateAdded;
+ public override string ProductRating { get; protected set; }
+ public override string PurchaseDate { get; protected set; }
+ public override string MyRating { get; protected set; }
+ public override string Series { get; protected set; }
+ public override string Title { get; protected set; }
+ public override string Length { get; protected set; }
+ public override string Authors { get; protected set; }
+ public override string Narrators { get; protected set; }
+ public override string Category { get; protected set; }
+ public override string Misc { get; protected set; }
+ public override string Description { get; protected set; }
+ public override string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
+
+ // these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
+ public override LiberateStatus Liberate
+ {
+ get
+ {
+ //Cache these statuses for faster sorting.
+ if ((DateTime.Now - lastStatusUpdate).TotalSeconds > 2)
+ {
+ _bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book);
+ _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
+ lastStatusUpdate = DateTime.Now;
+ }
+ return new LiberateStatus { BookStatus = _bookStatus, PdfStatus = _pdfStatus, IsSeries = false };
+ }
+ }
+ #endregion
+
+
+ public LibraryBookEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
+
+ public void UpdateLibraryBook(LibraryBook libraryBook)
+ {
+ if (AudibleProductId != libraryBook.Book.AudibleProductId)
+ throw new Exception("Invalid grid entry update. IDs must match");
+
+ setLibraryBook(libraryBook);
+
+ NotifyPropertyChanged();
+ }
+
+ private void setLibraryBook(LibraryBook libraryBook)
+ {
+ LibraryBook = libraryBook;
+ _memberValues = CreateMemberValueDictionary();
+
+ LoadCover();
+
+ // Immutable properties
+ {
+ Title = Book.Title;
+ Series = Book.SeriesNames();
+ Length = Book.LengthInMinutes == 0 ? "" : $"{Book.LengthInMinutes / 60} hr {Book.LengthInMinutes % 60} min";
+ MyRating = Book.UserDefinedItem.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ PurchaseDate = libraryBook.DateAdded.ToString("d");
+ ProductRating = Book.Rating?.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ Authors = Book.AuthorNames();
+ Narrators = Book.NarratorNames();
+ Category = string.Join(" > ", Book.CategoriesNames());
+ Misc = GetMiscDisplay(libraryBook);
+ LongDescription = GetDescriptionDisplay(Book);
+ Description = TrimTextToWord(LongDescription, 62);
+ }
+
+ UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged;
+ }
+
+
+ #region detect changes to the model, update the view, and save to database.
+
+ ///
+ /// This event handler receives notifications from the model that it has changed.
+ /// Save to the database and notify the view that it's changed.
+ ///
+ private void UserDefinedItem_ItemChanged(object sender, string itemName)
+ {
+ var udi = sender as UserDefinedItem;
+
+ if (udi.Book.AudibleProductId != Book.AudibleProductId)
+ return;
+
+ switch (itemName)
+ {
+ case nameof(udi.Tags):
+ Book.UserDefinedItem.Tags = udi.Tags;
+ NotifyPropertyChanged(nameof(DisplayTags));
+ break;
+ case nameof(udi.BookStatus):
+ Book.UserDefinedItem.BookStatus = udi.BookStatus;
+ _bookStatus = udi.BookStatus;
+ NotifyPropertyChanged(nameof(Liberate));
+ break;
+ case nameof(udi.PdfStatus):
+ Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
+ _pdfStatus = udi.PdfStatus;
+ NotifyPropertyChanged(nameof(Liberate));
+ break;
+ }
+ }
+
+ /// Save edits to the database
+ public void Commit(string newTags, LiberatedStatus bookStatus, LiberatedStatus? pdfStatus)
+ {
+ // validate
+ if (DisplayTags.EqualsInsensitive(newTags) &&
+ Liberate.BookStatus == bookStatus &&
+ Liberate.PdfStatus == pdfStatus)
+ return;
+
+ // update cache
+ _bookStatus = bookStatus;
+ _pdfStatus = pdfStatus;
+
+ // set + save
+ Book.UserDefinedItem.Tags = newTags;
+ Book.UserDefinedItem.BookStatus = bookStatus;
+ Book.UserDefinedItem.PdfStatus = pdfStatus;
+ LibraryCommands.UpdateUserDefinedItem(Book);
+ }
+
+ #endregion
+
+ #region Data Sorting
+ // These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
+ // Used by Dinah.Core.DataBinding.SortableBindingList for all sorting
+ public override object GetMemberValue(string memberName) => _memberValues[memberName]();
+
+ private Dictionary> _memberValues { get; set; }
+
+ ///
+ /// Create getters for all member object values by name
+ ///
+ private Dictionary> CreateMemberValueDictionary() => new()
+ {
+ { nameof(Title), () => Book.TitleSortable() },
+ { nameof(Series), () => Book.SeriesSortable() },
+ { nameof(Length), () => Book.LengthInMinutes },
+ { nameof(MyRating), () => Book.UserDefinedItem.Rating.FirstScore() },
+ { nameof(PurchaseDate), () => LibraryBook.DateAdded },
+ { nameof(ProductRating), () => Book.Rating.FirstScore() },
+ { nameof(Authors), () => Authors },
+ { nameof(Narrators), () => Narrators },
+ { nameof(Description), () => Description },
+ { nameof(Category), () => Category },
+ { nameof(Misc), () => Misc },
+ { nameof(DisplayTags), () => DisplayTags },
+ { nameof(Liberate), () => Liberate.BookStatus },
+ { nameof(DateAdded), () => DateAdded },
+ };
+
+
+ #endregion
+
+ #region Static library display functions
+
+ ///
+ /// This information should not change during lifetime, so call only once.
+ ///
+ private static string GetDescriptionDisplay(Book book)
+ {
+ var doc = new HtmlAgilityPack.HtmlDocument();
+ doc.LoadHtml(book?.Description?.Replace(" ", "\r\n\r\n") ?? "");
+ return doc.DocumentNode.InnerText.Trim();
+ }
+
+ private static string TrimTextToWord(string text, int maxLength)
+ {
+ return
+ text.Length <= maxLength ?
+ text :
+ text.Substring(0, maxLength - 3) + "...";
+ }
+
+ ///
+ /// This information should not change during lifetime, so call only once.
+ /// Maximum of 5 text rows will fit in 80-pixel row height.
+ ///
+ private static string GetMiscDisplay(LibraryBook libraryBook)
+ {
+ var details = new List();
+
+ var locale = libraryBook.Book.Locale.DefaultIfNullOrWhiteSpace("[unknown]");
+ var acct = libraryBook.Account.DefaultIfNullOrWhiteSpace("[unknown]");
+
+ details.Add($"Account: {locale} - {acct}");
+
+ if (libraryBook.Book.HasPdf())
+ details.Add("Has PDF");
+ if (libraryBook.Book.IsAbridged)
+ details.Add("Abridged");
+ if (libraryBook.Book.DatePublished.HasValue)
+ details.Add($"Date pub'd: {libraryBook.Book.DatePublished.Value:MM/dd/yyyy}");
+ // this goes last since it's most likely to have a line-break
+ if (!string.IsNullOrWhiteSpace(libraryBook.Book.Publisher))
+ details.Add($"Pub: {libraryBook.Book.Publisher.Trim()}");
+
+ if (!details.Any())
+ return "[details not imported]";
+
+ return string.Join("\r\n", details);
+ }
+
+ #endregion
+
+ ~LibraryBookEntry()
+ {
+ UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
+ }
+ }
+}
diff --git a/Source/LibationWinForms/grid/MasterDataGridView.cs b/Source/LibationWinForms/grid/MasterDataGridView.cs
new file mode 100644
index 00000000..fd3b481a
--- /dev/null
+++ b/Source/LibationWinForms/grid/MasterDataGridView.cs
@@ -0,0 +1,26 @@
+using Dinah.Core.Windows.Forms;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace LibationWinForms
+{
+
+ internal class MasterDataGridView : DataGridView
+ {
+ internal delegate void LibraryBookEntryClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry entry);
+ public event LibraryBookEntryClickedEventHandler LibraryBookEntryClicked;
+ public MasterDataGridView()
+ {
+
+ }
+
+
+ public GridEntry getGridEntry(int rowIndex) => this.GetBoundItem(rowIndex);
+
+ }
+}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
new file mode 100644
index 00000000..d15ad85c
--- /dev/null
+++ b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
@@ -0,0 +1,46 @@
+namespace LibationWinForms
+{
+ partial class ProductsDisplay
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // ProductsDisplay
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.Name = "ProductsDisplay";
+ this.Size = new System.Drawing.Size(1510, 380);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.cs b/Source/LibationWinForms/grid/ProductsDisplay.cs
new file mode 100644
index 00000000..e0e0fd58
--- /dev/null
+++ b/Source/LibationWinForms/grid/ProductsDisplay.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using ApplicationServices;
+using DataLayer;
+using Dinah.Core.Windows.Forms;
+using FileLiberator;
+using LibationFileManager;
+using LibationWinForms.Dialogs;
+
+namespace LibationWinForms
+{
+
+ #region // legacy instructions to update data_grid_view
+ // INSTRUCTIONS TO UPDATE DATA_GRID_VIEW
+ // - delete current DataGridView
+ // - view > other windows > data sources
+ // - refresh
+ // OR
+ // - Add New Data Source
+ // Object. Next
+ // LibationWinForms
+ // AudibleDTO
+ // GridEntry
+ // - go to Design view
+ // - click on Data Sources > ProductItem. dropdown: DataGridView
+ // - drag/drop ProductItem on design surface
+ //
+ // as of august 2021 this does not work in vs2019 with .net5 projects
+ // VS has improved since then with .net6+ but I haven't checked again
+ #endregion
+
+
+ public partial class ProductsDisplay : UserControl
+ {
+ public event EventHandler LiberateClicked;
+ /// Number of visible rows has changed
+ public event EventHandler VisibleCountChanged;
+
+ // alias
+
+ private ProductsGrid grid;
+
+ public ProductsDisplay()
+ {
+ InitializeComponent();
+
+ grid = new ProductsGrid();
+ grid.Dock = DockStyle.Fill;
+ Controls.Add(grid);
+
+ if (this.DesignMode)
+ return;
+
+ grid.LiberateClicked += (_, book) => LiberateClicked?.Invoke(this, book.LibraryBook);
+ grid.DetailsClicked += Grid_DetailsClicked;
+ grid.CoverClicked += Grid_CoverClicked;
+ grid.DescriptionClicked += Grid_DescriptionClicked1;
+ }
+
+ #region Button controls
+
+ private ImageDisplay imageDisplay;
+ private async void Grid_CoverClicked(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry)
+ {
+ var picDefinition = new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureLarge ?? liveGridEntry.LibraryBook.Book.PictureId, PictureSize.Native);
+ var picDlTask = Task.Run(() => PictureStorage.GetPictureSynchronously(picDefinition));
+
+ (_, byte[] initialImageBts) = PictureStorage.GetPicture(new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureId, PictureSize._80x80));
+ var windowTitle = $"{liveGridEntry.Title} - Cover";
+
+ if (imageDisplay is null || imageDisplay.IsDisposed || !imageDisplay.Visible)
+ {
+ imageDisplay = new ImageDisplay();
+ imageDisplay.RestoreSizeAndLocation(Configuration.Instance);
+ imageDisplay.FormClosed += (_, _) => imageDisplay.SaveSizeAndLocation(Configuration.Instance);
+ imageDisplay.Show(this);
+ }
+
+ imageDisplay.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(liveGridEntry.LibraryBook);
+ imageDisplay.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(liveGridEntry.LibraryBook, ".jpg"));
+ imageDisplay.Text = windowTitle;
+ imageDisplay.CoverPicture = initialImageBts;
+ imageDisplay.CoverPicture = await picDlTask;
+ }
+
+ private void Grid_DescriptionClicked1(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry, Rectangle cellRectangle)
+ {
+ var displayWindow = new DescriptionDisplay
+ {
+ SpawnLocation = PointToScreen(cellRectangle.Location + new Size(cellRectangle.Width, 0)),
+ DescriptionText = liveGridEntry.LongDescription,
+ BorderThickness = 2,
+ };
+
+ void CloseWindow(object o, EventArgs e)
+ {
+ displayWindow.Close();
+ }
+
+ grid.Scroll += CloseWindow;
+ displayWindow.FormClosed += (_, _) => grid.Scroll -= CloseWindow;
+ displayWindow.Show(this);
+ }
+
+
+ private void Grid_DetailsClicked(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry)
+ {
+ var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
+ if (bookDetailsForm.ShowDialog() == DialogResult.OK)
+ liveGridEntry.Commit(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
+ }
+
+ #endregion
+
+ #region UI display functions
+
+ private bool hasBeenDisplayed;
+ public event EventHandler InitialLoaded;
+ public void Display()
+ {
+ // don't return early if lib size == 0. this will not update correctly if all books are removed
+ var lib = DbContexts.GetLibrary_Flat_NoTracking();
+
+ if (!hasBeenDisplayed)
+ {
+ // bind
+ grid.bindToGrid(lib);
+ hasBeenDisplayed = true;
+ InitialLoaded?.Invoke(this, new());
+ VisibleCountChanged?.Invoke(this, grid.GetVisible().Count());
+ }
+ else
+ grid.updateGrid(lib);
+
+ }
+
+ #endregion
+
+ #region Filter
+
+ public void Filter(string searchString)
+ => grid.Filter(searchString);
+
+ #endregion
+
+ internal List GetVisible() => grid.GetVisible().ToList();
+ }
+}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.resx b/Source/LibationWinForms/grid/ProductsDisplay.resx
new file mode 100644
index 00000000..be5db7af
--- /dev/null
+++ b/Source/LibationWinForms/grid/ProductsDisplay.resx
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 81
+
+
\ No newline at end of file
diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
index b3eaecd5..27496d79 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
@@ -64,20 +64,20 @@
this.gridEntryDataGridView.AutoGenerateColumns = false;
this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.liberateGVColumn,
- this.coverGVColumn,
- this.titleGVColumn,
- this.authorsGVColumn,
- this.narratorsGVColumn,
- this.lengthGVColumn,
- this.seriesGVColumn,
- this.descriptionGVColumn,
- this.categoryGVColumn,
- this.productRatingGVColumn,
- this.purchaseDateGVColumn,
- this.myRatingGVColumn,
- this.miscGVColumn,
- this.tagAndDetailsGVColumn});
+ this.liberateGVColumn,
+ this.coverGVColumn,
+ this.titleGVColumn,
+ this.authorsGVColumn,
+ this.narratorsGVColumn,
+ this.lengthGVColumn,
+ this.seriesGVColumn,
+ this.descriptionGVColumn,
+ this.categoryGVColumn,
+ this.productRatingGVColumn,
+ this.purchaseDateGVColumn,
+ this.myRatingGVColumn,
+ this.miscGVColumn,
+ this.tagAndDetailsGVColumn});
this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1;
this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index 690cb00d..2d585f27 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -2,14 +2,11 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
-using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
using DataLayer;
using Dinah.Core.Windows.Forms;
-using FileLiberator;
using LibationFileManager;
-using LibationWinForms.Dialogs;
namespace LibationWinForms
{
@@ -36,7 +33,17 @@ namespace LibationWinForms
public partial class ProductsGrid : UserControl
{
- public event EventHandler LiberateClicked;
+
+ internal delegate void LibraryBookEntryClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry);
+ internal delegate void LibraryBookEntryRectangleClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry, Rectangle cellRectangle);
+ internal event LibraryBookEntryClickedEventHandler LiberateClicked;
+ internal event LibraryBookEntryClickedEventHandler CoverClicked;
+ internal event LibraryBookEntryClickedEventHandler DetailsClicked;
+ internal event LibraryBookEntryRectangleClickedEventHandler DescriptionClicked;
+ public new event EventHandler Scroll;
+
+ private FilterableSortableBindingList bindingList;
+
/// Number of visible rows has changed
public event EventHandler VisibleCountChanged;
@@ -53,8 +60,14 @@ namespace LibationWinForms
EnableDoubleBuffering();
_dataGridView.CellContentClick += DataGridView_CellContentClick;
+ _dataGridView.Scroll += (_, s) => Scroll?.Invoke(this, s);
- this.Load += ProductsGrid_Load;
+ Load += ProductsGrid_Load;
+ }
+
+ private void ProductsGrid_Scroll(object sender, ScrollEventArgs e)
+ {
+ throw new NotImplementedException();
}
private void EnableDoubleBuffering()
@@ -66,117 +79,70 @@ namespace LibationWinForms
#region Button controls
- private async void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
+ private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// handle grid button click: https://stackoverflow.com/a/13687844
if (e.RowIndex < 0)
return;
- if (e.ColumnIndex == liberateGVColumn.Index)
- Liberate_Click(getGridEntry(e.RowIndex));
- else if (e.ColumnIndex == tagAndDetailsGVColumn.Index)
- Details_Click(getGridEntry(e.RowIndex));
- else if (e.ColumnIndex == descriptionGVColumn.Index)
- Description_Click(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
- else if (e.ColumnIndex == coverGVColumn.Index)
- await Cover_Click(getGridEntry(e.RowIndex));
- }
-
- private ImageDisplay imageDisplay;
- private async Task Cover_Click(GridEntry liveGridEntry)
- {
- var picDefinition = new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureLarge ?? liveGridEntry.LibraryBook.Book.PictureId, PictureSize.Native);
- var picDlTask = Task.Run(() => PictureStorage.GetPictureSynchronously(picDefinition));
-
- (_, byte[] initialImageBts) = PictureStorage.GetPicture(new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureId, PictureSize._80x80));
- var windowTitle = $"{liveGridEntry.Title} - Cover";
-
- if (imageDisplay is null || imageDisplay.IsDisposed || !imageDisplay.Visible)
+ var entry = getGridEntry(e.RowIndex);
+ if (entry is LibraryBookEntry lbEntry)
{
- imageDisplay = new ImageDisplay();
- imageDisplay.RestoreSizeAndLocation(Configuration.Instance);
- imageDisplay.FormClosed += (_, _) => imageDisplay.SaveSizeAndLocation(Configuration.Instance);
- imageDisplay.Show(this);
+ if (e.ColumnIndex == liberateGVColumn.Index)
+ LiberateClicked?.Invoke(e, lbEntry);
+ else if (e.ColumnIndex == tagAndDetailsGVColumn.Index && entry is LibraryBookEntry)
+ DetailsClicked?.Invoke(e, lbEntry);
+ else if (e.ColumnIndex == descriptionGVColumn.Index)
+ DescriptionClicked?.Invoke(e, lbEntry, _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
+ else if (e.ColumnIndex == coverGVColumn.Index)
+ CoverClicked?.Invoke(e, lbEntry);
}
-
- imageDisplay.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(liveGridEntry.LibraryBook);
- imageDisplay.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(liveGridEntry.LibraryBook, ".jpg"));
- imageDisplay.Text = windowTitle;
- imageDisplay.CoverPicture = initialImageBts;
- imageDisplay.CoverPicture = await picDlTask;
- }
-
- private void Description_Click(GridEntry liveGridEntry, Rectangle cellDisplay)
- {
- var displayWindow = new DescriptionDisplay
+ else if (entry is SeriesEntry sEntry && e.ColumnIndex == liberateGVColumn.Index)
{
- SpawnLocation = PointToScreen(cellDisplay.Location + new Size(cellDisplay.Width, 0)),
- DescriptionText = liveGridEntry.LongDescription,
- BorderThickness = 2,
- };
+ if (sEntry.Liberate.Expanded)
+ bindingList.CollapseItem(sEntry);
+ else
+ bindingList.ExpandItem(sEntry);
- void CloseWindow(object o, EventArgs e)
- {
- displayWindow.Close();
+ sEntry.NotifyPropertyChanged(nameof(sEntry.Liberate));
}
-
- _dataGridView.Scroll += CloseWindow;
- displayWindow.FormClosed += (_, _) => _dataGridView.Scroll -= CloseWindow;
- displayWindow.Show(this);
}
- private void Liberate_Click(GridEntry liveGridEntry)
- {
- LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
- }
-
- private static void Details_Click(GridEntry liveGridEntry)
- {
- var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
- if (bookDetailsForm.ShowDialog() == DialogResult.OK)
- liveGridEntry.Commit(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
- }
+ private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex);
#endregion
#region UI display functions
- private FilterableSortableBindingList bindingList;
-
- private bool hasBeenDisplayed;
- public event EventHandler InitialLoaded;
- public void Display()
+ internal void bindToGrid(List dbBooks)
{
- // don't return early if lib size == 0. this will not update correctly if all books are removed
- var lib = DbContexts.GetLibrary_Flat_NoTracking();
+ var geList = dbBooks.Where(b => b.Book.ContentType is not ContentType.Episode).Select(b => new LibraryBookEntry(b)).Cast().ToList();
- if (!hasBeenDisplayed)
+ var episodes = dbBooks.Where(b => b.Book.ContentType is ContentType.Episode).ToList();
+
+ var series = episodes.Select(lb => lb.Book.SeriesLink.First()).DistinctBy(s => s.Series).ToList();
+
+ foreach (var s in series)
{
- // bind
- bindToGrid(lib);
- hasBeenDisplayed = true;
- InitialLoaded?.Invoke(this, new());
- VisibleCountChanged?.Invoke(this, bindingList.Count);
+ var seriesEntry = new SeriesEntry();
+ seriesEntry.Children = episodes.Where(lb => lb.Book.SeriesLink.First().Series == s.Book.SeriesLink.First().Series).Select(lb => new LibraryBookEntry(lb) { Parent = seriesEntry }).Cast().ToList();
+
+ seriesEntry.setSeriesBook(s);
+ geList.Add(seriesEntry);
}
- else
- updateGrid(lib);
- }
-
- private void bindToGrid(List dbBooks)
- {
- bindingList = new FilterableSortableBindingList(dbBooks.OrderByDescending(lb => lb.DateAdded).Select(lb => new GridEntry(lb)));
+ bindingList = new FilterableSortableBindingList(geList.OrderByDescending(ge => ge.DateAdded));
gridEntryBindingSource.DataSource = bindingList;
}
- private void updateGrid(List dbBooks)
+ internal void updateGrid(List dbBooks)
{
int visibleCount = bindingList.Count;
string existingFilter = gridEntryBindingSource.Filter;
//Add absent books to grid, or update current books
- var allItmes = bindingList.AllItems();
+ var allItmes = bindingList.AllItems().Where(i => i is LibraryBookEntry).Cast();
for (var i = dbBooks.Count - 1; i >= 0; i--)
{
var libraryBook = dbBooks[i];
@@ -184,10 +150,37 @@ namespace LibationWinForms
// add new to top
if (existingItem is null)
- bindingList.Insert(0, new GridEntry(libraryBook));
+ {
+ var lb = new LibraryBookEntry(libraryBook);
+
+ if (libraryBook.Book.ContentType is ContentType.Episode)
+ {
+ //Find the series that libraryBook, if it exists
+ var series = bindingList.AllItems().Where(i => i is SeriesEntry).Cast().FirstOrDefault(i => libraryBook.Book.SeriesLink.Any(s => s.Series.Name == i.Series));
+
+ if (series is null)
+ {
+ //Series doesn't exist yet, so create and add it
+ var newSeries = new SeriesEntry { Children = new List { lb } };
+ newSeries.setSeriesBook(libraryBook.Book.SeriesLink.First());
+ lb.Parent = newSeries;
+ newSeries.Liberate.Expanded = true;
+ bindingList.Insert(0, newSeries);
+ }
+ else
+ {
+ lb.Parent = series;
+ series.Children.Add(lb);
+ }
+ }
+ //Add the new product
+ bindingList.Insert(0, lb);
+ }
// update existing
else
+ {
existingItem.UpdateLibraryBook(libraryBook);
+ }
}
if (bindingList.Count != visibleCount)
@@ -199,13 +192,22 @@ namespace LibationWinForms
// remove deleted from grid.
// note: actual deletion from db must still occur via the RemoveBook feature. deleting from audible will not trigger this
- var removedBooks =
+ var removedBooks =
bindingList
.AllItems()
- .ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId)
- .ToList();
+ .Where(i => i is LibraryBookEntry)
+ .Cast()
+ .ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId);
- foreach (var removed in removedBooks)
+ //Remove series that have no children
+ var removedSeries =
+ bindingList
+ .AllItems()
+ .Where(i => i is SeriesEntry)
+ .Cast()
+ .Where(i => removedBooks.Count(r => r.Series == i.Series) == i.Children.Count);
+
+ foreach (var removed in removedBooks.Cast().Concat(removedSeries))
//no need to re-filter for removed books
bindingList.Remove(removed);
@@ -232,12 +234,11 @@ namespace LibationWinForms
#endregion
- internal List GetVisible()
+ internal IEnumerable GetVisible()
=> bindingList
- .Select(row => row.LibraryBook)
- .ToList();
-
- private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex);
+ .Where(row => row is LibraryBookEntry)
+ .Cast()
+ .Select(row => row.LibraryBook);
#region Column Customizations
@@ -293,8 +294,6 @@ namespace LibationWinForms
column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index);
}
-
- base.OnVisibleChanged(e);
}
private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/grid/ProductsGrid.resx
index 8a560af5..be5db7af 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.resx
+++ b/Source/LibationWinForms/grid/ProductsGrid.resx
@@ -57,12 +57,6 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 17, 17
-
-
- 197, 17
-
81
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/grid/SeriesEntry.cs
new file mode 100644
index 00000000..6a1e51b8
--- /dev/null
+++ b/Source/LibationWinForms/grid/SeriesEntry.cs
@@ -0,0 +1,90 @@
+using DataLayer;
+using Dinah.Core;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibationWinForms
+{
+ internal class SeriesEntry : GridEntry
+ {
+ public override DateTime DateAdded => Children.Max(c => c.DateAdded);
+ public override string ProductRating { get; protected set; }
+ public override string PurchaseDate { get; protected set; }
+ public override string MyRating { get; protected set; }
+ public override string Series { get; protected set; }
+ public override string Title { get; protected set; }
+ public override string Length { get; protected set; }
+ public override string Authors { get; protected set; }
+ public override string Narrators { get; protected set; }
+ public override string Category { get; protected set; }
+ public override string Misc { get; protected set; }
+ public override string Description { get; protected set; }
+ public override string DisplayTags => string.Empty;
+
+ public override LiberateStatus Liberate => _liberate;
+
+ protected override Book Book => SeriesBook.Book;
+
+ private SeriesBook SeriesBook { get; set; }
+
+ private LiberateStatus _liberate = new LiberateStatus { IsSeries = true };
+ public void setSeriesBook(SeriesBook seriesBook)
+ {
+ SeriesBook = seriesBook;
+ _memberValues = CreateMemberValueDictionary();
+ LoadCover();
+
+ // Immutable properties
+ {
+ var childLB = Children.Cast();
+ int bookLenMins = childLB.Sum(c => c.LibraryBook.Book.LengthInMinutes);
+
+ var myAverageRating = new Rating(childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
+ var productAverageRating = new Rating(childLB.Average(c => c.LibraryBook.Book.Rating.OverallRating), childLB.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), childLB.Average(c => c.LibraryBook.Book.Rating.StoryRating));
+
+
+ Title = SeriesBook.Series.Name;
+ Series = SeriesBook.Series.Name;
+ Length = bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
+ MyRating = myAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ PurchaseDate = childLB.Min(c => c.LibraryBook.DateAdded).ToString("d");
+ ProductRating = productAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ Authors = Book.AuthorNames();
+ Narrators = Book.NarratorNames();
+ Category = string.Join(" > ", Book.CategoriesNames());
+ }
+ }
+
+ // These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
+ // Used by Dinah.Core.DataBinding.SortableBindingList for all sorting
+ public override object GetMemberValue(string memberName) => _memberValues[memberName]();
+
+ private Dictionary> _memberValues { get; set; }
+
+ ///
+ /// Create getters for all member object values by name
+ ///
+ private Dictionary> CreateMemberValueDictionary() => new()
+ {
+ { nameof(Title), () => Book.SeriesSortable() },
+ { nameof(Series), () => Book.SeriesSortable() },
+ { nameof(Length), () => Children.Cast().Sum(c=>c.LibraryBook.Book.LengthInMinutes) },
+ { nameof(MyRating), () => Children.Cast().Average(c=>c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
+ { nameof(PurchaseDate), () => Children.Cast().Min(c=>c.LibraryBook.DateAdded) },
+ { nameof(ProductRating), () => Children.Cast().Average(c => c.LibraryBook.Book.Rating.FirstScore()) },
+ { nameof(Authors), () => string.Empty },
+ { nameof(Narrators), () => string.Empty },
+ { nameof(Description), () => string.Empty },
+ { nameof(Category), () => string.Empty },
+ { nameof(Misc), () => string.Empty },
+ { nameof(DisplayTags), () => string.Empty },
+ { nameof(Liberate), () => Liberate.BookStatus },
+ { nameof(DateAdded), () => DateAdded },
+ };
+ }
+}
diff --git a/Source/LibationWinForms/grid/SortableBindingList1.cs b/Source/LibationWinForms/grid/SortableBindingList1.cs
new file mode 100644
index 00000000..7d12819f
--- /dev/null
+++ b/Source/LibationWinForms/grid/SortableBindingList1.cs
@@ -0,0 +1,111 @@
+using Dinah.Core.DataBinding;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LibationWinForms
+{
+ internal class SortableBindingList1 : BindingList where T : class, IMemberComparable, IHierarchical
+ {
+ private bool isSorted;
+ private ListSortDirection listSortDirection;
+ private PropertyDescriptor propertyDescriptor;
+
+ public SortableBindingList1() : base(new List()) { }
+ public SortableBindingList1(IEnumerable enumeration) : base(new List(enumeration)) { }
+
+ protected MemberComparer Comparer { get; } = new();
+ protected override bool SupportsSortingCore => true;
+ protected override bool SupportsSearchingCore => true;
+ protected override bool IsSortedCore => isSorted;
+ protected override PropertyDescriptor SortPropertyCore => propertyDescriptor;
+ protected override ListSortDirection SortDirectionCore => listSortDirection;
+
+ protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
+ {
+ Comparer.PropertyName = property.Name;
+ Comparer.Direction = direction;
+
+ Sort();
+
+ propertyDescriptor = property;
+ listSortDirection = direction;
+ isSorted = true;
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+ }
+
+ protected void Sort()
+ {
+ List itemsList = (List)Items;
+
+ //Array.Sort() and List.Sort() are unstable sorts. OrderBy is stable.
+ var sortedItems = itemsList.OrderBy((ge) => ge, Comparer).ToList();
+
+ var children = sortedItems.Where(i => i.Parent is not null).ToList();
+ var parents = sortedItems.Where(i => i.Children is not null).ToList();
+
+ //Top Level items
+ var topLevelItems = sortedItems.Except(children);
+
+ itemsList.Clear();
+ itemsList.AddRange(topLevelItems);
+
+ foreach (var p in parents)
+ {
+ var pIndex = itemsList.IndexOf(p);
+ foreach (var c in children.Where(c=> c.Parent == p))
+ itemsList.Insert(++pIndex, c);
+ }
+ }
+
+ protected override void OnListChanged(ListChangedEventArgs e)
+ {
+ if (isSorted &&
+ ((e.ListChangedType == ListChangedType.ItemChanged && e.PropertyDescriptor == SortPropertyCore) ||
+ e.ListChangedType == ListChangedType.ItemAdded))
+ {
+ var item = Items[e.NewIndex];
+ Sort();
+ var newIndex = Items.IndexOf(item);
+
+ base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
+ }
+ else
+ base.OnListChanged(e);
+ }
+
+ protected override void RemoveSortCore()
+ {
+ isSorted = false;
+ propertyDescriptor = base.SortPropertyCore;
+ listSortDirection = base.SortDirectionCore;
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+ }
+
+ protected override int FindCore(PropertyDescriptor property, object key)
+ {
+ int count = Count;
+
+ System.Collections.IComparer valueComparer = null;
+
+ for (int i = 0; i < count; ++i)
+ {
+ var element = this[i];
+ var elemValue = element.GetMemberValue(property.Name);
+ valueComparer ??= element.GetMemberComparer(elemValue.GetType());
+
+ if (valueComparer.Compare(elemValue, key) == 0)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+ }
+}
From 593fe57ea1c35a3b20107d6111b8fbe444aed5fd Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 15:29:26 -0600
Subject: [PATCH 03/15] Refactor ProductsGrid
---
Source/LibationWinForms/Form1.Designer.cs | 939 +++++++++---------
Source/LibationWinForms/Form1.Filter.cs | 2 +-
Source/LibationWinForms/Form1.ProcessQueue.cs | 3 +-
Source/LibationWinForms/Form1.QuickFilters.cs | 12 +-
Source/LibationWinForms/Form1.VisibleBooks.cs | 37 +-
Source/LibationWinForms/Form1.cs | 18 +-
.../LibationWinForms/LibationWinForms.csproj | 6 -
.../EditTagsDataGridViewImageButtonColumn.cs | 9 +-
.../grid/FilterableSortableBindingList.cs | 99 +-
Source/LibationWinForms/grid/GridEntry.cs | 42 +-
.../LibationWinForms/grid/LibraryBookEntry.cs | 4 +-
.../grid/MasterDataGridView.cs | 26 -
.../grid/ProductsDisplay.Designer.cs | 19 +
.../LibationWinForms/grid/ProductsDisplay.cs | 69 +-
.../grid/ProductsGrid.Designer.cs | 48 +-
Source/LibationWinForms/grid/ProductsGrid.cs | 205 ++--
.../LibationWinForms/grid/ProductsGrid.resx | 4 +-
Source/LibationWinForms/grid/SeriesEntry.cs | 22 +-
.../grid/SortableBindingList1.cs | 41 +-
19 files changed, 768 insertions(+), 837 deletions(-)
delete mode 100644 Source/LibationWinForms/grid/MasterDataGridView.cs
diff --git a/Source/LibationWinForms/Form1.Designer.cs b/Source/LibationWinForms/Form1.Designer.cs
index 1f554c16..98a7b9f7 100644
--- a/Source/LibationWinForms/Form1.Designer.cs
+++ b/Source/LibationWinForms/Form1.Designer.cs
@@ -28,111 +28,100 @@
///
private void InitializeComponent()
{
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
- this.gridPanel = new System.Windows.Forms.Panel();
- this.filterHelpBtn = new System.Windows.Forms.Button();
- this.filterBtn = new System.Windows.Forms.Button();
- this.filterSearchTb = new System.Windows.Forms.TextBox();
- this.menuStrip1 = new System.Windows.Forms.MenuStrip();
- this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.autoScanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.noAccountsYetAddAccountToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.scanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.scanLibraryOfAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.scanLibraryOfSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.removeLibraryBooksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.beginBookBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
- this.beginPdfBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
- this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.liberateVisible2ToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
- this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.firstFilterIsDefaultToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
- this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.visibleBooksToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
- this.liberateVisibleToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
- this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.accountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.basicSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
- this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.statusStrip1 = new System.Windows.Forms.StatusStrip();
- this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel();
- this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
- this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
- this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel();
- this.addQuickFilterBtn = new System.Windows.Forms.Button();
- this.splitContainer1 = new System.Windows.Forms.SplitContainer();
- this.panel1 = new System.Windows.Forms.Panel();
- this.toggleQueueHideBtn = new System.Windows.Forms.Button();
- this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl();
- this.menuStrip1.SuspendLayout();
- this.statusStrip1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
- this.splitContainer1.Panel1.SuspendLayout();
- this.splitContainer1.Panel2.SuspendLayout();
- this.splitContainer1.SuspendLayout();
- this.panel1.SuspendLayout();
- this.SuspendLayout();
- //
- // gridPanel
- //
- this.gridPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
- | System.Windows.Forms.AnchorStyles.Left)
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
+ this.filterHelpBtn = new System.Windows.Forms.Button();
+ this.filterBtn = new System.Windows.Forms.Button();
+ this.filterSearchTb = new System.Windows.Forms.TextBox();
+ this.menuStrip1 = new System.Windows.Forms.MenuStrip();
+ this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.autoScanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.noAccountsYetAddAccountToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.scanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.scanLibraryOfAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.scanLibraryOfSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeLibraryBooksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.beginBookBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
+ this.beginPdfBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
+ this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.liberateVisible2ToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
+ this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.firstFilterIsDefaultToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+ this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.visibleBooksToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
+ this.liberateVisibleToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
+ this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.accountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.basicSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
+ this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.statusStrip1 = new System.Windows.Forms.StatusStrip();
+ this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel();
+ this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
+ this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
+ this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel();
+ this.addQuickFilterBtn = new System.Windows.Forms.Button();
+ this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.productsDisplay = new LibationWinForms.ProductsDisplay();
+ this.toggleQueueHideBtn = new System.Windows.Forms.Button();
+ this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl();
+ this.menuStrip1.SuspendLayout();
+ this.statusStrip1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+ this.splitContainer1.Panel1.SuspendLayout();
+ this.splitContainer1.Panel2.SuspendLayout();
+ this.splitContainer1.SuspendLayout();
+ this.panel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // filterHelpBtn
+ //
+ this.filterHelpBtn.Location = new System.Drawing.Point(15, 3);
+ this.filterHelpBtn.Margin = new System.Windows.Forms.Padding(15, 3, 4, 3);
+ this.filterHelpBtn.Name = "filterHelpBtn";
+ this.filterHelpBtn.Size = new System.Drawing.Size(26, 27);
+ this.filterHelpBtn.TabIndex = 3;
+ this.filterHelpBtn.Text = "?";
+ this.filterHelpBtn.UseVisualStyleBackColor = true;
+ this.filterHelpBtn.Click += new System.EventHandler(this.filterHelpBtn_Click);
+ //
+ // filterBtn
+ //
+ this.filterBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.filterBtn.Location = new System.Drawing.Point(748, 3);
+ this.filterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.filterBtn.Name = "filterBtn";
+ this.filterBtn.Size = new System.Drawing.Size(88, 27);
+ this.filterBtn.TabIndex = 2;
+ this.filterBtn.Text = "Filter";
+ this.filterBtn.UseVisualStyleBackColor = true;
+ this.filterBtn.Click += new System.EventHandler(this.filterBtn_Click);
+ //
+ // filterSearchTb
+ //
+ this.filterSearchTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.gridPanel.Location = new System.Drawing.Point(15, 33);
- this.gridPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
- this.gridPanel.Name = "gridPanel";
- this.gridPanel.Size = new System.Drawing.Size(864, 558);
- this.gridPanel.TabIndex = 5;
- //
- // filterHelpBtn
- //
- this.filterHelpBtn.Location = new System.Drawing.Point(15, 3);
- this.filterHelpBtn.Margin = new System.Windows.Forms.Padding(15, 3, 4, 3);
- this.filterHelpBtn.Name = "filterHelpBtn";
- this.filterHelpBtn.Size = new System.Drawing.Size(26, 27);
- this.filterHelpBtn.TabIndex = 3;
- this.filterHelpBtn.Text = "?";
- this.filterHelpBtn.UseVisualStyleBackColor = true;
- this.filterHelpBtn.Click += new System.EventHandler(this.filterHelpBtn_Click);
- //
- // filterBtn
- //
- this.filterBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.filterBtn.Location = new System.Drawing.Point(748, 3);
- this.filterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
- this.filterBtn.Name = "filterBtn";
- this.filterBtn.Size = new System.Drawing.Size(88, 27);
- this.filterBtn.TabIndex = 2;
- this.filterBtn.Text = "Filter";
- this.filterBtn.UseVisualStyleBackColor = true;
- this.filterBtn.Click += new System.EventHandler(this.filterBtn_Click);
- //
- // filterSearchTb
- //
- this.filterSearchTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
- | System.Windows.Forms.AnchorStyles.Right)));
- this.filterSearchTb.Location = new System.Drawing.Point(196, 7);
- this.filterSearchTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
- this.filterSearchTb.Name = "filterSearchTb";
- this.filterSearchTb.Size = new System.Drawing.Size(544, 23);
- this.filterSearchTb.TabIndex = 1;
- this.filterSearchTb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filterSearchTb_KeyPress);
- //
- // menuStrip1
- //
- this.menuStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
- this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.filterSearchTb.Location = new System.Drawing.Point(196, 7);
+ this.filterSearchTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.filterSearchTb.Name = "filterSearchTb";
+ this.filterSearchTb.Size = new System.Drawing.Size(544, 23);
+ this.filterSearchTb.TabIndex = 1;
+ this.filterSearchTb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filterSearchTb_KeyPress);
+ //
+ // menuStrip1
+ //
+ this.menuStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
+ this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.importToolStripMenuItem,
this.liberateToolStripMenuItem,
this.exportToolStripMenuItem,
@@ -140,402 +129,415 @@
this.scanningToolStripMenuItem,
this.visibleBooksToolStripMenuItem,
this.settingsToolStripMenuItem});
- this.menuStrip1.Location = new System.Drawing.Point(0, 0);
- this.menuStrip1.Name = "menuStrip1";
- this.menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2);
- this.menuStrip1.Size = new System.Drawing.Size(893, 24);
- this.menuStrip1.TabIndex = 0;
- this.menuStrip1.Text = "menuStrip1";
- //
- // importToolStripMenuItem
- //
- this.importToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.menuStrip1.Location = new System.Drawing.Point(0, 0);
+ this.menuStrip1.Name = "menuStrip1";
+ this.menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2);
+ this.menuStrip1.Size = new System.Drawing.Size(893, 24);
+ this.menuStrip1.TabIndex = 0;
+ this.menuStrip1.Text = "menuStrip1";
+ //
+ // importToolStripMenuItem
+ //
+ this.importToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.autoScanLibraryToolStripMenuItem,
this.noAccountsYetAddAccountToolStripMenuItem,
this.scanLibraryToolStripMenuItem,
this.scanLibraryOfAllAccountsToolStripMenuItem,
this.scanLibraryOfSomeAccountsToolStripMenuItem,
this.removeLibraryBooksToolStripMenuItem});
- this.importToolStripMenuItem.Name = "importToolStripMenuItem";
- this.importToolStripMenuItem.Size = new System.Drawing.Size(55, 20);
- this.importToolStripMenuItem.Text = "&Import";
- //
- // autoScanLibraryToolStripMenuItem
- //
- this.autoScanLibraryToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
- this.autoScanLibraryToolStripMenuItem.Name = "autoScanLibraryToolStripMenuItem";
- this.autoScanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.autoScanLibraryToolStripMenuItem.Text = "A&uto Scan Library";
- this.autoScanLibraryToolStripMenuItem.Click += new System.EventHandler(this.autoScanLibraryToolStripMenuItem_Click);
- //
- // noAccountsYetAddAccountToolStripMenuItem
- //
- this.noAccountsYetAddAccountToolStripMenuItem.Name = "noAccountsYetAddAccountToolStripMenuItem";
- this.noAccountsYetAddAccountToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.noAccountsYetAddAccountToolStripMenuItem.Text = "No accounts yet. A&dd Account...";
- this.noAccountsYetAddAccountToolStripMenuItem.Click += new System.EventHandler(this.noAccountsYetAddAccountToolStripMenuItem_Click);
- //
- // scanLibraryToolStripMenuItem
- //
- this.scanLibraryToolStripMenuItem.Name = "scanLibraryToolStripMenuItem";
- this.scanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.scanLibraryToolStripMenuItem.Text = "Scan &Library";
- this.scanLibraryToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryToolStripMenuItem_Click);
- //
- // scanLibraryOfAllAccountsToolStripMenuItem
- //
- this.scanLibraryOfAllAccountsToolStripMenuItem.Name = "scanLibraryOfAllAccountsToolStripMenuItem";
- this.scanLibraryOfAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.scanLibraryOfAllAccountsToolStripMenuItem.Text = "Scan Library of &All Accounts";
- this.scanLibraryOfAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfAllAccountsToolStripMenuItem_Click);
- //
- // scanLibraryOfSomeAccountsToolStripMenuItem
- //
- this.scanLibraryOfSomeAccountsToolStripMenuItem.Name = "scanLibraryOfSomeAccountsToolStripMenuItem";
- this.scanLibraryOfSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.scanLibraryOfSomeAccountsToolStripMenuItem.Text = "Scan Library of &Some Accounts...";
- this.scanLibraryOfSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfSomeAccountsToolStripMenuItem_Click);
- //
- // removeLibraryBooksToolStripMenuItem
- //
- this.removeLibraryBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.importToolStripMenuItem.Name = "importToolStripMenuItem";
+ this.importToolStripMenuItem.Size = new System.Drawing.Size(55, 20);
+ this.importToolStripMenuItem.Text = "&Import";
+ //
+ // autoScanLibraryToolStripMenuItem
+ //
+ this.autoScanLibraryToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.autoScanLibraryToolStripMenuItem.Name = "autoScanLibraryToolStripMenuItem";
+ this.autoScanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.autoScanLibraryToolStripMenuItem.Text = "A&uto Scan Library";
+ this.autoScanLibraryToolStripMenuItem.Click += new System.EventHandler(this.autoScanLibraryToolStripMenuItem_Click);
+ //
+ // noAccountsYetAddAccountToolStripMenuItem
+ //
+ this.noAccountsYetAddAccountToolStripMenuItem.Name = "noAccountsYetAddAccountToolStripMenuItem";
+ this.noAccountsYetAddAccountToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.noAccountsYetAddAccountToolStripMenuItem.Text = "No accounts yet. A&dd Account...";
+ this.noAccountsYetAddAccountToolStripMenuItem.Click += new System.EventHandler(this.noAccountsYetAddAccountToolStripMenuItem_Click);
+ //
+ // scanLibraryToolStripMenuItem
+ //
+ this.scanLibraryToolStripMenuItem.Name = "scanLibraryToolStripMenuItem";
+ this.scanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.scanLibraryToolStripMenuItem.Text = "Scan &Library";
+ this.scanLibraryToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryToolStripMenuItem_Click);
+ //
+ // scanLibraryOfAllAccountsToolStripMenuItem
+ //
+ this.scanLibraryOfAllAccountsToolStripMenuItem.Name = "scanLibraryOfAllAccountsToolStripMenuItem";
+ this.scanLibraryOfAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.scanLibraryOfAllAccountsToolStripMenuItem.Text = "Scan Library of &All Accounts";
+ this.scanLibraryOfAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfAllAccountsToolStripMenuItem_Click);
+ //
+ // scanLibraryOfSomeAccountsToolStripMenuItem
+ //
+ this.scanLibraryOfSomeAccountsToolStripMenuItem.Name = "scanLibraryOfSomeAccountsToolStripMenuItem";
+ this.scanLibraryOfSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.scanLibraryOfSomeAccountsToolStripMenuItem.Text = "Scan Library of &Some Accounts...";
+ this.scanLibraryOfSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfSomeAccountsToolStripMenuItem_Click);
+ //
+ // removeLibraryBooksToolStripMenuItem
+ //
+ this.removeLibraryBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.removeAllAccountsToolStripMenuItem,
this.removeSomeAccountsToolStripMenuItem});
- this.removeLibraryBooksToolStripMenuItem.Name = "removeLibraryBooksToolStripMenuItem";
- this.removeLibraryBooksToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
- this.removeLibraryBooksToolStripMenuItem.Text = "Remove Library Books";
- this.removeLibraryBooksToolStripMenuItem.Click += new System.EventHandler(this.removeLibraryBooksToolStripMenuItem_Click);
- //
- // removeAllAccountsToolStripMenuItem
- //
- this.removeAllAccountsToolStripMenuItem.Name = "removeAllAccountsToolStripMenuItem";
- this.removeAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
- this.removeAllAccountsToolStripMenuItem.Text = "All Accounts";
- this.removeAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeAllAccountsToolStripMenuItem_Click);
- //
- // removeSomeAccountsToolStripMenuItem
- //
- this.removeSomeAccountsToolStripMenuItem.Name = "removeSomeAccountsToolStripMenuItem";
- this.removeSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
- this.removeSomeAccountsToolStripMenuItem.Text = "Some Accounts";
- this.removeSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeSomeAccountsToolStripMenuItem_Click);
- //
- // liberateToolStripMenuItem
- //
- this.liberateToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.removeLibraryBooksToolStripMenuItem.Name = "removeLibraryBooksToolStripMenuItem";
+ this.removeLibraryBooksToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
+ this.removeLibraryBooksToolStripMenuItem.Text = "Remove Library Books";
+ this.removeLibraryBooksToolStripMenuItem.Click += new System.EventHandler(this.removeLibraryBooksToolStripMenuItem_Click);
+ //
+ // removeAllAccountsToolStripMenuItem
+ //
+ this.removeAllAccountsToolStripMenuItem.Name = "removeAllAccountsToolStripMenuItem";
+ this.removeAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
+ this.removeAllAccountsToolStripMenuItem.Text = "All Accounts";
+ this.removeAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeAllAccountsToolStripMenuItem_Click);
+ //
+ // removeSomeAccountsToolStripMenuItem
+ //
+ this.removeSomeAccountsToolStripMenuItem.Name = "removeSomeAccountsToolStripMenuItem";
+ this.removeSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
+ this.removeSomeAccountsToolStripMenuItem.Text = "Some Accounts";
+ this.removeSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeSomeAccountsToolStripMenuItem_Click);
+ //
+ // liberateToolStripMenuItem
+ //
+ this.liberateToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.beginBookBackupsToolStripMenuItem,
this.beginPdfBackupsToolStripMenuItem,
this.convertAllM4bToMp3ToolStripMenuItem,
this.liberateVisible2ToolStripMenuItem});
- this.liberateToolStripMenuItem.Name = "liberateToolStripMenuItem";
- this.liberateToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
- this.liberateToolStripMenuItem.Text = "&Liberate";
- //
- // beginBookBackupsToolStripMenuItem
- //
- this.beginBookBackupsToolStripMenuItem.FormatText = "Begin &Book and PDF Backups: {0}";
- this.beginBookBackupsToolStripMenuItem.Name = "beginBookBackupsToolStripMenuItem";
- this.beginBookBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
- this.beginBookBackupsToolStripMenuItem.Text = "Begin &Book and PDF Backups: {0}";
- this.beginBookBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginBookBackupsToolStripMenuItem_Click);
- //
- // beginPdfBackupsToolStripMenuItem
- //
- this.beginPdfBackupsToolStripMenuItem.FormatText = "Begin &PDF Only Backups: {0}";
- this.beginPdfBackupsToolStripMenuItem.Name = "beginPdfBackupsToolStripMenuItem";
- this.beginPdfBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
- this.beginPdfBackupsToolStripMenuItem.Text = "Begin &PDF Only Backups: {0}";
- this.beginPdfBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginPdfBackupsToolStripMenuItem_Click);
- //
- // convertAllM4bToMp3ToolStripMenuItem
- //
- this.convertAllM4bToMp3ToolStripMenuItem.Name = "convertAllM4bToMp3ToolStripMenuItem";
- this.convertAllM4bToMp3ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
- this.convertAllM4bToMp3ToolStripMenuItem.Text = "Convert all &M4b to Mp3 [Long-running]...";
- this.convertAllM4bToMp3ToolStripMenuItem.Click += new System.EventHandler(this.convertAllM4bToMp3ToolStripMenuItem_Click);
- //
- // liberateVisible2ToolStripMenuItem
- //
- this.liberateVisible2ToolStripMenuItem.FormatText = "Liberate &Visible Books: {0}";
- this.liberateVisible2ToolStripMenuItem.Name = "liberateVisible2ToolStripMenuItem";
- this.liberateVisible2ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
- this.liberateVisible2ToolStripMenuItem.Text = "Liberate &Visible Books: {0}";
- this.liberateVisible2ToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
- //
- // exportToolStripMenuItem
- //
- this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.liberateToolStripMenuItem.Name = "liberateToolStripMenuItem";
+ this.liberateToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
+ this.liberateToolStripMenuItem.Text = "&Liberate";
+ //
+ // beginBookBackupsToolStripMenuItem
+ //
+ this.beginBookBackupsToolStripMenuItem.FormatText = "Begin &Book and PDF Backups: {0}";
+ this.beginBookBackupsToolStripMenuItem.Name = "beginBookBackupsToolStripMenuItem";
+ this.beginBookBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
+ this.beginBookBackupsToolStripMenuItem.Text = "Begin &Book and PDF Backups: {0}";
+ this.beginBookBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginBookBackupsToolStripMenuItem_Click);
+ //
+ // beginPdfBackupsToolStripMenuItem
+ //
+ this.beginPdfBackupsToolStripMenuItem.FormatText = "Begin &PDF Only Backups: {0}";
+ this.beginPdfBackupsToolStripMenuItem.Name = "beginPdfBackupsToolStripMenuItem";
+ this.beginPdfBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
+ this.beginPdfBackupsToolStripMenuItem.Text = "Begin &PDF Only Backups: {0}";
+ this.beginPdfBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginPdfBackupsToolStripMenuItem_Click);
+ //
+ // convertAllM4bToMp3ToolStripMenuItem
+ //
+ this.convertAllM4bToMp3ToolStripMenuItem.Name = "convertAllM4bToMp3ToolStripMenuItem";
+ this.convertAllM4bToMp3ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
+ this.convertAllM4bToMp3ToolStripMenuItem.Text = "Convert all &M4b to Mp3 [Long-running]...";
+ this.convertAllM4bToMp3ToolStripMenuItem.Click += new System.EventHandler(this.convertAllM4bToMp3ToolStripMenuItem_Click);
+ //
+ // liberateVisible2ToolStripMenuItem
+ //
+ this.liberateVisible2ToolStripMenuItem.FormatText = "Liberate &Visible Books: {0}";
+ this.liberateVisible2ToolStripMenuItem.Name = "liberateVisible2ToolStripMenuItem";
+ this.liberateVisible2ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
+ this.liberateVisible2ToolStripMenuItem.Text = "Liberate &Visible Books: {0}";
+ this.liberateVisible2ToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
+ //
+ // exportToolStripMenuItem
+ //
+ this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.exportLibraryToolStripMenuItem});
- this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
- this.exportToolStripMenuItem.Size = new System.Drawing.Size(53, 20);
- this.exportToolStripMenuItem.Text = "E&xport";
- //
- // exportLibraryToolStripMenuItem
- //
- this.exportLibraryToolStripMenuItem.Name = "exportLibraryToolStripMenuItem";
- this.exportLibraryToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
- this.exportLibraryToolStripMenuItem.Text = "E&xport Library...";
- this.exportLibraryToolStripMenuItem.Click += new System.EventHandler(this.exportLibraryToolStripMenuItem_Click);
- //
- // quickFiltersToolStripMenuItem
- //
- this.quickFiltersToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
+ this.exportToolStripMenuItem.Size = new System.Drawing.Size(53, 20);
+ this.exportToolStripMenuItem.Text = "E&xport";
+ //
+ // exportLibraryToolStripMenuItem
+ //
+ this.exportLibraryToolStripMenuItem.Name = "exportLibraryToolStripMenuItem";
+ this.exportLibraryToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
+ this.exportLibraryToolStripMenuItem.Text = "E&xport Library...";
+ this.exportLibraryToolStripMenuItem.Click += new System.EventHandler(this.exportLibraryToolStripMenuItem_Click);
+ //
+ // quickFiltersToolStripMenuItem
+ //
+ this.quickFiltersToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.firstFilterIsDefaultToolStripMenuItem,
this.editQuickFiltersToolStripMenuItem,
this.toolStripSeparator1});
- this.quickFiltersToolStripMenuItem.Name = "quickFiltersToolStripMenuItem";
- this.quickFiltersToolStripMenuItem.Size = new System.Drawing.Size(84, 20);
- this.quickFiltersToolStripMenuItem.Text = "Quick &Filters";
- //
- // firstFilterIsDefaultToolStripMenuItem
- //
- this.firstFilterIsDefaultToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
- this.firstFilterIsDefaultToolStripMenuItem.Name = "firstFilterIsDefaultToolStripMenuItem";
- this.firstFilterIsDefaultToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
- this.firstFilterIsDefaultToolStripMenuItem.Text = "Start Libation with 1st filter &Default";
- this.firstFilterIsDefaultToolStripMenuItem.Click += new System.EventHandler(this.firstFilterIsDefaultToolStripMenuItem_Click);
- //
- // editQuickFiltersToolStripMenuItem
- //
- this.editQuickFiltersToolStripMenuItem.Name = "editQuickFiltersToolStripMenuItem";
- this.editQuickFiltersToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
- this.editQuickFiltersToolStripMenuItem.Text = "&Edit quick filters...";
- this.editQuickFiltersToolStripMenuItem.Click += new System.EventHandler(this.editQuickFiltersToolStripMenuItem_Click);
- //
- // toolStripSeparator1
- //
- this.toolStripSeparator1.Name = "toolStripSeparator1";
- this.toolStripSeparator1.Size = new System.Drawing.Size(253, 6);
- //
- // scanningToolStripMenuItem
- //
- this.scanningToolStripMenuItem.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
- this.scanningToolStripMenuItem.Enabled = false;
- this.scanningToolStripMenuItem.Image = global::LibationWinForms.Properties.Resources.import_16x16;
- this.scanningToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
- this.scanningToolStripMenuItem.Name = "scanningToolStripMenuItem";
- this.scanningToolStripMenuItem.Size = new System.Drawing.Size(93, 20);
- this.scanningToolStripMenuItem.Text = "Scanning...";
- this.scanningToolStripMenuItem.Visible = false;
- //
- // visibleBooksToolStripMenuItem
- //
- this.visibleBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.quickFiltersToolStripMenuItem.Name = "quickFiltersToolStripMenuItem";
+ this.quickFiltersToolStripMenuItem.Size = new System.Drawing.Size(84, 20);
+ this.quickFiltersToolStripMenuItem.Text = "Quick &Filters";
+ //
+ // firstFilterIsDefaultToolStripMenuItem
+ //
+ this.firstFilterIsDefaultToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.firstFilterIsDefaultToolStripMenuItem.Name = "firstFilterIsDefaultToolStripMenuItem";
+ this.firstFilterIsDefaultToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+ this.firstFilterIsDefaultToolStripMenuItem.Text = "Start Libation with 1st filter &Default";
+ this.firstFilterIsDefaultToolStripMenuItem.Click += new System.EventHandler(this.firstFilterIsDefaultToolStripMenuItem_Click);
+ //
+ // editQuickFiltersToolStripMenuItem
+ //
+ this.editQuickFiltersToolStripMenuItem.Name = "editQuickFiltersToolStripMenuItem";
+ this.editQuickFiltersToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
+ this.editQuickFiltersToolStripMenuItem.Text = "&Edit quick filters...";
+ this.editQuickFiltersToolStripMenuItem.Click += new System.EventHandler(this.editQuickFiltersToolStripMenuItem_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ this.toolStripSeparator1.Size = new System.Drawing.Size(253, 6);
+ //
+ // scanningToolStripMenuItem
+ //
+ this.scanningToolStripMenuItem.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.scanningToolStripMenuItem.Enabled = false;
+ this.scanningToolStripMenuItem.Image = global::LibationWinForms.Properties.Resources.import_16x16;
+ this.scanningToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
+ this.scanningToolStripMenuItem.Name = "scanningToolStripMenuItem";
+ this.scanningToolStripMenuItem.Size = new System.Drawing.Size(93, 20);
+ this.scanningToolStripMenuItem.Text = "Scanning...";
+ this.scanningToolStripMenuItem.Visible = false;
+ //
+ // visibleBooksToolStripMenuItem
+ //
+ this.visibleBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.liberateVisibleToolStripMenuItem,
this.replaceTagsToolStripMenuItem,
this.setDownloadedToolStripMenuItem,
this.removeToolStripMenuItem});
- this.visibleBooksToolStripMenuItem.FormatText = "&Visible Books: {0}";
- this.visibleBooksToolStripMenuItem.Name = "visibleBooksToolStripMenuItem";
- this.visibleBooksToolStripMenuItem.Size = new System.Drawing.Size(108, 20);
- this.visibleBooksToolStripMenuItem.Text = "&Visible Books: {0}";
- //
- // liberateVisibleToolStripMenuItem
- //
- this.liberateVisibleToolStripMenuItem.FormatText = "&Liberate: {0}";
- this.liberateVisibleToolStripMenuItem.Name = "liberateVisibleToolStripMenuItem";
- this.liberateVisibleToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
- this.liberateVisibleToolStripMenuItem.Text = "&Liberate: {0}";
- this.liberateVisibleToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
- //
- // replaceTagsToolStripMenuItem
- //
- this.replaceTagsToolStripMenuItem.Name = "replaceTagsToolStripMenuItem";
- this.replaceTagsToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
- this.replaceTagsToolStripMenuItem.Text = "Replace &Tags...";
- this.replaceTagsToolStripMenuItem.Click += new System.EventHandler(this.replaceTagsToolStripMenuItem_Click);
- //
- // setDownloadedToolStripMenuItem
- //
- this.setDownloadedToolStripMenuItem.Name = "setDownloadedToolStripMenuItem";
- this.setDownloadedToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
- this.setDownloadedToolStripMenuItem.Text = "Set \'&Downloaded\' status...";
- this.setDownloadedToolStripMenuItem.Click += new System.EventHandler(this.setDownloadedToolStripMenuItem_Click);
- //
- // removeToolStripMenuItem
- //
- this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
- this.removeToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
- this.removeToolStripMenuItem.Text = "&Remove from library...";
- this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
- //
- // settingsToolStripMenuItem
- //
- this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.visibleBooksToolStripMenuItem.FormatText = "&Visible Books: {0}";
+ this.visibleBooksToolStripMenuItem.Name = "visibleBooksToolStripMenuItem";
+ this.visibleBooksToolStripMenuItem.Size = new System.Drawing.Size(108, 20);
+ this.visibleBooksToolStripMenuItem.Text = "&Visible Books: {0}";
+ //
+ // liberateVisibleToolStripMenuItem
+ //
+ this.liberateVisibleToolStripMenuItem.FormatText = "&Liberate: {0}";
+ this.liberateVisibleToolStripMenuItem.Name = "liberateVisibleToolStripMenuItem";
+ this.liberateVisibleToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.liberateVisibleToolStripMenuItem.Text = "&Liberate: {0}";
+ this.liberateVisibleToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
+ //
+ // replaceTagsToolStripMenuItem
+ //
+ this.replaceTagsToolStripMenuItem.Name = "replaceTagsToolStripMenuItem";
+ this.replaceTagsToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.replaceTagsToolStripMenuItem.Text = "Replace &Tags...";
+ this.replaceTagsToolStripMenuItem.Click += new System.EventHandler(this.replaceTagsToolStripMenuItem_Click);
+ //
+ // setDownloadedToolStripMenuItem
+ //
+ this.setDownloadedToolStripMenuItem.Name = "setDownloadedToolStripMenuItem";
+ this.setDownloadedToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.setDownloadedToolStripMenuItem.Text = "Set \'&Downloaded\' status...";
+ this.setDownloadedToolStripMenuItem.Click += new System.EventHandler(this.setDownloadedToolStripMenuItem_Click);
+ //
+ // removeToolStripMenuItem
+ //
+ this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
+ this.removeToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
+ this.removeToolStripMenuItem.Text = "&Remove from library...";
+ this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
+ //
+ // settingsToolStripMenuItem
+ //
+ this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.accountsToolStripMenuItem,
this.basicSettingsToolStripMenuItem,
this.toolStripSeparator2,
this.aboutToolStripMenuItem});
- this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
- this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
- this.settingsToolStripMenuItem.Text = "&Settings";
- //
- // accountsToolStripMenuItem
- //
- this.accountsToolStripMenuItem.Name = "accountsToolStripMenuItem";
- this.accountsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
- this.accountsToolStripMenuItem.Text = "&Accounts...";
- this.accountsToolStripMenuItem.Click += new System.EventHandler(this.accountsToolStripMenuItem_Click);
- //
- // basicSettingsToolStripMenuItem
- //
- this.basicSettingsToolStripMenuItem.Name = "basicSettingsToolStripMenuItem";
- this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
- this.basicSettingsToolStripMenuItem.Text = "&Settings...";
- this.basicSettingsToolStripMenuItem.Click += new System.EventHandler(this.basicSettingsToolStripMenuItem_Click);
- //
- // toolStripSeparator2
- //
- this.toolStripSeparator2.Name = "toolStripSeparator2";
- this.toolStripSeparator2.Size = new System.Drawing.Size(130, 6);
- //
- // aboutToolStripMenuItem
- //
- this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
- this.aboutToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
- this.aboutToolStripMenuItem.Text = "A&bout...";
- this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
- //
- // statusStrip1
- //
- this.statusStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
- this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
+ this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
+ this.settingsToolStripMenuItem.Text = "&Settings";
+ //
+ // accountsToolStripMenuItem
+ //
+ this.accountsToolStripMenuItem.Name = "accountsToolStripMenuItem";
+ this.accountsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
+ this.accountsToolStripMenuItem.Text = "&Accounts...";
+ this.accountsToolStripMenuItem.Click += new System.EventHandler(this.accountsToolStripMenuItem_Click);
+ //
+ // basicSettingsToolStripMenuItem
+ //
+ this.basicSettingsToolStripMenuItem.Name = "basicSettingsToolStripMenuItem";
+ this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
+ this.basicSettingsToolStripMenuItem.Text = "&Settings...";
+ this.basicSettingsToolStripMenuItem.Click += new System.EventHandler(this.basicSettingsToolStripMenuItem_Click);
+ //
+ // toolStripSeparator2
+ //
+ this.toolStripSeparator2.Name = "toolStripSeparator2";
+ this.toolStripSeparator2.Size = new System.Drawing.Size(130, 6);
+ //
+ // aboutToolStripMenuItem
+ //
+ this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
+ this.aboutToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
+ this.aboutToolStripMenuItem.Text = "A&bout...";
+ this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
+ //
+ // statusStrip1
+ //
+ this.statusStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
+ this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.visibleCountLbl,
this.springLbl,
this.backupsCountsLbl,
this.pdfsCountsLbl});
- this.statusStrip1.Location = new System.Drawing.Point(0, 618);
- this.statusStrip1.Name = "statusStrip1";
- this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0);
- this.statusStrip1.Size = new System.Drawing.Size(893, 22);
- this.statusStrip1.TabIndex = 6;
- this.statusStrip1.Text = "statusStrip1";
- //
- // visibleCountLbl
- //
- this.visibleCountLbl.FormatText = "Visible: {0}";
- this.visibleCountLbl.Name = "visibleCountLbl";
- this.visibleCountLbl.Size = new System.Drawing.Size(61, 17);
- this.visibleCountLbl.Text = "Visible: {0}";
- //
- // springLbl
- //
- this.springLbl.Name = "springLbl";
- this.springLbl.Size = new System.Drawing.Size(379, 17);
- this.springLbl.Spring = true;
- //
- // backupsCountsLbl
- //
- this.backupsCountsLbl.Name = "backupsCountsLbl";
- this.backupsCountsLbl.Size = new System.Drawing.Size(218, 17);
- this.backupsCountsLbl.Text = "[Calculating backed up book quantities]";
- //
- // pdfsCountsLbl
- //
- this.pdfsCountsLbl.FormatText = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
- this.pdfsCountsLbl.Name = "pdfsCountsLbl";
- this.pdfsCountsLbl.Size = new System.Drawing.Size(218, 17);
- this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
- //
- // addQuickFilterBtn
- //
- this.addQuickFilterBtn.Location = new System.Drawing.Point(50, 3);
- this.addQuickFilterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
- this.addQuickFilterBtn.Name = "addQuickFilterBtn";
- this.addQuickFilterBtn.Size = new System.Drawing.Size(137, 27);
- this.addQuickFilterBtn.TabIndex = 4;
- this.addQuickFilterBtn.Text = "Add To Quick Filters";
- this.addQuickFilterBtn.UseVisualStyleBackColor = true;
- this.addQuickFilterBtn.Click += new System.EventHandler(this.addQuickFilterBtn_Click);
- //
- // splitContainer1
- //
- this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.splitContainer1.Location = new System.Drawing.Point(0, 0);
- this.splitContainer1.Name = "splitContainer1";
- //
- // splitContainer1.Panel1
- //
- this.splitContainer1.Panel1.Controls.Add(this.panel1);
- this.splitContainer1.Panel1.Controls.Add(this.menuStrip1);
- this.splitContainer1.Panel1.Controls.Add(this.statusStrip1);
- //
- // splitContainer1.Panel2
- //
- this.splitContainer1.Panel2.Controls.Add(this.processBookQueue1);
- this.splitContainer1.Size = new System.Drawing.Size(1231, 640);
- this.splitContainer1.SplitterDistance = 893;
- this.splitContainer1.SplitterWidth = 8;
- this.splitContainer1.TabIndex = 7;
- //
- // panel1
- //
- this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
- this.panel1.Controls.Add(this.toggleQueueHideBtn);
- this.panel1.Controls.Add(this.gridPanel);
- this.panel1.Controls.Add(this.addQuickFilterBtn);
- this.panel1.Controls.Add(this.filterHelpBtn);
- this.panel1.Controls.Add(this.filterSearchTb);
- this.panel1.Controls.Add(this.filterBtn);
- this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.panel1.Location = new System.Drawing.Point(0, 24);
- this.panel1.Margin = new System.Windows.Forms.Padding(0);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(893, 594);
- this.panel1.TabIndex = 7;
- //
- // toggleQueueHideBtn
- //
- this.toggleQueueHideBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.toggleQueueHideBtn.Location = new System.Drawing.Point(845, 3);
- this.toggleQueueHideBtn.Margin = new System.Windows.Forms.Padding(4, 3, 15, 3);
- this.toggleQueueHideBtn.Name = "toggleQueueHideBtn";
- this.toggleQueueHideBtn.Size = new System.Drawing.Size(33, 27);
- this.toggleQueueHideBtn.TabIndex = 8;
- this.toggleQueueHideBtn.Text = "❱❱❱";
- this.toggleQueueHideBtn.UseVisualStyleBackColor = true;
- this.toggleQueueHideBtn.Click += new System.EventHandler(this.ToggleQueueHideBtn_Click);
- //
- // processBookQueue1
- //
- this.processBookQueue1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.processBookQueue1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.processBookQueue1.Location = new System.Drawing.Point(0, 0);
- this.processBookQueue1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
- this.processBookQueue1.Name = "processBookQueue1";
- this.processBookQueue1.Size = new System.Drawing.Size(330, 640);
- this.processBookQueue1.TabIndex = 0;
- //
- // Form1
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1231, 640);
- this.Controls.Add(this.splitContainer1);
- this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
- this.MainMenuStrip = this.menuStrip1;
- this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
- this.Name = "Form1";
- this.Text = "Libation: Liberate your Library";
- this.Load += new System.EventHandler(this.Form1_Load);
- this.menuStrip1.ResumeLayout(false);
- this.menuStrip1.PerformLayout();
- this.statusStrip1.ResumeLayout(false);
- this.statusStrip1.PerformLayout();
- this.splitContainer1.Panel1.ResumeLayout(false);
- this.splitContainer1.Panel1.PerformLayout();
- this.splitContainer1.Panel2.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
- this.splitContainer1.ResumeLayout(false);
- this.panel1.ResumeLayout(false);
- this.panel1.PerformLayout();
- this.ResumeLayout(false);
+ this.statusStrip1.Location = new System.Drawing.Point(0, 618);
+ this.statusStrip1.Name = "statusStrip1";
+ this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0);
+ this.statusStrip1.Size = new System.Drawing.Size(893, 22);
+ this.statusStrip1.TabIndex = 6;
+ this.statusStrip1.Text = "statusStrip1";
+ //
+ // visibleCountLbl
+ //
+ this.visibleCountLbl.FormatText = "Visible: {0}";
+ this.visibleCountLbl.Name = "visibleCountLbl";
+ this.visibleCountLbl.Size = new System.Drawing.Size(61, 17);
+ this.visibleCountLbl.Text = "Visible: {0}";
+ //
+ // springLbl
+ //
+ this.springLbl.Name = "springLbl";
+ this.springLbl.Size = new System.Drawing.Size(379, 17);
+ this.springLbl.Spring = true;
+ //
+ // backupsCountsLbl
+ //
+ this.backupsCountsLbl.Name = "backupsCountsLbl";
+ this.backupsCountsLbl.Size = new System.Drawing.Size(218, 17);
+ this.backupsCountsLbl.Text = "[Calculating backed up book quantities]";
+ //
+ // pdfsCountsLbl
+ //
+ this.pdfsCountsLbl.FormatText = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
+ this.pdfsCountsLbl.Name = "pdfsCountsLbl";
+ this.pdfsCountsLbl.Size = new System.Drawing.Size(218, 17);
+ this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
+ //
+ // addQuickFilterBtn
+ //
+ this.addQuickFilterBtn.Location = new System.Drawing.Point(50, 3);
+ this.addQuickFilterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.addQuickFilterBtn.Name = "addQuickFilterBtn";
+ this.addQuickFilterBtn.Size = new System.Drawing.Size(137, 27);
+ this.addQuickFilterBtn.TabIndex = 4;
+ this.addQuickFilterBtn.Text = "Add To Quick Filters";
+ this.addQuickFilterBtn.UseVisualStyleBackColor = true;
+ this.addQuickFilterBtn.Click += new System.EventHandler(this.addQuickFilterBtn_Click);
+ //
+ // splitContainer1
+ //
+ this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+ this.splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ this.splitContainer1.Panel1.Controls.Add(this.panel1);
+ this.splitContainer1.Panel1.Controls.Add(this.menuStrip1);
+ this.splitContainer1.Panel1.Controls.Add(this.statusStrip1);
+ //
+ // splitContainer1.Panel2
+ //
+ this.splitContainer1.Panel2.Controls.Add(this.processBookQueue1);
+ this.splitContainer1.Size = new System.Drawing.Size(1231, 640);
+ this.splitContainer1.SplitterDistance = 893;
+ this.splitContainer1.SplitterWidth = 8;
+ this.splitContainer1.TabIndex = 7;
+ //
+ // panel1
+ //
+ this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.panel1.Controls.Add(this.productsDisplay);
+ this.panel1.Controls.Add(this.toggleQueueHideBtn);
+ this.panel1.Controls.Add(this.addQuickFilterBtn);
+ this.panel1.Controls.Add(this.filterHelpBtn);
+ this.panel1.Controls.Add(this.filterSearchTb);
+ this.panel1.Controls.Add(this.filterBtn);
+ this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.panel1.Location = new System.Drawing.Point(0, 24);
+ this.panel1.Margin = new System.Windows.Forms.Padding(0);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(893, 594);
+ this.panel1.TabIndex = 7;
+ //
+ // productsDisplay
+ //
+ this.productsDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.productsDisplay.AutoScroll = true;
+ this.productsDisplay.Location = new System.Drawing.Point(15, 36);
+ this.productsDisplay.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.productsDisplay.Name = "productsDisplay";
+ this.productsDisplay.Size = new System.Drawing.Size(863, 555);
+ this.productsDisplay.TabIndex = 9;
+ this.productsDisplay.LiberateClicked += new System.EventHandler(this.ProductsDisplay_LiberateClicked);
+ this.productsDisplay.VisibleCountChanged += new System.EventHandler(this.productsDisplay_VisibleCountChanged);
+ this.productsDisplay.InitialLoaded += new System.EventHandler(this.productsDisplay_InitialLoaded);
+ //
+ // toggleQueueHideBtn
+ //
+ this.toggleQueueHideBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.toggleQueueHideBtn.Location = new System.Drawing.Point(845, 3);
+ this.toggleQueueHideBtn.Margin = new System.Windows.Forms.Padding(4, 3, 15, 3);
+ this.toggleQueueHideBtn.Name = "toggleQueueHideBtn";
+ this.toggleQueueHideBtn.Size = new System.Drawing.Size(33, 27);
+ this.toggleQueueHideBtn.TabIndex = 8;
+ this.toggleQueueHideBtn.Text = "❱❱❱";
+ this.toggleQueueHideBtn.UseVisualStyleBackColor = true;
+ this.toggleQueueHideBtn.Click += new System.EventHandler(this.ToggleQueueHideBtn_Click);
+ //
+ // processBookQueue1
+ //
+ this.processBookQueue1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.processBookQueue1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.processBookQueue1.Location = new System.Drawing.Point(0, 0);
+ this.processBookQueue1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
+ this.processBookQueue1.Name = "processBookQueue1";
+ this.processBookQueue1.Size = new System.Drawing.Size(330, 640);
+ this.processBookQueue1.TabIndex = 0;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1231, 640);
+ this.Controls.Add(this.splitContainer1);
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MainMenuStrip = this.menuStrip1;
+ this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
+ this.Name = "Form1";
+ this.Text = "Libation: Liberate your Library";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.menuStrip1.ResumeLayout(false);
+ this.menuStrip1.PerformLayout();
+ this.statusStrip1.ResumeLayout(false);
+ this.statusStrip1.PerformLayout();
+ this.splitContainer1.Panel1.ResumeLayout(false);
+ this.splitContainer1.Panel1.PerformLayout();
+ this.splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+ this.splitContainer1.ResumeLayout(false);
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
+ this.ResumeLayout(false);
}
#endregion
-
- private System.Windows.Forms.Panel gridPanel;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip1;
@@ -581,5 +583,6 @@
private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button toggleQueueHideBtn;
+ private ProductsDisplay productsDisplay;
}
}
diff --git a/Source/LibationWinForms/Form1.Filter.cs b/Source/LibationWinForms/Form1.Filter.cs
index 03e89f9d..2a175e74 100644
--- a/Source/LibationWinForms/Form1.Filter.cs
+++ b/Source/LibationWinForms/Form1.Filter.cs
@@ -30,7 +30,7 @@ namespace LibationWinForms
try
{
- productsGrid.Filter(filterString);
+ productsDisplay.Filter(filterString);
lastGoodFilter = filterString;
}
catch (Exception ex)
diff --git a/Source/LibationWinForms/Form1.ProcessQueue.cs b/Source/LibationWinForms/Form1.ProcessQueue.cs
index 74d30406..8a8178f2 100644
--- a/Source/LibationWinForms/Form1.ProcessQueue.cs
+++ b/Source/LibationWinForms/Form1.ProcessQueue.cs
@@ -14,14 +14,13 @@ namespace LibationWinForms
int WidthChange = 0;
private void Configure_ProcessQueue()
{
- productsGrid.LiberateClicked += ProductsGrid_LiberateClicked;
processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut;
var coppalseState = Configuration.Instance.GetNonString(nameof(splitContainer1.Panel2Collapsed));
WidthChange = splitContainer1.Panel2.Width + splitContainer1.SplitterWidth;
SetQueueCollapseState(coppalseState);
}
- private void ProductsGrid_LiberateClicked(object sender, LibraryBook e)
+ private void ProductsDisplay_LiberateClicked(object sender, LibraryBook e)
{
if (e.Book.UserDefinedItem.BookStatus != LiberatedStatus.Liberated)
{
diff --git a/Source/LibationWinForms/Form1.QuickFilters.cs b/Source/LibationWinForms/Form1.QuickFilters.cs
index 8804f083..3908290b 100644
--- a/Source/LibationWinForms/Form1.QuickFilters.cs
+++ b/Source/LibationWinForms/Form1.QuickFilters.cs
@@ -14,12 +14,6 @@ namespace LibationWinForms
Load += updateFiltersMenu;
QuickFilters.UseDefaultChanged += updateFirstFilterIsDefaultToolStripMenuItem;
QuickFilters.Updated += updateFiltersMenu;
-
- productsGrid.InitialLoaded += (_, __) =>
- {
- if (QuickFilters.UseDefault)
- performFilter(QuickFilters.Filters.FirstOrDefault());
- };
}
private object quickFilterTag { get; } = new();
@@ -56,5 +50,11 @@ namespace LibationWinForms
private void addQuickFilterBtn_Click(object sender, EventArgs e) => QuickFilters.Add(this.filterSearchTb.Text);
private void editQuickFiltersToolStripMenuItem_Click(object sender, EventArgs e) => new EditQuickFilters().ShowDialog();
+
+ private void productsDisplay_InitialLoaded(object sender, EventArgs e)
+ {
+ if (QuickFilters.UseDefault)
+ performFilter(QuickFilters.Filters.FirstOrDefault());
+ }
}
}
diff --git a/Source/LibationWinForms/Form1.VisibleBooks.cs b/Source/LibationWinForms/Form1.VisibleBooks.cs
index 65dfecca..a17effa7 100644
--- a/Source/LibationWinForms/Form1.VisibleBooks.cs
+++ b/Source/LibationWinForms/Form1.VisibleBooks.cs
@@ -17,28 +17,16 @@ namespace LibationWinForms
liberateVisibleToolStripMenuItem.Format(0);
liberateVisible2ToolStripMenuItem.Format(0);
- // bottom-left visible count
- productsGrid.VisibleCountChanged += (_, qty) => visibleCountLbl.Format(qty);
-
// top menu strip
visibleBooksToolStripMenuItem.Format(0);
- productsGrid.VisibleCountChanged += (_, qty) => {
- visibleBooksToolStripMenuItem.Format(qty);
- visibleBooksToolStripMenuItem.Enabled = qty > 0;
- var notLiberatedCount = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
- };
-
- productsGrid.VisibleCountChanged += setLiberatedVisibleMenuItemAsync;
LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync;
}
- private async void setLiberatedVisibleMenuItemAsync(object _, int __)
- => await Task.Run(setLiberatedVisibleMenuItem);
private async void setLiberatedVisibleMenuItemAsync(object _, EventArgs __)
=> await Task.Run(setLiberatedVisibleMenuItem);
void setLiberatedVisibleMenuItem()
{
- var notLiberated = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
+ var notLiberated = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
this.UIThreadSync(() =>
{
if (notLiberated > 0)
@@ -63,7 +51,7 @@ namespace LibationWinForms
private async void liberateVisible(object sender, EventArgs e)
{
SetQueueCollapseState(false);
- await Task.Run(() => processBookQueue1.AddDownloadDecrypt(productsGrid.GetVisible()));
+ await Task.Run(() => processBookQueue1.AddDownloadDecrypt(productsDisplay.GetVisible()));
}
private void replaceTagsToolStripMenuItem_Click(object sender, EventArgs e)
@@ -73,7 +61,7 @@ namespace LibationWinForms
if (result != DialogResult.OK)
return;
- var visibleLibraryBooks = productsGrid.GetVisible();
+ var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks,
@@ -95,7 +83,7 @@ namespace LibationWinForms
if (result != DialogResult.OK)
return;
- var visibleLibraryBooks = productsGrid.GetVisible();
+ var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks,
@@ -112,7 +100,7 @@ namespace LibationWinForms
private async void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
- var visibleLibraryBooks = productsGrid.GetVisible();
+ var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks,
@@ -125,5 +113,20 @@ namespace LibationWinForms
var visibleIds = visibleLibraryBooks.Select(lb => lb.Book.AudibleProductId).ToList();
await LibraryCommands.RemoveBooksAsync(visibleIds);
}
+
+ private async void productsDisplay_VisibleCountChanged(object sender, int qty)
+ {
+ // bottom-left visible count
+ visibleCountLbl.Format(qty);
+
+ // top menu strip
+ visibleBooksToolStripMenuItem.Format(qty);
+ visibleBooksToolStripMenuItem.Enabled = qty > 0;
+
+ //Not used for anything?
+ var notLiberatedCount = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
+
+ await Task.Run(setLiberatedVisibleMenuItem);
+ }
}
}
diff --git a/Source/LibationWinForms/Form1.cs b/Source/LibationWinForms/Form1.cs
index 0c2f3ce1..43151f73 100644
--- a/Source/LibationWinForms/Form1.cs
+++ b/Source/LibationWinForms/Form1.cs
@@ -12,24 +12,10 @@ namespace LibationWinForms
{
public partial class Form1 : Form
{
- private ProductsDisplay productsGrid { get; }
-
public Form1()
{
InitializeComponent();
- if (this.DesignMode)
- return;
-
- {
- // I'd actually like these lines to be handled in the designer, but I'm currently getting this error when I try:
- // Failed to create component 'ProductsGrid'. The error message follows:
- // 'Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Object reference not set to an instance of an object.
- // Since the designer's choking on it, I'm keeping it below the DesignMode check to be safe
- productsGrid = new ProductsDisplay { Dock = DockStyle.Fill };
- gridPanel.Controls.Add(productsGrid);
- }
-
// Pre-requisite:
// Before calling anything else, including subscribing to events, ensure database exists. If we wait and let it happen lazily, race conditions and errors are likely during new installs
using var _ = DbContexts.GetContext();
@@ -67,8 +53,8 @@ namespace LibationWinForms
// Configure_Grid(); // since it's just this, can keep here. If it needs more, then give grid it's own 'partial class Form1'
{
- this.Load += (_, __) => productsGrid.Display();
- LibraryCommands.LibrarySizeChanged += (_, __) => this.UIThreadAsync(() => productsGrid.Display());
+ this.Load += (_, __) => productsDisplay.Display();
+ LibraryCommands.LibrarySizeChanged += (_, __) => this.UIThreadAsync(() => productsDisplay.Display());
}
}
diff --git a/Source/LibationWinForms/LibationWinForms.csproj b/Source/LibationWinForms/LibationWinForms.csproj
index 979db0ff..2ecd019b 100644
--- a/Source/LibationWinForms/LibationWinForms.csproj
+++ b/Source/LibationWinForms/LibationWinForms.csproj
@@ -45,9 +45,6 @@
-
- UserControl
-
True
True
@@ -56,9 +53,6 @@
-
- Designer
-
ResXFileCodeGenerator
Resources.Designer.cs
diff --git a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
index 1349325a..db8bb484 100644
--- a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
@@ -1,4 +1,5 @@
-using System.Drawing;
+using Dinah.Core.Windows.Forms;
+using System.Drawing;
using System.Windows.Forms;
namespace LibationWinForms
@@ -18,6 +19,12 @@ namespace LibationWinForms
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)
{
+ if (rowIndex >= 0 && DataGridView.GetBoundItem(rowIndex) is SeriesEntry)
+ {
+ base.Paint(graphics, clipBounds, cellBounds, rowIndex, DataGridViewElementStates.None, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
+ return;
+ }
+
var tagsString = (string)value;
var foreColor = tagsString?.Contains("hidden") == true ? HiddenForeColor : DataGridView.DefaultCellStyle.ForeColor;
diff --git a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
index e3bcaad0..e309f7fe 100644
--- a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
+++ b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
@@ -8,17 +8,17 @@ using System.Linq;
namespace LibationWinForms
{
/*
- * Allows filtering of the underlying SortableBindingList
- * by implementing IBindingListView and using SearchEngineCommands
- *
- * When filtering is applied, the filtered-out items are removed
- * from the base list and added to the private FilterRemoved list.
- * When filtering is removed, items in the FilterRemoved list are
- * added back to the base list.
- *
- * Remove is overridden to ensure that removed items are removed from
- * the base list (visible items) as well as the FilterRemoved list.
- */
+ * Allows filtering of the underlying SortableBindingList
+ * by implementing IBindingListView and using SearchEngineCommands
+ *
+ * When filtering is applied, the filtered-out items are removed
+ * from the base list and added to the private FilterRemoved list.
+ * When filtering is removed, items in the FilterRemoved list are
+ * added back to the base list.
+ *
+ * Remove is overridden to ensure that removed items are removed from
+ * the base list (visible items) as well as the FilterRemoved list.
+ */
internal class FilterableSortableBindingList : SortableBindingList1, IBindingListView
{
///
@@ -50,14 +50,7 @@ namespace LibationWinForms
}
/// All items in the list, including those filtered out.
- public List AllItems()
- {
- var allItems = Items.Concat(FilterRemoved);
-
- var series = allItems.Where(i => i is SeriesEntry).Cast().SelectMany(s => s.Children);
-
- return series.Concat(allItems).ToList();
- }
+ public List AllItems() => Items.Concat(FilterRemoved).ToList();
private void ApplyFilter(string filterString)
{
@@ -65,32 +58,41 @@ namespace LibationWinForms
RemoveFilter();
FilterString = filterString;
-
SearchResults = SearchEngineCommands.Search(filterString);
- var filteredOut = Items.Where(i => i is LibraryBookEntry).Cast().ExceptBy(SearchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId).Cast().ToList();
- var parents = Items.Where(i => i is SeriesEntry).Cast();
+ var booksFilteredIn = Items.LibraryBooks().Join(SearchResults.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => (GridEntry)lbe);
- foreach (var p in parents)
+ //Find all series containing children that match the search criteria
+ var seriesFilteredIn = Items.Series().Where(s => s.Children.Join(SearchResults.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => lbe).Any());
+
+ var filteredOut = Items.Except(booksFilteredIn.Concat(seriesFilteredIn)).ToList();
+
+ foreach (var item in filteredOut)
{
- if (p.Children.Cast().ExceptBy(SearchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId).Count() == p.Children.Count)
- {
- //Don't show series whose episodes have all been filtered out
- filteredOut.Add(p);
- }
+ FilterRemoved.Add(item);
+ base.Remove(item);
}
+ }
- for (int i = 0; i < filteredOut.Count; i++)
- {
- FilterRemoved.Add(filteredOut[i]);
- base.Remove(filteredOut[i]);
- }
+ public void CollapseAll()
+ {
+ foreach (var series in Items.Series().ToList())
+ CollapseItem(series);
+ }
+
+ public void ExpandAll()
+ {
+ foreach (var series in Items.Series().ToList())
+ ExpandItem(series);
}
public void CollapseItem(SeriesEntry sEntry)
{
- foreach (var item in Items.Where(b => b is LibraryBookEntry).Cast().Where(b => b.Parent == sEntry).ToList())
- base.Remove(item);
+ foreach (var episode in Items.Where(b => b.Parent == sEntry).Cast().ToList())
+ {
+ FilterRemoved.Add(episode);
+ base.Remove(episode);
+ }
sEntry.Liberate.Expanded = false;
}
@@ -98,16 +100,17 @@ namespace LibationWinForms
public void ExpandItem(SeriesEntry sEntry)
{
var sindex = Items.IndexOf(sEntry);
- var children = sEntry.Children.Cast().ToList();
- for (int i = 0; i < children.Count; i++)
+
+ foreach (var episode in FilterRemoved.Where(b => b.Parent == sEntry).Cast().ToList())
{
- if (SearchResults is null || SearchResults.Docs.Any(d=> d.ProductId == children[i].AudibleProductId))
- Insert(++sindex, children[i]);
- else
+ if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
{
- FilterRemoved.Add(children[i]);
+ FilterRemoved.Remove(episode);
+ Items.Insert(++sindex, episode);
}
}
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
sEntry.Liberate.Expanded = true;
}
@@ -116,13 +119,15 @@ namespace LibationWinForms
if (FilterString is null) return;
int visibleCount = Items.Count;
- for (int i = 0; i < FilterRemoved.Count; i++)
- {
- if (FilterRemoved[i].Parent is null || FilterRemoved[i].Parent.Liberate.Expanded)
- base.InsertItem(i + visibleCount, FilterRemoved[i]);
- }
- FilterRemoved.Clear();
+ foreach (var item in FilterRemoved.ToList())
+ {
+ if (item.Parent is null || item.Parent.Liberate.Expanded)
+ {
+ FilterRemoved.Remove(item);
+ base.InsertItem(visibleCount++, item);
+ }
+ }
if (IsSortedCore)
Sort();
diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs
index a9d86b41..e0f19c1c 100644
--- a/Source/LibationWinForms/grid/GridEntry.cs
+++ b/Source/LibationWinForms/grid/GridEntry.cs
@@ -5,25 +5,37 @@ using LibationFileManager;
using System;
using System.Collections;
using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
+using System.ComponentModel;using System.Drawing;
+using System.Linq;
namespace LibationWinForms
{
public interface IHierarchical where T : class
{
T Parent { get; }
- List Children { get; }
}
- internal class LiberateStatus
+
+ public class LiberateStatus : IComparable
{
public LiberatedStatus BookStatus;
public LiberatedStatus? PdfStatus;
public bool IsSeries;
public bool Expanded;
+
+ public int CompareTo(object obj)
+ {
+ if (obj is not LiberateStatus second) return -1;
+
+ if (IsSeries && !second.IsSeries) return -1;
+ else if (!IsSeries && second.IsSeries) return 1;
+ else if (IsSeries && second.IsSeries) return 0;
+ else if (BookStatus == LiberatedStatus.Liberated && second.BookStatus != LiberatedStatus.Liberated) return -1;
+ else if (BookStatus != LiberatedStatus.Liberated && second.BookStatus == LiberatedStatus.Liberated) return 1;
+ else return BookStatus.CompareTo(second.BookStatus);
+ }
}
- internal abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable, IHierarchical
+ public abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable, IHierarchical
{
protected abstract Book Book { get; }
@@ -38,11 +50,15 @@ namespace LibationWinForms
NotifyPropertyChanged();
}
}
+
+ [Browsable(false)]
+ public new bool InvokeRequired => base.InvokeRequired;
+ [Browsable(false)]
public GridEntry Parent { get; set; }
- public List Children { get; set; }
+ [Browsable(false)]
+ public abstract DateTime DateAdded { get; }
public abstract string ProductRating { get; protected set; }
public abstract string PurchaseDate { get; protected set; }
- public abstract DateTime DateAdded { get; }
public abstract string MyRating { get; protected set; }
public abstract string Series { get; protected set; }
public abstract string Title { get; protected set; }
@@ -89,12 +105,20 @@ namespace LibationWinForms
{ typeof(float), new ObjectComparer() },
{ typeof(bool), new ObjectComparer() },
{ typeof(DateTime), new ObjectComparer() },
- { typeof(LiberatedStatus), new ObjectComparer() },
+ { typeof(LiberateStatus), new ObjectComparer() },
};
~GridEntry()
{
PictureStorage.PictureCached -= PictureStorage_PictureCached;
- }
+ }
+ }
+
+ internal static class GridEntryExtensions
+ {
+ public static IEnumerable Series(this IEnumerable gridEntries)
+ => gridEntries.Where(i => i is SeriesEntry).Cast();
+ public static IEnumerable LibraryBooks(this IEnumerable gridEntries)
+ => gridEntries.Where(i => i is LibraryBookEntry).Cast();
}
}
diff --git a/Source/LibationWinForms/grid/LibraryBookEntry.cs b/Source/LibationWinForms/grid/LibraryBookEntry.cs
index e87ae630..c1be718c 100644
--- a/Source/LibationWinForms/grid/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/grid/LibraryBookEntry.cs
@@ -17,7 +17,7 @@ namespace LibationWinForms
///
/// The View Model for a LibraryBook
///
- internal class LibraryBookEntry : GridEntry
+ public class LibraryBookEntry : GridEntry
{
#region implementation properties NOT exposed to the view
// hide from public fields from Data Source GUI with [Browsable(false)]
@@ -187,7 +187,7 @@ namespace LibationWinForms
{ nameof(Category), () => Category },
{ nameof(Misc), () => Misc },
{ nameof(DisplayTags), () => DisplayTags },
- { nameof(Liberate), () => Liberate.BookStatus },
+ { nameof(Liberate), () => Liberate },
{ nameof(DateAdded), () => DateAdded },
};
diff --git a/Source/LibationWinForms/grid/MasterDataGridView.cs b/Source/LibationWinForms/grid/MasterDataGridView.cs
deleted file mode 100644
index fd3b481a..00000000
--- a/Source/LibationWinForms/grid/MasterDataGridView.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using Dinah.Core.Windows.Forms;
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-
-namespace LibationWinForms
-{
-
- internal class MasterDataGridView : DataGridView
- {
- internal delegate void LibraryBookEntryClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry entry);
- public event LibraryBookEntryClickedEventHandler LibraryBookEntryClicked;
- public MasterDataGridView()
- {
-
- }
-
-
- public GridEntry getGridEntry(int rowIndex) => this.GetBoundItem(rowIndex);
-
- }
-}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
index d15ad85c..a10e1c95 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
@@ -28,19 +28,38 @@
///
private void InitializeComponent()
{
+ this.productsGrid = new LibationWinForms.grid.ProductsGrid();
this.SuspendLayout();
//
+ // productsGrid
+ //
+ this.productsGrid.AutoScroll = true;
+ this.productsGrid.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.productsGrid.Location = new System.Drawing.Point(0, 0);
+ this.productsGrid.Name = "productsGrid";
+ this.productsGrid.Size = new System.Drawing.Size(1510, 380);
+ this.productsGrid.TabIndex = 0;
+ this.productsGrid.LiberateClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_LiberateClicked);
+ this.productsGrid.CoverClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_CoverClicked);
+ this.productsGrid.DetailsClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_DetailsClicked);
+ this.productsGrid.DescriptionClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryRectangleClickedEventHandler(this.productsGrid_DescriptionClicked);
+ this.productsGrid.VisibleCountChanged += new System.EventHandler(this.productsGrid_VisibleCountChanged);
+ //
// ProductsDisplay
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.productsGrid);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsDisplay";
this.Size = new System.Drawing.Size(1510, 380);
+ this.Load += new System.EventHandler(this.ProductsDisplay_Load);
this.ResumeLayout(false);
}
#endregion
+
+ private grid.ProductsGrid productsGrid;
}
}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.cs b/Source/LibationWinForms/grid/ProductsDisplay.cs
index e0e0fd58..0a9bee61 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.cs
+++ b/Source/LibationWinForms/grid/ProductsDisplay.cs
@@ -6,65 +6,35 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
using DataLayer;
-using Dinah.Core.Windows.Forms;
using FileLiberator;
using LibationFileManager;
using LibationWinForms.Dialogs;
namespace LibationWinForms
{
-
- #region // legacy instructions to update data_grid_view
- // INSTRUCTIONS TO UPDATE DATA_GRID_VIEW
- // - delete current DataGridView
- // - view > other windows > data sources
- // - refresh
- // OR
- // - Add New Data Source
- // Object. Next
- // LibationWinForms
- // AudibleDTO
- // GridEntry
- // - go to Design view
- // - click on Data Sources > ProductItem. dropdown: DataGridView
- // - drag/drop ProductItem on design surface
- //
- // as of august 2021 this does not work in vs2019 with .net5 projects
- // VS has improved since then with .net6+ but I haven't checked again
- #endregion
-
-
public partial class ProductsDisplay : UserControl
{
public event EventHandler LiberateClicked;
/// Number of visible rows has changed
public event EventHandler VisibleCountChanged;
- // alias
-
- private ProductsGrid grid;
-
public ProductsDisplay()
{
InitializeComponent();
+ }
- grid = new ProductsGrid();
- grid.Dock = DockStyle.Fill;
- Controls.Add(grid);
-
- if (this.DesignMode)
+ private void ProductsDisplay_Load(object sender, EventArgs e)
+ {
+ if (DesignMode)
return;
- grid.LiberateClicked += (_, book) => LiberateClicked?.Invoke(this, book.LibraryBook);
- grid.DetailsClicked += Grid_DetailsClicked;
- grid.CoverClicked += Grid_CoverClicked;
- grid.DescriptionClicked += Grid_DescriptionClicked1;
}
+
#region Button controls
private ImageDisplay imageDisplay;
- private async void Grid_CoverClicked(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry)
+ private async void productsGrid_CoverClicked(LibraryBookEntry liveGridEntry)
{
var picDefinition = new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureLarge ?? liveGridEntry.LibraryBook.Book.PictureId, PictureSize.Native);
var picDlTask = Task.Run(() => PictureStorage.GetPictureSynchronously(picDefinition));
@@ -87,7 +57,7 @@ namespace LibationWinForms
imageDisplay.CoverPicture = await picDlTask;
}
- private void Grid_DescriptionClicked1(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry, Rectangle cellRectangle)
+ private void productsGrid_DescriptionClicked(LibraryBookEntry liveGridEntry, Rectangle cellRectangle)
{
var displayWindow = new DescriptionDisplay
{
@@ -101,13 +71,13 @@ namespace LibationWinForms
displayWindow.Close();
}
- grid.Scroll += CloseWindow;
- displayWindow.FormClosed += (_, _) => grid.Scroll -= CloseWindow;
+ productsGrid.Scroll += CloseWindow;
+ displayWindow.FormClosed += (_, _) => productsGrid.Scroll -= CloseWindow;
displayWindow.Show(this);
}
- private void Grid_DetailsClicked(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry)
+ private void productsGrid_DetailsClicked(LibraryBookEntry liveGridEntry)
{
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
if (bookDetailsForm.ShowDialog() == DialogResult.OK)
@@ -128,13 +98,12 @@ namespace LibationWinForms
if (!hasBeenDisplayed)
{
// bind
- grid.bindToGrid(lib);
+ productsGrid.BindToGrid(lib);
hasBeenDisplayed = true;
InitialLoaded?.Invoke(this, new());
- VisibleCountChanged?.Invoke(this, grid.GetVisible().Count());
}
else
- grid.updateGrid(lib);
+ productsGrid.UpdateGrid(lib);
}
@@ -143,10 +112,20 @@ namespace LibationWinForms
#region Filter
public void Filter(string searchString)
- => grid.Filter(searchString);
+ => productsGrid.Filter(searchString);
#endregion
- internal List GetVisible() => grid.GetVisible().ToList();
+ internal List GetVisible() => productsGrid.GetVisible().Select(v => v.LibraryBook).ToList();
+
+ private void productsGrid_VisibleCountChanged(object sender, int count)
+ {
+ VisibleCountChanged?.Invoke(this, count);
+ }
+
+ private void productsGrid_LiberateClicked(LibraryBookEntry liveGridEntry)
+ {
+ LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
+ }
}
}
diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
index 27496d79..e818ed5b 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
@@ -1,4 +1,4 @@
-namespace LibationWinForms
+namespace LibationWinForms.grid
{
partial class ProductsGrid
{
@@ -30,7 +30,6 @@
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
- this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components);
this.gridEntryDataGridView = new System.Windows.Forms.DataGridView();
this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn();
this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn();
@@ -47,39 +46,32 @@
this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
- ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit();
this.SuspendLayout();
//
- // gridEntryBindingSource
- //
- this.gridEntryBindingSource.DataSource = typeof(LibationWinForms.GridEntry);
- //
// gridEntryDataGridView
//
this.gridEntryDataGridView.AllowUserToAddRows = false;
this.gridEntryDataGridView.AllowUserToDeleteRows = false;
this.gridEntryDataGridView.AllowUserToOrderColumns = true;
this.gridEntryDataGridView.AllowUserToResizeRows = false;
- this.gridEntryDataGridView.AutoGenerateColumns = false;
this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.liberateGVColumn,
- this.coverGVColumn,
- this.titleGVColumn,
- this.authorsGVColumn,
- this.narratorsGVColumn,
- this.lengthGVColumn,
- this.seriesGVColumn,
- this.descriptionGVColumn,
- this.categoryGVColumn,
- this.productRatingGVColumn,
- this.purchaseDateGVColumn,
- this.myRatingGVColumn,
- this.miscGVColumn,
- this.tagAndDetailsGVColumn});
+ this.liberateGVColumn,
+ this.coverGVColumn,
+ this.titleGVColumn,
+ this.authorsGVColumn,
+ this.narratorsGVColumn,
+ this.lengthGVColumn,
+ this.seriesGVColumn,
+ this.descriptionGVColumn,
+ this.categoryGVColumn,
+ this.productRatingGVColumn,
+ this.purchaseDateGVColumn,
+ this.myRatingGVColumn,
+ this.miscGVColumn,
+ this.tagAndDetailsGVColumn});
this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1;
- this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
@@ -90,16 +82,15 @@
this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle1;
this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.gridEntryDataGridView.Location = new System.Drawing.Point(0, 0);
- this.gridEntryDataGridView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.gridEntryDataGridView.Name = "gridEntryDataGridView";
this.gridEntryDataGridView.ReadOnly = true;
this.gridEntryDataGridView.RowHeadersVisible = false;
this.gridEntryDataGridView.RowTemplate.Height = 82;
this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380);
this.gridEntryDataGridView.TabIndex = 0;
+ this.gridEntryDataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellContentClick);
this.gridEntryDataGridView.CellToolTipTextNeeded += new System.Windows.Forms.DataGridViewCellToolTipTextNeededEventHandler(this.gridEntryDataGridView_CellToolTipTextNeeded);
this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged);
- this.gridEntryDataGridView.ColumnWidthChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnWidthChanged);
//
// liberateGVColumn
//
@@ -222,19 +213,18 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoScroll = true;
this.Controls.Add(this.gridEntryDataGridView);
- this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsGrid";
this.Size = new System.Drawing.Size(1510, 380);
- ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit();
+ this.Load += new System.EventHandler(this.ProductsGrid_Load);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit();
this.ResumeLayout(false);
}
- #endregion
- private LibationWinForms.SyncBindingSource gridEntryBindingSource;
+ #endregion
private System.Windows.Forms.DataGridView gridEntryDataGridView;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private LiberateDataGridViewImageButtonColumn liberateGVColumn;
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index 2d585f27..b119285d 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -1,103 +1,70 @@
-using System;
+using DataLayer;
+using Dinah.Core.Windows.Forms;
+using LibationFileManager;
+using System;
using System.Collections.Generic;
+using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
-using ApplicationServices;
-using DataLayer;
-using Dinah.Core.Windows.Forms;
-using LibationFileManager;
-namespace LibationWinForms
+namespace LibationWinForms.grid
{
-
- #region // legacy instructions to update data_grid_view
- // INSTRUCTIONS TO UPDATE DATA_GRID_VIEW
- // - delete current DataGridView
- // - view > other windows > data sources
- // - refresh
- // OR
- // - Add New Data Source
- // Object. Next
- // LibationWinForms
- // AudibleDTO
- // GridEntry
- // - go to Design view
- // - click on Data Sources > ProductItem. dropdown: DataGridView
- // - drag/drop ProductItem on design surface
- //
- // as of august 2021 this does not work in vs2019 with .net5 projects
- // VS has improved since then with .net6+ but I haven't checked again
- #endregion
-
-
public partial class ProductsGrid : UserControl
{
-
- internal delegate void LibraryBookEntryClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry);
- internal delegate void LibraryBookEntryRectangleClickedEventHandler(DataGridViewCellEventArgs e, LibraryBookEntry liveGridEntry, Rectangle cellRectangle);
- internal event LibraryBookEntryClickedEventHandler LiberateClicked;
- internal event LibraryBookEntryClickedEventHandler CoverClicked;
- internal event LibraryBookEntryClickedEventHandler DetailsClicked;
- internal event LibraryBookEntryRectangleClickedEventHandler DescriptionClicked;
- public new event EventHandler Scroll;
-
- private FilterableSortableBindingList bindingList;
+ public delegate void LibraryBookEntryClickedEventHandler(LibraryBookEntry liveGridEntry);
+ public delegate void LibraryBookEntryRectangleClickedEventHandler(LibraryBookEntry liveGridEntry, Rectangle cellRectangle);
/// Number of visible rows has changed
public event EventHandler VisibleCountChanged;
+ public event LibraryBookEntryClickedEventHandler LiberateClicked;
+ public event LibraryBookEntryClickedEventHandler CoverClicked;
+ public event LibraryBookEntryClickedEventHandler DetailsClicked;
+ public event LibraryBookEntryRectangleClickedEventHandler DescriptionClicked;
+ public new event EventHandler Scroll;
- // alias
- private DataGridView _dataGridView => gridEntryDataGridView;
+ private FilterableSortableBindingList bindingList;
+ private SyncBindingSource gridEntryBindingSource;
public ProductsGrid()
{
InitializeComponent();
-
- if (this.DesignMode)
- return;
-
EnableDoubleBuffering();
-
- _dataGridView.CellContentClick += DataGridView_CellContentClick;
- _dataGridView.Scroll += (_, s) => Scroll?.Invoke(this, s);
-
- Load += ProductsGrid_Load;
- }
-
- private void ProductsGrid_Scroll(object sender, ScrollEventArgs e)
- {
- throw new NotImplementedException();
+ //There a bug in designer that causes errors if you add BindingSource to the DataGridView at design time.
+ gridEntryBindingSource = new SyncBindingSource();
+ gridEntryDataGridView.DataSource = gridEntryBindingSource;
+ gridEntryDataGridView.Scroll += (_, s) => Scroll?.Invoke(this, s);
}
private void EnableDoubleBuffering()
{
- var propertyInfo = _dataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
+ var propertyInfo = gridEntryDataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
- propertyInfo.SetValue(_dataGridView, true, null);
+ propertyInfo.SetValue(gridEntryDataGridView, true, null);
}
#region Button controls
-
private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// handle grid button click: https://stackoverflow.com/a/13687844
- if (e.RowIndex < 0)
+ if ( e.RowIndex < 0)
return;
+ var column = gridEntryDataGridView.Columns[e.ColumnIndex];
+
var entry = getGridEntry(e.RowIndex);
if (entry is LibraryBookEntry lbEntry)
{
- if (e.ColumnIndex == liberateGVColumn.Index)
- LiberateClicked?.Invoke(e, lbEntry);
- else if (e.ColumnIndex == tagAndDetailsGVColumn.Index && entry is LibraryBookEntry)
- DetailsClicked?.Invoke(e, lbEntry);
- else if (e.ColumnIndex == descriptionGVColumn.Index)
- DescriptionClicked?.Invoke(e, lbEntry, _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
- else if (e.ColumnIndex == coverGVColumn.Index)
- CoverClicked?.Invoke(e, lbEntry);
+ if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == liberateGVColumn.DataPropertyName)
+ LiberateClicked?.Invoke(lbEntry);
+ else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == tagAndDetailsGVColumn.DataPropertyName && entry is LibraryBookEntry)
+ DetailsClicked?.Invoke(lbEntry);
+ else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == descriptionGVColumn.DataPropertyName)
+ DescriptionClicked?.Invoke(lbEntry, gridEntryDataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
+ else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == coverGVColumn.DataPropertyName)
+ CoverClicked?.Invoke(lbEntry);
}
- else if (entry is SeriesEntry sEntry && e.ColumnIndex == liberateGVColumn.Index)
+ else if (entry is SeriesEntry sEntry && gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == liberateGVColumn.DataPropertyName)
{
if (sEntry.Liberate.Expanded)
bindingList.CollapseItem(sEntry);
@@ -105,16 +72,19 @@ namespace LibationWinForms
bindingList.ExpandItem(sEntry);
sEntry.NotifyPropertyChanged(nameof(sEntry.Liberate));
+
+ VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
}
- private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex);
+ private GridEntry getGridEntry(int rowIndex) => gridEntryDataGridView.GetBoundItem(rowIndex);
#endregion
+
#region UI display functions
- internal void bindToGrid(List dbBooks)
+ internal void BindToGrid(List dbBooks)
{
var geList = dbBooks.Where(b => b.Book.ContentType is not ContentType.Episode).Select(b => new LibraryBookEntry(b)).Cast().ToList();
@@ -125,24 +95,28 @@ namespace LibationWinForms
foreach (var s in series)
{
var seriesEntry = new SeriesEntry();
- seriesEntry.Children = episodes.Where(lb => lb.Book.SeriesLink.First().Series == s.Book.SeriesLink.First().Series).Select(lb => new LibraryBookEntry(lb) { Parent = seriesEntry }).Cast().ToList();
+ seriesEntry.Children = episodes.Where(lb => lb.Book.SeriesLink.First().Series == s.Book.SeriesLink.First().Series).Select(lb => new LibraryBookEntry(lb) { Parent = seriesEntry }).ToList();
seriesEntry.setSeriesBook(s);
+
geList.Add(seriesEntry);
+ geList.AddRange(seriesEntry.Children);
}
- bindingList = new FilterableSortableBindingList(geList.OrderByDescending(ge => ge.DateAdded));
+ bindingList = new FilterableSortableBindingList(geList.OrderByDescending(e => e.DateAdded));
+ bindingList.CollapseAll();
gridEntryBindingSource.DataSource = bindingList;
+ VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
- internal void updateGrid(List dbBooks)
+ internal void UpdateGrid(List dbBooks)
{
int visibleCount = bindingList.Count;
string existingFilter = gridEntryBindingSource.Filter;
//Add absent books to grid, or update current books
- var allItmes = bindingList.AllItems().Where(i => i is LibraryBookEntry).Cast();
+ var allItmes = bindingList.AllItems().LibraryBooks();
for (var i = dbBooks.Count - 1; i >= 0; i--)
{
var libraryBook = dbBooks[i];
@@ -155,26 +129,31 @@ namespace LibationWinForms
if (libraryBook.Book.ContentType is ContentType.Episode)
{
- //Find the series that libraryBook, if it exists
- var series = bindingList.AllItems().Where(i => i is SeriesEntry).Cast().FirstOrDefault(i => libraryBook.Book.SeriesLink.Any(s => s.Series.Name == i.Series));
+ //Find the series that libraryBook belongs to, if it exists
+ var series = bindingList.AllItems().Series().FirstOrDefault(i => libraryBook.Book.SeriesLink.Any(s => s.Series.Name == i.Series));
if (series is null)
{
//Series doesn't exist yet, so create and add it
- var newSeries = new SeriesEntry { Children = new List { lb } };
+ var newSeries = new SeriesEntry { Children = new List { lb } };
newSeries.setSeriesBook(libraryBook.Book.SeriesLink.First());
lb.Parent = newSeries;
newSeries.Liberate.Expanded = true;
bindingList.Insert(0, newSeries);
+ series = newSeries;
}
else
{
lb.Parent = series;
series.Children.Add(lb);
}
+ //Add episode beneath the parent
+ int seriesIndex = bindingList.IndexOf(series);
+ bindingList.Insert(seriesIndex + 1, lb);
}
- //Add the new product
- bindingList.Insert(0, lb);
+ else
+ //Add the new product
+ bindingList.Insert(0, lb);
}
// update existing
else
@@ -195,24 +174,27 @@ namespace LibationWinForms
var removedBooks =
bindingList
.AllItems()
- .Where(i => i is LibraryBookEntry)
- .Cast()
+ .LibraryBooks()
.ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId);
+ foreach (var removed in removedBooks.Where(b => b.Parent is not null))
+ {
+ ((SeriesEntry)removed.Parent).Children.Remove(removed);
+ }
+
//Remove series that have no children
var removedSeries =
bindingList
.AllItems()
- .Where(i => i is SeriesEntry)
- .Cast()
- .Where(i => removedBooks.Count(r => r.Series == i.Series) == i.Children.Count);
+ .Series()
+ .Where(i => i.Children.Count == 0);
foreach (var removed in removedBooks.Cast().Concat(removedSeries))
//no need to re-filter for removed books
bindingList.Remove(removed);
if (bindingList.Count != visibleCount)
- VisibleCountChanged?.Invoke(this, bindingList.Count);
+ VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
#endregion
@@ -229,24 +211,19 @@ namespace LibationWinForms
gridEntryBindingSource.Filter = searchString;
if (visibleCount != bindingList.Count)
- VisibleCountChanged?.Invoke(this, bindingList.Count);
+ VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
+
}
#endregion
- internal IEnumerable GetVisible()
+ internal IEnumerable GetVisible()
=> bindingList
- .Where(row => row is LibraryBookEntry)
- .Cast()
- .Select(row => row.LibraryBook);
+ .LibraryBooks();
- #region Column Customizations
-
- // to ensure this is only ever called once: Load instead of 'override OnVisibleChanged'
private void ProductsGrid_Load(object sender, EventArgs e)
{
- if (this.DesignMode)
- return;
+ gridEntryDataGridView.ColumnWidthChanged += gridEntryDataGridView_ColumnWidthChanged;
contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns"));
contextMenuStrip1.Items.Add(new ToolStripSeparator());
@@ -259,7 +236,7 @@ namespace LibationWinForms
var cmsKiller = new ContextMenuStrip();
- foreach (DataGridViewColumn column in _dataGridView.Columns)
+ foreach (DataGridViewColumn column in gridEntryDataGridView.Columns)
{
var itemName = column.DataPropertyName;
var visible = gridColumnsVisibilities.GetValueOrDefault(itemName, true);
@@ -288,38 +265,19 @@ namespace LibationWinForms
//We must set DisplayIndex properties in ascending order
foreach (var itemName in displayIndices.OrderBy(i => i.Value).Select(i => i.Key))
{
- var column = _dataGridView.Columns
+ var column = gridEntryDataGridView.Columns
.Cast()
.Single(c => c.DataPropertyName == itemName);
column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index);
}
}
-
- private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
- {
- var config = Configuration.Instance;
-
- var dictionary = config.GridColumnsDisplayIndices;
- dictionary[e.Column.DataPropertyName] = e.Column.DisplayIndex;
- config.GridColumnsDisplayIndices = dictionary;
- }
-
- private void gridEntryDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
- {
- var config = Configuration.Instance;
-
- var dictionary = config.GridColumnsWidths;
- dictionary[e.Column.DataPropertyName] = e.Column.Width;
- config.GridColumnsWidths = dictionary;
- }
-
private void HideMenuItem_Click(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
var propertyName = menuItem.Tag as string;
- var column = _dataGridView.Columns
+ var column = gridEntryDataGridView.Columns
.Cast()
.FirstOrDefault(c => c.DataPropertyName == propertyName);
@@ -337,6 +295,15 @@ namespace LibationWinForms
}
}
+ private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
+ {
+ var config = Configuration.Instance;
+
+ var dictionary = config.GridColumnsDisplayIndices;
+ dictionary[e.Column.DataPropertyName] = e.Column.DisplayIndex;
+ config.GridColumnsDisplayIndices = dictionary;
+ }
+
private void gridEntryDataGridView_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e)
{
if (e.ColumnIndex == descriptionGVColumn.Index)
@@ -345,6 +312,12 @@ namespace LibationWinForms
e.ToolTipText = "Click to see full size";
}
- #endregion
+ private void gridEntryDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
+ {
+ var config = Configuration.Instance;
+
+ var dictionary = config.GridColumnsWidths;
+ dictionary[e.Column.DataPropertyName] = e.Column.Width;
+ }
}
}
diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/grid/ProductsGrid.resx
index be5db7af..2a349cc7 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.resx
+++ b/Source/LibationWinForms/grid/ProductsGrid.resx
@@ -57,7 +57,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
- 81
+
+ 17, 17
\ No newline at end of file
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/grid/SeriesEntry.cs
index 6a1e51b8..22252e7b 100644
--- a/Source/LibationWinForms/grid/SeriesEntry.cs
+++ b/Source/LibationWinForms/grid/SeriesEntry.cs
@@ -12,6 +12,7 @@ namespace LibationWinForms
{
internal class SeriesEntry : GridEntry
{
+ public List Children { get; set; }
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
public override string ProductRating { get; protected set; }
public override string PurchaseDate { get; protected set; }
@@ -24,7 +25,7 @@ namespace LibationWinForms
public override string Category { get; protected set; }
public override string Misc { get; protected set; }
public override string Description { get; protected set; }
- public override string DisplayTags => string.Empty;
+ public override string DisplayTags { get; } = string.Empty;
public override LiberateStatus Liberate => _liberate;
@@ -41,18 +42,17 @@ namespace LibationWinForms
// Immutable properties
{
- var childLB = Children.Cast();
- int bookLenMins = childLB.Sum(c => c.LibraryBook.Book.LengthInMinutes);
+ int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
- var myAverageRating = new Rating(childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), childLB.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
- var productAverageRating = new Rating(childLB.Average(c => c.LibraryBook.Book.Rating.OverallRating), childLB.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), childLB.Average(c => c.LibraryBook.Book.Rating.StoryRating));
+ var myAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
+ var productAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.Rating.StoryRating));
Title = SeriesBook.Series.Name;
Series = SeriesBook.Series.Name;
Length = bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
MyRating = myAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
- PurchaseDate = childLB.Min(c => c.LibraryBook.DateAdded).ToString("d");
+ PurchaseDate = Children.Min(c => c.LibraryBook.DateAdded).ToString("d");
ProductRating = productAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
Authors = Book.AuthorNames();
Narrators = Book.NarratorNames();
@@ -73,17 +73,17 @@ namespace LibationWinForms
{
{ nameof(Title), () => Book.SeriesSortable() },
{ nameof(Series), () => Book.SeriesSortable() },
- { nameof(Length), () => Children.Cast().Sum(c=>c.LibraryBook.Book.LengthInMinutes) },
- { nameof(MyRating), () => Children.Cast().Average(c=>c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
- { nameof(PurchaseDate), () => Children.Cast().Min(c=>c.LibraryBook.DateAdded) },
- { nameof(ProductRating), () => Children.Cast().Average(c => c.LibraryBook.Book.Rating.FirstScore()) },
+ { nameof(Length), () => Children.Sum(c=>c.LibraryBook.Book.LengthInMinutes) },
+ { nameof(MyRating), () => Children.Average(c=>c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
+ { nameof(PurchaseDate), () => Children.Min(c=>c.LibraryBook.DateAdded) },
+ { nameof(ProductRating), () => Children.Average(c => c.LibraryBook.Book.Rating.FirstScore()) },
{ nameof(Authors), () => string.Empty },
{ nameof(Narrators), () => string.Empty },
{ nameof(Description), () => string.Empty },
{ nameof(Category), () => string.Empty },
{ nameof(Misc), () => string.Empty },
{ nameof(DisplayTags), () => string.Empty },
- { nameof(Liberate), () => Liberate.BookStatus },
+ { nameof(Liberate), () => Liberate },
{ nameof(DateAdded), () => DateAdded },
};
}
diff --git a/Source/LibationWinForms/grid/SortableBindingList1.cs b/Source/LibationWinForms/grid/SortableBindingList1.cs
index 7d12819f..0a0606f5 100644
--- a/Source/LibationWinForms/grid/SortableBindingList1.cs
+++ b/Source/LibationWinForms/grid/SortableBindingList1.cs
@@ -3,8 +3,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace LibationWinForms
{
@@ -42,22 +40,20 @@ namespace LibationWinForms
{
List itemsList = (List)Items;
- //Array.Sort() and List.Sort() are unstable sorts. OrderBy is stable.
- var sortedItems = itemsList.OrderBy((ge) => ge, Comparer).ToList();
+ var sortedItems = Items.OrderBy(ge => ge, Comparer).ToList();
var children = sortedItems.Where(i => i.Parent is not null).ToList();
- var parents = sortedItems.Where(i => i.Children is not null).ToList();
-
- //Top Level items
- var topLevelItems = sortedItems.Except(children);
itemsList.Clear();
- itemsList.AddRange(topLevelItems);
- foreach (var p in parents)
+ //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));
+
+ foreach (var parent in children.Select(c => c.Parent).Distinct())
{
- var pIndex = itemsList.IndexOf(p);
- foreach (var c in children.Where(c=> c.Parent == p))
+ var pIndex = itemsList.IndexOf(parent);
+ foreach (var c in children.Where(c=> c.Parent == parent))
itemsList.Insert(++pIndex, c);
}
}
@@ -86,26 +82,5 @@ namespace LibationWinForms
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
-
- protected override int FindCore(PropertyDescriptor property, object key)
- {
- int count = Count;
-
- System.Collections.IComparer valueComparer = null;
-
- for (int i = 0; i < count; ++i)
- {
- var element = this[i];
- var elemValue = element.GetMemberValue(property.Name);
- valueComparer ??= element.GetMemberComparer(elemValue.GetType());
-
- if (valueComparer.Compare(elemValue, key) == 0)
- {
- return i;
- }
- }
-
- return -1;
- }
}
}
From 440550ded91817c05d19d440bd13031d35fe8da5 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 16:05:00 -0600
Subject: [PATCH 04/15] Add binding source at design time
---
.../EditTagsDataGridViewImageButtonColumn.cs | 2 +-
.../LiberateDataGridViewImageButtonColumn.cs | 4 +-
.../grid/ProductsDisplay.Designer.cs | 1 -
.../LibationWinForms/grid/ProductsDisplay.cs | 16 ++-----
.../grid/ProductsGrid.Designer.cs | 37 +++++++++++-----
Source/LibationWinForms/grid/ProductsGrid.cs | 26 ++++++-----
.../LibationWinForms/grid/ProductsGrid.resx | 9 ++++
Source/LibationWinForms/grid/SeriesEntry.cs | 44 +++++++++++++------
8 files changed, 87 insertions(+), 52 deletions(-)
diff --git a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
index db8bb484..b0d9407e 100644
--- a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
@@ -21,7 +21,7 @@ namespace LibationWinForms
{
if (rowIndex >= 0 && DataGridView.GetBoundItem(rowIndex) is SeriesEntry)
{
- base.Paint(graphics, clipBounds, cellBounds, rowIndex, DataGridViewElementStates.None, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
+ base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
return;
}
diff --git a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
index 159b1e4a..9d97dca9 100644
--- a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
@@ -25,13 +25,11 @@ namespace LibationWinForms
if (status.IsSeries)
{
var imageName = status.Expanded ? "minus" : "plus";
- var text = status.Expanded ? "Click to Collpase" : "Click to Expand";
var bmp = (Bitmap)Properties.Resources.ResourceManager.GetObject(imageName);
DrawButtonImage(graphics, bmp, cellBounds);
- ToolTipText = text;
-
+ ToolTipText = status.Expanded ? "Click to Collpase" : "Click to Expand";
}
else
{
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
index a10e1c95..8f561b0f 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
@@ -53,7 +53,6 @@
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsDisplay";
this.Size = new System.Drawing.Size(1510, 380);
- this.Load += new System.EventHandler(this.ProductsDisplay_Load);
this.ResumeLayout(false);
}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.cs b/Source/LibationWinForms/grid/ProductsDisplay.cs
index 0a9bee61..6fc37fa0 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.cs
+++ b/Source/LibationWinForms/grid/ProductsDisplay.cs
@@ -14,23 +14,18 @@ namespace LibationWinForms
{
public partial class ProductsDisplay : UserControl
{
- public event EventHandler LiberateClicked;
/// Number of visible rows has changed
public event EventHandler VisibleCountChanged;
+ public event EventHandler LiberateClicked;
+ public event EventHandler InitialLoaded;
+
+ private bool hasBeenDisplayed;
public ProductsDisplay()
{
InitializeComponent();
}
- private void ProductsDisplay_Load(object sender, EventArgs e)
- {
- if (DesignMode)
- return;
-
- }
-
-
#region Button controls
private ImageDisplay imageDisplay;
@@ -76,7 +71,6 @@ namespace LibationWinForms
displayWindow.Show(this);
}
-
private void productsGrid_DetailsClicked(LibraryBookEntry liveGridEntry)
{
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
@@ -88,8 +82,6 @@ namespace LibationWinForms
#region UI display functions
- private bool hasBeenDisplayed;
- public event EventHandler InitialLoaded;
public void Display()
{
// don't return early if lib size == 0. this will not update correctly if all books are removed
diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
index e818ed5b..cd312da0 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
@@ -29,7 +29,7 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
- System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
this.gridEntryDataGridView = new System.Windows.Forms.DataGridView();
this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn();
this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn();
@@ -46,7 +46,11 @@
this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.syncBindingSource = new LibationWinForms.SyncBindingSource(this.components);
+ this.bindingSource = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).BeginInit();
this.SuspendLayout();
//
// gridEntryDataGridView
@@ -55,6 +59,7 @@
this.gridEntryDataGridView.AllowUserToDeleteRows = false;
this.gridEntryDataGridView.AllowUserToOrderColumns = true;
this.gridEntryDataGridView.AllowUserToResizeRows = false;
+ this.gridEntryDataGridView.AutoGenerateColumns = false;
this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.liberateGVColumn,
@@ -72,14 +77,15 @@
this.miscGVColumn,
this.tagAndDetailsGVColumn});
this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1;
- dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
- dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
- dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
- dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
- dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
- dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
- dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
- this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle1;
+ this.gridEntryDataGridView.DataSource = this.syncBindingSource;
+ dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle2.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
+ dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText;
+ dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
+ this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle2;
this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.gridEntryDataGridView.Location = new System.Drawing.Point(0, 0);
this.gridEntryDataGridView.Name = "gridEntryDataGridView";
@@ -90,7 +96,6 @@
this.gridEntryDataGridView.TabIndex = 0;
this.gridEntryDataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellContentClick);
this.gridEntryDataGridView.CellToolTipTextNeeded += new System.Windows.Forms.DataGridViewCellToolTipTextNeededEventHandler(this.gridEntryDataGridView_CellToolTipTextNeeded);
- this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged);
//
// liberateGVColumn
//
@@ -209,6 +214,14 @@
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
//
+ // syncBindingSource
+ //
+ this.syncBindingSource.DataSource = this.bindingSource;
+ //
+ // bindingSource
+ //
+ this.bindingSource.DataSource = typeof(LibationWinForms.GridEntry);
+ //
// ProductsGrid
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
@@ -219,6 +232,8 @@
this.Size = new System.Drawing.Size(1510, 380);
this.Load += new System.EventHandler(this.ProductsGrid_Load);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).EndInit();
this.ResumeLayout(false);
}
@@ -241,5 +256,7 @@
private System.Windows.Forms.DataGridViewTextBoxColumn myRatingGVColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn;
private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn;
+ private SyncBindingSource syncBindingSource;
+ private System.Windows.Forms.BindingSource bindingSource;
}
}
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index b119285d..0593d743 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -24,15 +24,14 @@ namespace LibationWinForms.grid
public new event EventHandler Scroll;
private FilterableSortableBindingList bindingList;
- private SyncBindingSource gridEntryBindingSource;
+ internal IEnumerable GetVisible()
+ => bindingList
+ .LibraryBooks();
public ProductsGrid()
{
InitializeComponent();
EnableDoubleBuffering();
- //There a bug in designer that causes errors if you add BindingSource to the DataGridView at design time.
- gridEntryBindingSource = new SyncBindingSource();
- gridEntryDataGridView.DataSource = gridEntryBindingSource;
gridEntryDataGridView.Scroll += (_, s) => Scroll?.Invoke(this, s);
}
@@ -105,14 +104,14 @@ namespace LibationWinForms.grid
bindingList = new FilterableSortableBindingList(geList.OrderByDescending(e => e.DateAdded));
bindingList.CollapseAll();
- gridEntryBindingSource.DataSource = bindingList;
+ syncBindingSource.DataSource = bindingList;
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
internal void UpdateGrid(List dbBooks)
{
int visibleCount = bindingList.Count;
- string existingFilter = gridEntryBindingSource.Filter;
+ string existingFilter = syncBindingSource.Filter;
//Add absent books to grid, or update current books
@@ -206,9 +205,9 @@ namespace LibationWinForms.grid
int visibleCount = bindingList.Count;
if (string.IsNullOrEmpty(searchString))
- gridEntryBindingSource.RemoveFilter();
+ syncBindingSource.RemoveFilter();
else
- gridEntryBindingSource.Filter = searchString;
+ syncBindingSource.Filter = searchString;
if (visibleCount != bindingList.Count)
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
@@ -217,13 +216,15 @@ namespace LibationWinForms.grid
#endregion
- internal IEnumerable GetVisible()
- => bindingList
- .LibraryBooks();
+ #region Column Customizations
private void ProductsGrid_Load(object sender, EventArgs e)
{
+ //https://stackoverflow.com/a/4498512/3335599
+ if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) return;
+
gridEntryDataGridView.ColumnWidthChanged += gridEntryDataGridView_ColumnWidthChanged;
+ gridEntryDataGridView.ColumnDisplayIndexChanged += gridEntryDataGridView_ColumnDisplayIndexChanged;
contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns"));
contextMenuStrip1.Items.Add(new ToolStripSeparator());
@@ -272,6 +273,7 @@ namespace LibationWinForms.grid
column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index);
}
}
+
private void HideMenuItem_Click(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
@@ -319,5 +321,7 @@ namespace LibationWinForms.grid
var dictionary = config.GridColumnsWidths;
dictionary[e.Column.DataPropertyName] = e.Column.Width;
}
+
+ #endregion
}
}
diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/grid/ProductsGrid.resx
index 2a349cc7..bc15cd01 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.resx
+++ b/Source/LibationWinForms/grid/ProductsGrid.resx
@@ -58,6 +58,15 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ 171, 17
+
+
17, 17
+
+ 326, 17
+
+
+ 326, 17
+
\ No newline at end of file
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/grid/SeriesEntry.cs
index 22252e7b..afe21444 100644
--- a/Source/LibationWinForms/grid/SeriesEntry.cs
+++ b/Source/LibationWinForms/grid/SeriesEntry.cs
@@ -14,17 +14,41 @@ namespace LibationWinForms
{
public List Children { get; set; }
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
- public override string ProductRating { get; protected set; }
+ public override string ProductRating
+ {
+ get
+ {
+ var productAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.Rating.StoryRating));
+ return productAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ }
+ protected set => throw new NotImplementedException();
+ }
public override string PurchaseDate { get; protected set; }
- public override string MyRating { get; protected set; }
+ public override string MyRating
+ {
+ get
+ {
+ var myAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
+ return myAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
+ }
+ protected set => throw new NotImplementedException();
+ }
public override string Series { get; protected set; }
public override string Title { get; protected set; }
- public override string Length { get; protected set; }
+ public override string Length
+ {
+ get
+ {
+ int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
+ return bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
+ }
+ protected set => throw new NotImplementedException();
+ }
public override string Authors { get; protected set; }
public override string Narrators { get; protected set; }
public override string Category { get; protected set; }
- public override string Misc { get; protected set; }
- public override string Description { get; protected set; }
+ public override string Misc { get; protected set; } = string.Empty;
+ public override string Description { get; protected set; } = string.Empty;
public override string DisplayTags { get; } = string.Empty;
public override LiberateStatus Liberate => _liberate;
@@ -34,6 +58,7 @@ namespace LibationWinForms
private SeriesBook SeriesBook { get; set; }
private LiberateStatus _liberate = new LiberateStatus { IsSeries = true };
+
public void setSeriesBook(SeriesBook seriesBook)
{
SeriesBook = seriesBook;
@@ -42,18 +67,9 @@ namespace LibationWinForms
// Immutable properties
{
- int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
-
- var myAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
- var productAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.Rating.StoryRating));
-
-
Title = SeriesBook.Series.Name;
Series = SeriesBook.Series.Name;
- Length = bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
- MyRating = myAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
PurchaseDate = Children.Min(c => c.LibraryBook.DateAdded).ToString("d");
- ProductRating = productAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
Authors = Book.AuthorNames();
Narrators = Book.NarratorNames();
Category = string.Join(" > ", Book.CategoriesNames());
From 718d21f6cb7dabff7726a4bc7078909877b5c0e6 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 16:42:05 -0600
Subject: [PATCH 05/15] NotifyPropertyChanged series on update
---
Source/LibationWinForms/grid/GridEntry.cs | 8 ++++----
.../grid/LiberateDataGridViewImageButtonColumn.cs | 2 +-
Source/LibationWinForms/grid/LibraryBookEntry.cs | 4 ++--
Source/LibationWinForms/grid/ProductsGrid.cs | 6 +++++-
Source/LibationWinForms/grid/SeriesEntry.cs | 8 ++------
5 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs
index e0f19c1c..5c53f7e9 100644
--- a/Source/LibationWinForms/grid/GridEntry.cs
+++ b/Source/LibationWinForms/grid/GridEntry.cs
@@ -15,7 +15,7 @@ namespace LibationWinForms
T Parent { get; }
}
- public class LiberateStatus : IComparable
+ public class LiberateButtonStatus : IComparable
{
public LiberatedStatus BookStatus;
public LiberatedStatus? PdfStatus;
@@ -24,7 +24,7 @@ namespace LibationWinForms
public int CompareTo(object obj)
{
- if (obj is not LiberateStatus second) return -1;
+ if (obj is not LiberateButtonStatus second) return -1;
if (IsSeries && !second.IsSeries) return -1;
else if (!IsSeries && second.IsSeries) return 1;
@@ -69,7 +69,7 @@ namespace LibationWinForms
public abstract string Misc { get; protected set; }
public abstract string Description { get; protected set; }
public abstract string DisplayTags { get; }
- public abstract LiberateStatus Liberate { get; }
+ public abstract LiberateButtonStatus Liberate { get; }
public abstract object GetMemberValue(string memberName);
#endregion
public IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
@@ -105,7 +105,7 @@ namespace LibationWinForms
{ typeof(float), new ObjectComparer() },
{ typeof(bool), new ObjectComparer() },
{ typeof(DateTime), new ObjectComparer() },
- { typeof(LiberateStatus), new ObjectComparer() },
+ { typeof(LiberateButtonStatus), new ObjectComparer() },
};
~GridEntry()
diff --git a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
index 9d97dca9..feb9b0e0 100644
--- a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
@@ -20,7 +20,7 @@ namespace LibationWinForms
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
- if (value is LiberateStatus status)
+ if (value is LiberateButtonStatus status)
{
if (status.IsSeries)
{
diff --git a/Source/LibationWinForms/grid/LibraryBookEntry.cs b/Source/LibationWinForms/grid/LibraryBookEntry.cs
index c1be718c..a02686eb 100644
--- a/Source/LibationWinForms/grid/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/grid/LibraryBookEntry.cs
@@ -53,7 +53,7 @@ namespace LibationWinForms
public override string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
// these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
- public override LiberateStatus Liberate
+ public override LiberateButtonStatus Liberate
{
get
{
@@ -64,7 +64,7 @@ namespace LibationWinForms
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
lastStatusUpdate = DateTime.Now;
}
- return new LiberateStatus { BookStatus = _bookStatus, PdfStatus = _pdfStatus, IsSeries = false };
+ return new LiberateButtonStatus { BookStatus = _bookStatus, PdfStatus = _pdfStatus, IsSeries = false };
}
}
#endregion
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index 0593d743..f42a6de1 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -149,6 +149,8 @@ namespace LibationWinForms.grid
//Add episode beneath the parent
int seriesIndex = bindingList.IndexOf(series);
bindingList.Insert(seriesIndex + 1, lb);
+
+ series.NotifyPropertyChanged();
}
else
//Add the new product
@@ -178,7 +180,9 @@ namespace LibationWinForms.grid
foreach (var removed in removedBooks.Where(b => b.Parent is not null))
{
- ((SeriesEntry)removed.Parent).Children.Remove(removed);
+ var series = removed.Parent as SeriesEntry;
+ series.Children.Remove(removed);
+ series.NotifyPropertyChanged();
}
//Remove series that have no children
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/grid/SeriesEntry.cs
index afe21444..bc74f147 100644
--- a/Source/LibationWinForms/grid/SeriesEntry.cs
+++ b/Source/LibationWinForms/grid/SeriesEntry.cs
@@ -1,12 +1,8 @@
using DataLayer;
using Dinah.Core;
using System;
-using System.Collections;
using System.Collections.Generic;
-using System.Drawing;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace LibationWinForms
{
@@ -51,13 +47,13 @@ namespace LibationWinForms
public override string Description { get; protected set; } = string.Empty;
public override string DisplayTags { get; } = string.Empty;
- public override LiberateStatus Liberate => _liberate;
+ public override LiberateButtonStatus Liberate => _liberate;
protected override Book Book => SeriesBook.Book;
private SeriesBook SeriesBook { get; set; }
- private LiberateStatus _liberate = new LiberateStatus { IsSeries = true };
+ private LiberateButtonStatus _liberate = new LiberateButtonStatus { IsSeries = true };
public void setSeriesBook(SeriesBook seriesBook)
{
From f29dff33868c2ebd9c9c72460ed83b954247023f Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 17:22:02 -0600
Subject: [PATCH 06/15] Fix filtering bug
---
Source/LibationWinForms/grid/ProductsGrid.cs | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index f42a6de1..f0fc1497 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -110,8 +110,8 @@ namespace LibationWinForms.grid
internal void UpdateGrid(List dbBooks)
{
- int visibleCount = bindingList.Count;
string existingFilter = syncBindingSource.Filter;
+ Filter(null);
//Add absent books to grid, or update current books
@@ -150,6 +150,11 @@ namespace LibationWinForms.grid
int seriesIndex = bindingList.IndexOf(series);
bindingList.Insert(seriesIndex + 1, lb);
+ if (series.Liberate.Expanded)
+ bindingList.ExpandItem(series);
+ else
+ bindingList.CollapseItem(series);
+
series.NotifyPropertyChanged();
}
else
@@ -163,13 +168,6 @@ namespace LibationWinForms.grid
}
}
- if (bindingList.Count != visibleCount)
- {
- //re-filter for newly added items
- Filter(null);
- Filter(existingFilter);
- }
-
// remove deleted from grid.
// note: actual deletion from db must still occur via the RemoveBook feature. deleting from audible will not trigger this
var removedBooks =
@@ -196,8 +194,9 @@ namespace LibationWinForms.grid
//no need to re-filter for removed books
bindingList.Remove(removed);
- if (bindingList.Count != visibleCount)
- VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
+ Filter(existingFilter);
+
+ VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
#endregion
From 4a82541ffdaa9ffa95e91a93a0b52da2f6ef3296 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 17:46:55 -0600
Subject: [PATCH 07/15] Fix error while removing filter on a sorted binding
list
---
Source/LibationWinForms/grid/FilterableSortableBindingList.cs | 4 ++++
Source/LibationWinForms/grid/SortableBindingList1.cs | 3 ++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
index e309f7fe..dcb70524 100644
--- a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
+++ b/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
@@ -120,6 +120,8 @@ namespace LibationWinForms
int visibleCount = Items.Count;
+ SuspendSorting = true;
+
foreach (var item in FilterRemoved.ToList())
{
if (item.Parent is null || item.Parent.Liberate.Expanded)
@@ -129,6 +131,8 @@ namespace LibationWinForms
}
}
+ SuspendSorting = false;
+
if (IsSortedCore)
Sort();
else
diff --git a/Source/LibationWinForms/grid/SortableBindingList1.cs b/Source/LibationWinForms/grid/SortableBindingList1.cs
index 0a0606f5..ec545340 100644
--- a/Source/LibationWinForms/grid/SortableBindingList1.cs
+++ b/Source/LibationWinForms/grid/SortableBindingList1.cs
@@ -15,6 +15,7 @@ namespace LibationWinForms
public SortableBindingList1() : base(new List()) { }
public SortableBindingList1(IEnumerable enumeration) : base(new List(enumeration)) { }
+ protected bool SuspendSorting { get; set; }
protected MemberComparer Comparer { get; } = new();
protected override bool SupportsSortingCore => true;
protected override bool SupportsSearchingCore => true;
@@ -60,7 +61,7 @@ namespace LibationWinForms
protected override void OnListChanged(ListChangedEventArgs e)
{
- if (isSorted &&
+ if (isSorted && !SuspendSorting &&
((e.ListChangedType == ListChangedType.ItemChanged && e.PropertyDescriptor == SortPropertyCore) ||
e.ListChangedType == ListChangedType.ItemAdded))
{
From d71cdecd35a45756112b88da91f1e271ed2a6a7d Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 21:20:26 -0600
Subject: [PATCH 08/15] Refactoring and addressing comments
---
Source/AppScaffolding/AppScaffolding.csproj | 2 +-
Source/LibationWinForms/Form1.Designer.cs | 26 ++---
Source/LibationWinForms/Form1.resx | 36 +++++++
.../ProcessQueue/ProcessQueueControl.cs | 13 ++-
.../ProcessQueue/VirtualFlowControl.cs | 3 -
Source/LibationWinForms/grid/GridEntry.cs | 41 ++-----
...BindingList.cs => GridEntryBindingList.cs} | 101 +++++++++++++++---
.../grid/LiberateButtonStatus.cs | 28 +++++
.../LibationWinForms/grid/LibraryBookEntry.cs | 9 +-
.../grid/ProductsGrid.Designer.cs | 10 +-
Source/LibationWinForms/grid/ProductsGrid.cs | 50 ++++-----
Source/LibationWinForms/grid/SeriesEntry.cs | 17 ++-
.../grid/SortableBindingList1.cs | 87 ---------------
13 files changed, 218 insertions(+), 205 deletions(-)
rename Source/LibationWinForms/grid/{FilterableSortableBindingList.cs => GridEntryBindingList.cs} (56%)
create mode 100644 Source/LibationWinForms/grid/LiberateButtonStatus.cs
delete mode 100644 Source/LibationWinForms/grid/SortableBindingList1.cs
diff --git a/Source/AppScaffolding/AppScaffolding.csproj b/Source/AppScaffolding/AppScaffolding.csproj
index db37ad59..37d7e6ca 100644
--- a/Source/AppScaffolding/AppScaffolding.csproj
+++ b/Source/AppScaffolding/AppScaffolding.csproj
@@ -3,7 +3,7 @@
net6.0-windows
- 7.7.0.14
+ 7.7.1.1
diff --git a/Source/LibationWinForms/Form1.Designer.cs b/Source/LibationWinForms/Form1.Designer.cs
index 98a7b9f7..49c41b42 100644
--- a/Source/LibationWinForms/Form1.Designer.cs
+++ b/Source/LibationWinForms/Form1.Designer.cs
@@ -98,7 +98,7 @@
// filterBtn
//
this.filterBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.filterBtn.Location = new System.Drawing.Point(748, 3);
+ this.filterBtn.Location = new System.Drawing.Point(916, 3);
this.filterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.filterBtn.Name = "filterBtn";
this.filterBtn.Size = new System.Drawing.Size(88, 27);
@@ -114,7 +114,7 @@
this.filterSearchTb.Location = new System.Drawing.Point(196, 7);
this.filterSearchTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.filterSearchTb.Name = "filterSearchTb";
- this.filterSearchTb.Size = new System.Drawing.Size(544, 23);
+ this.filterSearchTb.Size = new System.Drawing.Size(712, 23);
this.filterSearchTb.TabIndex = 1;
this.filterSearchTb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filterSearchTb_KeyPress);
//
@@ -132,7 +132,7 @@
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2);
- this.menuStrip1.Size = new System.Drawing.Size(893, 24);
+ this.menuStrip1.Size = new System.Drawing.Size(1061, 24);
this.menuStrip1.TabIndex = 0;
this.menuStrip1.Text = "menuStrip1";
//
@@ -396,7 +396,7 @@
this.statusStrip1.Location = new System.Drawing.Point(0, 618);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0);
- this.statusStrip1.Size = new System.Drawing.Size(893, 22);
+ this.statusStrip1.Size = new System.Drawing.Size(1061, 22);
this.statusStrip1.TabIndex = 6;
this.statusStrip1.Text = "statusStrip1";
//
@@ -410,7 +410,7 @@
// springLbl
//
this.springLbl.Name = "springLbl";
- this.springLbl.Size = new System.Drawing.Size(379, 17);
+ this.springLbl.Size = new System.Drawing.Size(547, 17);
this.springLbl.Spring = true;
//
// backupsCountsLbl
@@ -452,8 +452,8 @@
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.processBookQueue1);
- this.splitContainer1.Size = new System.Drawing.Size(1231, 640);
- this.splitContainer1.SplitterDistance = 893;
+ this.splitContainer1.Size = new System.Drawing.Size(1463, 640);
+ this.splitContainer1.SplitterDistance = 1061;
this.splitContainer1.SplitterWidth = 8;
this.splitContainer1.TabIndex = 7;
//
@@ -470,7 +470,7 @@
this.panel1.Location = new System.Drawing.Point(0, 24);
this.panel1.Margin = new System.Windows.Forms.Padding(0);
this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(893, 594);
+ this.panel1.Size = new System.Drawing.Size(1061, 594);
this.panel1.TabIndex = 7;
//
// productsDisplay
@@ -482,16 +482,16 @@
this.productsDisplay.Location = new System.Drawing.Point(15, 36);
this.productsDisplay.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.productsDisplay.Name = "productsDisplay";
- this.productsDisplay.Size = new System.Drawing.Size(863, 555);
+ this.productsDisplay.Size = new System.Drawing.Size(1031, 555);
this.productsDisplay.TabIndex = 9;
- this.productsDisplay.LiberateClicked += new System.EventHandler(this.ProductsDisplay_LiberateClicked);
this.productsDisplay.VisibleCountChanged += new System.EventHandler(this.productsDisplay_VisibleCountChanged);
+ this.productsDisplay.LiberateClicked += new System.EventHandler(this.ProductsDisplay_LiberateClicked);
this.productsDisplay.InitialLoaded += new System.EventHandler(this.productsDisplay_InitialLoaded);
//
// toggleQueueHideBtn
//
this.toggleQueueHideBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
- this.toggleQueueHideBtn.Location = new System.Drawing.Point(845, 3);
+ this.toggleQueueHideBtn.Location = new System.Drawing.Point(1013, 3);
this.toggleQueueHideBtn.Margin = new System.Windows.Forms.Padding(4, 3, 15, 3);
this.toggleQueueHideBtn.Name = "toggleQueueHideBtn";
this.toggleQueueHideBtn.Size = new System.Drawing.Size(33, 27);
@@ -507,14 +507,14 @@
this.processBookQueue1.Location = new System.Drawing.Point(0, 0);
this.processBookQueue1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.processBookQueue1.Name = "processBookQueue1";
- this.processBookQueue1.Size = new System.Drawing.Size(330, 640);
+ this.processBookQueue1.Size = new System.Drawing.Size(394, 640);
this.processBookQueue1.TabIndex = 0;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(1231, 640);
+ this.ClientSize = new System.Drawing.Size(1463, 640);
this.Controls.Add(this.splitContainer1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.menuStrip1;
diff --git a/Source/LibationWinForms/Form1.resx b/Source/LibationWinForms/Form1.resx
index 64da6d15..2505fa27 100644
--- a/Source/LibationWinForms/Form1.resx
+++ b/Source/LibationWinForms/Form1.resx
@@ -57,12 +57,48 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ True
+
+
+ True
+
+
+ True
+
17, 17
+
+ True
+
132, 17
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
index 88c309a3..9acf1eb4 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
@@ -46,24 +46,31 @@ namespace LibationWinForms.ProcessQueue
public ProcessQueueControl()
{
InitializeComponent();
- Logger = LogMe.RegisterForm(this);
- runningTimeLbl.Text = string.Empty;
popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
popoutBtn.Name = "popoutBtn";
popoutBtn.Text = "Pop Out";
popoutBtn.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
popoutBtn.Alignment = ToolStripItemAlignment.Right;
popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
-
statusStrip1.Items.Add(popoutBtn);
+ Logger = LogMe.RegisterForm(this);
+
virtualFlowControl2.RequestData += VirtualFlowControl1_RequestData;
virtualFlowControl2.ButtonClicked += VirtualFlowControl2_ButtonClicked;
Queue.QueuededCountChanged += Queue_QueuededCountChanged;
Queue.CompletedCountChanged += Queue_CompletedCountChanged;
+ Load += ProcessQueueControl_Load;
+ }
+
+ private void ProcessQueueControl_Load(object sender, EventArgs e)
+ {
+ if (DesignMode) return;
+
+ runningTimeLbl.Text = string.Empty;
QueuedCount = 0;
ErrorCount = 0;
CompletedCount = 0;
diff --git a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
index 296e34bf..3c146703 100644
--- a/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
@@ -114,9 +114,6 @@ namespace LibationWinForms.ProcessQueue
BookControls.Add(control);
panel1.Controls.Add(control);
- if (DesignMode)
- return;
-
for (int i = 1; i < NUM_ACTUAL_CONTROLS; i++)
{
control = InitControl(VirtualControlHeight * i);
diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs
index 5c53f7e9..d26ae575 100644
--- a/Source/LibationWinForms/grid/GridEntry.cs
+++ b/Source/LibationWinForms/grid/GridEntry.cs
@@ -5,37 +5,12 @@ using LibationFileManager;
using System;
using System.Collections;
using System.Collections.Generic;
-using System.ComponentModel;using System.Drawing;
+using System.Drawing;
using System.Linq;
namespace LibationWinForms
{
- public interface IHierarchical where T : class
- {
- T Parent { get; }
- }
-
- public class LiberateButtonStatus : IComparable
- {
- public LiberatedStatus BookStatus;
- public LiberatedStatus? PdfStatus;
- public bool IsSeries;
- public bool Expanded;
-
- public int CompareTo(object obj)
- {
- if (obj is not LiberateButtonStatus second) return -1;
-
- if (IsSeries && !second.IsSeries) return -1;
- else if (!IsSeries && second.IsSeries) return 1;
- else if (IsSeries && second.IsSeries) return 0;
- else if (BookStatus == LiberatedStatus.Liberated && second.BookStatus != LiberatedStatus.Liberated) return -1;
- else if (BookStatus != LiberatedStatus.Liberated && second.BookStatus == LiberatedStatus.Liberated) return 1;
- else return BookStatus.CompareTo(second.BookStatus);
- }
- }
-
- public abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable, IHierarchical
+ public abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
{
protected abstract Book Book { get; }
@@ -50,12 +25,7 @@ namespace LibationWinForms
NotifyPropertyChanged();
}
}
-
- [Browsable(false)]
public new bool InvokeRequired => base.InvokeRequired;
- [Browsable(false)]
- public GridEntry Parent { get; set; }
- [Browsable(false)]
public abstract DateTime DateAdded { get; }
public abstract string ProductRating { get; protected set; }
public abstract string PurchaseDate { get; protected set; }
@@ -116,9 +86,16 @@ namespace LibationWinForms
internal static class GridEntryExtensions
{
+ #nullable enable
public static IEnumerable Series(this IEnumerable gridEntries)
=> gridEntries.Where(i => i is SeriesEntry).Cast();
public static IEnumerable LibraryBooks(this IEnumerable gridEntries)
=> gridEntries.Where(i => i is LibraryBookEntry).Cast();
+ public static LibraryBookEntry? FindBookByAsin(this IEnumerable gridEntries, string audibleProductID)
+ => gridEntries.FirstOrDefault(i => i.AudibleProductId == audibleProductID);
+ public static SeriesEntry? FindBookSeriesEntry(this IEnumerable gridEntries, IEnumerable matchSeries)
+ => gridEntries.Series().FirstOrDefault(i => matchSeries.Any(s => s.Series.Name == i.Series));
+ public static IEnumerable EmptySeries(this IEnumerable gridEntries)
+ => gridEntries.Series().Where(i => i.Children.Count == 0);
}
}
diff --git a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs b/Source/LibationWinForms/grid/GridEntryBindingList.cs
similarity index 56%
rename from Source/LibationWinForms/grid/FilterableSortableBindingList.cs
rename to Source/LibationWinForms/grid/GridEntryBindingList.cs
index dcb70524..fb6f7df7 100644
--- a/Source/LibationWinForms/grid/FilterableSortableBindingList.cs
+++ b/Source/LibationWinForms/grid/GridEntryBindingList.cs
@@ -8,7 +8,7 @@ using System.Linq;
namespace LibationWinForms
{
/*
- * Allows filtering of the underlying SortableBindingList
+ * Allows filtering and sorting of the underlying BindingList
* by implementing IBindingListView and using SearchEngineCommands
*
* When filtering is applied, the filtered-out items are removed
@@ -19,19 +19,34 @@ namespace LibationWinForms
* Remove is overridden to ensure that removed items are removed from
* the base list (visible items) as well as the FilterRemoved list.
*/
- internal class FilterableSortableBindingList : SortableBindingList1, IBindingListView
+ internal class GridEntryBindingList : BindingList, IBindingListView
{
+ private bool isSorted;
+ private ListSortDirection listSortDirection;
+ private PropertyDescriptor propertyDescriptor;
+
+ public GridEntryBindingList() : base(new List()) { }
+ public GridEntryBindingList(IEnumerable enumeration) : base(new List(enumeration)) { }
+
+ /// All items in the list, including those filtered out.
+ public List AllItems() => Items.Concat(FilterRemoved).ToList();
+
+ protected MemberComparer Comparer { get; } = new();
+ protected override bool SupportsSortingCore => true;
+ protected override bool SupportsSearchingCore => true;
+ 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); }
+
///
/// Items that were removed from the base list due to filtering
///
private readonly List FilterRemoved = new();
private string FilterString;
private LibationSearchEngine.SearchResultSet SearchResults;
- public FilterableSortableBindingList(IEnumerable enumeration) : base(enumeration) { }
- public FilterableSortableBindingList() : base(new List()) { }
- public bool SupportsFiltering => true;
- public string Filter { get => FilterString; set => ApplyFilter(value); }
#region Unused - Advanced Filtering
public bool SupportsAdvancedSorting => false;
@@ -49,9 +64,6 @@ namespace LibationWinForms
base.Remove(entry);
}
- /// All items in the list, including those filtered out.
- public List AllItems() => Items.Concat(FilterRemoved).ToList();
-
private void ApplyFilter(string filterString)
{
if (filterString != FilterString)
@@ -88,7 +100,7 @@ namespace LibationWinForms
public void CollapseItem(SeriesEntry sEntry)
{
- foreach (var episode in Items.Where(b => b.Parent == sEntry).Cast().ToList())
+ foreach (var episode in Items.LibraryBooks().Where(b => b.Parent == sEntry).ToList())
{
FilterRemoved.Add(episode);
base.Remove(episode);
@@ -101,7 +113,7 @@ namespace LibationWinForms
{
var sindex = Items.IndexOf(sEntry);
- foreach (var episode in FilterRemoved.Where(b => b.Parent == sEntry).Cast().ToList())
+ foreach (var episode in FilterRemoved.LibraryBooks().Where(b => b.Parent == sEntry).ToList())
{
if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
{
@@ -120,23 +132,19 @@ namespace LibationWinForms
int visibleCount = Items.Count;
- SuspendSorting = true;
-
foreach (var item in FilterRemoved.ToList())
{
- if (item.Parent is null || item.Parent.Liberate.Expanded)
+ if (item is SeriesEntry || (item is LibraryBookEntry lbe && (lbe.Parent is null || lbe.Parent.Liberate.Expanded)))
{
FilterRemoved.Remove(item);
base.InsertItem(visibleCount++, item);
}
}
- SuspendSorting = false;
-
if (IsSortedCore)
Sort();
else
- //No user sort is applied, so do default sorting by PurchaseDate, descending
+ //No user sort is applied, so do default sorting by DateAdded, descending
{
Comparer.PropertyName = nameof(GridEntry.DateAdded);
Comparer.Direction = ListSortDirection.Descending;
@@ -148,5 +156,64 @@ namespace LibationWinForms
FilterString = null;
SearchResults = null;
}
+
+ protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
+ {
+ Comparer.PropertyName = property.Name;
+ Comparer.Direction = direction;
+
+ Sort();
+
+ propertyDescriptor = property;
+ listSortDirection = direction;
+ isSorted = true;
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+ }
+
+ protected void Sort()
+ {
+ var itemsList = (List)Items;
+
+ var sortedItems = Items.OrderBy(ge => ge, Comparer).ToList();
+
+ var children = sortedItems.LibraryBooks().Where(i => i.Parent is not null).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));
+
+ 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))
+ itemsList.Insert(++pIndex, c);
+ }
+ }
+
+ protected override void OnListChanged(ListChangedEventArgs e)
+ {
+ if (isSorted && e.ListChangedType == ListChangedType.ItemChanged && e.PropertyDescriptor == SortPropertyCore)
+ {
+ var item = Items[e.NewIndex];
+ Sort();
+ var newIndex = Items.IndexOf(item);
+
+ base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
+ }
+ else
+ base.OnListChanged(e);
+ }
+
+ protected override void RemoveSortCore()
+ {
+ isSorted = false;
+ propertyDescriptor = base.SortPropertyCore;
+ listSortDirection = base.SortDirectionCore;
+
+ OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
+ }
}
}
diff --git a/Source/LibationWinForms/grid/LiberateButtonStatus.cs b/Source/LibationWinForms/grid/LiberateButtonStatus.cs
new file mode 100644
index 00000000..8814eb24
--- /dev/null
+++ b/Source/LibationWinForms/grid/LiberateButtonStatus.cs
@@ -0,0 +1,28 @@
+using DataLayer;
+using System;
+
+namespace LibationWinForms
+{
+ public class LiberateButtonStatus : IComparable
+ {
+ public LiberatedStatus BookStatus { get; set; }
+ public LiberatedStatus? PdfStatus { get; set; }
+ public bool IsSeries { get; init; }
+ public bool Expanded { get; set; }
+
+ ///
+ /// Defines the Liberate column's sorting behavior
+ ///
+ public int CompareTo(object obj)
+ {
+ if (obj is not LiberateButtonStatus second) return -1;
+
+ if (IsSeries && !second.IsSeries) return -1;
+ else if (!IsSeries && second.IsSeries) return 1;
+ else if (IsSeries && second.IsSeries) return 0;
+ else if (BookStatus == LiberatedStatus.Liberated && second.BookStatus != LiberatedStatus.Liberated) return -1;
+ else if (BookStatus != LiberatedStatus.Liberated && second.BookStatus == LiberatedStatus.Liberated) return 1;
+ else return BookStatus.CompareTo(second.BookStatus);
+ }
+ }
+}
diff --git a/Source/LibationWinForms/grid/LibraryBookEntry.cs b/Source/LibationWinForms/grid/LibraryBookEntry.cs
index a02686eb..3834e502 100644
--- a/Source/LibationWinForms/grid/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/grid/LibraryBookEntry.cs
@@ -1,16 +1,10 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
-using System.Drawing;
using System.Linq;
using ApplicationServices;
using DataLayer;
-using Dinah.Core.DataBinding;
using Dinah.Core;
-using Dinah.Core.Drawing;
-using LibationFileManager;
-using System.Threading.Tasks;
namespace LibationWinForms
{
@@ -30,7 +24,6 @@ namespace LibationWinForms
public string LongDescription { get; private set; }
#endregion
- // alias
protected override Book Book => LibraryBook.Book;
#region Model properties exposed to the view
@@ -69,9 +62,9 @@ namespace LibationWinForms
}
#endregion
-
public LibraryBookEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
+ public SeriesEntry Parent { get; init; }
public void UpdateLibraryBook(LibraryBook libraryBook)
{
if (AudibleProductId != libraryBook.Book.AudibleProductId)
diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
index cd312da0..fec72094 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
@@ -47,10 +47,8 @@
this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.syncBindingSource = new LibationWinForms.SyncBindingSource(this.components);
- this.bindingSource = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).BeginInit();
- ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).BeginInit();
this.SuspendLayout();
//
// gridEntryDataGridView
@@ -216,11 +214,7 @@
//
// syncBindingSource
//
- this.syncBindingSource.DataSource = this.bindingSource;
- //
- // bindingSource
- //
- this.bindingSource.DataSource = typeof(LibationWinForms.GridEntry);
+ this.syncBindingSource.DataSource = typeof(LibationWinForms.GridEntry);
//
// ProductsGrid
//
@@ -233,7 +227,6 @@
this.Load += new System.EventHandler(this.ProductsGrid_Load);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).EndInit();
- ((System.ComponentModel.ISupportInitialize)(this.bindingSource)).EndInit();
this.ResumeLayout(false);
}
@@ -257,6 +250,5 @@
private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn;
private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn;
private SyncBindingSource syncBindingSource;
- private System.Windows.Forms.BindingSource bindingSource;
}
}
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs
index f0fc1497..8e3cfe8d 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/grid/ProductsGrid.cs
@@ -23,7 +23,7 @@ namespace LibationWinForms.grid
public event LibraryBookEntryRectangleClickedEventHandler DescriptionClicked;
public new event EventHandler Scroll;
- private FilterableSortableBindingList bindingList;
+ private GridEntryBindingList bindingList;
internal IEnumerable GetVisible()
=> bindingList
.LibraryBooks();
@@ -89,20 +89,15 @@ namespace LibationWinForms.grid
var episodes = dbBooks.Where(b => b.Book.ContentType is ContentType.Episode).ToList();
- var series = episodes.Select(lb => lb.Book.SeriesLink.First()).DistinctBy(s => s.Series).ToList();
-
- foreach (var s in series)
+ foreach (var series in episodes.Select(lb => lb.Book.SeriesLink.First()).DistinctBy(s => s.Series))
{
- var seriesEntry = new SeriesEntry();
- seriesEntry.Children = episodes.Where(lb => lb.Book.SeriesLink.First().Series == s.Book.SeriesLink.First().Series).Select(lb => new LibraryBookEntry(lb) { Parent = seriesEntry }).ToList();
-
- seriesEntry.setSeriesBook(s);
+ var seriesEntry = new SeriesEntry(series, episodes.Where(lb => lb.Book.SeriesLink.First().Series == series.Book.SeriesLink.First().Series));
geList.Add(seriesEntry);
geList.AddRange(seriesEntry.Children);
}
- bindingList = new FilterableSortableBindingList(geList.OrderByDescending(e => e.DateAdded));
+ bindingList = new GridEntryBindingList(geList.OrderByDescending(e => e.DateAdded));
bindingList.CollapseAll();
syncBindingSource.DataSource = bindingList;
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
@@ -116,39 +111,36 @@ namespace LibationWinForms.grid
//Add absent books to grid, or update current books
var allItmes = bindingList.AllItems().LibraryBooks();
- for (var i = dbBooks.Count - 1; i >= 0; i--)
+ foreach (var libraryBook in dbBooks)
{
- var libraryBook = dbBooks[i];
- var existingItem = allItmes.FirstOrDefault(i => i.AudibleProductId == libraryBook.Book.AudibleProductId);
+ var existingItem = allItmes.FindBookByAsin(libraryBook.Book.AudibleProductId);
// add new to top
if (existingItem is null)
{
- var lb = new LibraryBookEntry(libraryBook);
-
if (libraryBook.Book.ContentType is ContentType.Episode)
{
+ LibraryBookEntry lbe;
//Find the series that libraryBook belongs to, if it exists
- var series = bindingList.AllItems().Series().FirstOrDefault(i => libraryBook.Book.SeriesLink.Any(s => s.Series.Name == i.Series));
+ var series = bindingList.AllItems().FindBookSeriesEntry(libraryBook.Book.SeriesLink);
if (series is null)
{
//Series doesn't exist yet, so create and add it
- var newSeries = new SeriesEntry { Children = new List { lb } };
- newSeries.setSeriesBook(libraryBook.Book.SeriesLink.First());
- lb.Parent = newSeries;
+ var newSeries = new SeriesEntry(libraryBook.Book.SeriesLink.First(), libraryBook);
+ lbe = newSeries.Children[0];
newSeries.Liberate.Expanded = true;
bindingList.Insert(0, newSeries);
series = newSeries;
}
else
{
- lb.Parent = series;
- series.Children.Add(lb);
+ lbe = new(libraryBook) { Parent = series };
+ series.Children.Add(lbe);
}
//Add episode beneath the parent
int seriesIndex = bindingList.IndexOf(series);
- bindingList.Insert(seriesIndex + 1, lb);
+ bindingList.Insert(seriesIndex + 1, lbe);
if (series.Liberate.Expanded)
bindingList.ExpandItem(series);
@@ -159,7 +151,7 @@ namespace LibationWinForms.grid
}
else
//Add the new product
- bindingList.Insert(0, lb);
+ bindingList.Insert(0, new LibraryBookEntry(libraryBook));
}
// update existing
else
@@ -168,6 +160,9 @@ namespace LibationWinForms.grid
}
}
+ //Re-filter after updating existing / adding new books to capture any changes
+ Filter(existingFilter);
+
// remove deleted from grid.
// note: actual deletion from db must still occur via the RemoveBook feature. deleting from audible will not trigger this
var removedBooks =
@@ -176,26 +171,23 @@ namespace LibationWinForms.grid
.LibraryBooks()
.ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId);
+ //Remove books in series from their parents' Children list
foreach (var removed in removedBooks.Where(b => b.Parent is not null))
{
- var series = removed.Parent as SeriesEntry;
- series.Children.Remove(removed);
- series.NotifyPropertyChanged();
+ removed.Parent.Children.Remove(removed);
+ removed.Parent.NotifyPropertyChanged();
}
//Remove series that have no children
var removedSeries =
bindingList
.AllItems()
- .Series()
- .Where(i => i.Children.Count == 0);
+ .EmptySeries();
foreach (var removed in removedBooks.Cast().Concat(removedSeries))
//no need to re-filter for removed books
bindingList.Remove(removed);
- Filter(existingFilter);
-
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/grid/SeriesEntry.cs
index bc74f147..9646c52f 100644
--- a/Source/LibationWinForms/grid/SeriesEntry.cs
+++ b/Source/LibationWinForms/grid/SeriesEntry.cs
@@ -6,9 +6,9 @@ using System.Linq;
namespace LibationWinForms
{
- internal class SeriesEntry : GridEntry
+ public class SeriesEntry : GridEntry
{
- public List Children { get; set; }
+ public List Children { get; init; }
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
public override string ProductRating
{
@@ -55,7 +55,18 @@ namespace LibationWinForms
private LiberateButtonStatus _liberate = new LiberateButtonStatus { IsSeries = true };
- public void setSeriesBook(SeriesBook seriesBook)
+ public SeriesEntry(SeriesBook seriesBook, IEnumerable children)
+ {
+ Children = children.Select(c=>new LibraryBookEntry(c) { Parent = this }).ToList();
+ SetSeriesBook(seriesBook);
+ }
+ public SeriesEntry(SeriesBook seriesBook, LibraryBook child)
+ {
+ Children = new() { new LibraryBookEntry(child) { Parent = this } };
+ SetSeriesBook(seriesBook);
+ }
+
+ private void SetSeriesBook(SeriesBook seriesBook)
{
SeriesBook = seriesBook;
_memberValues = CreateMemberValueDictionary();
diff --git a/Source/LibationWinForms/grid/SortableBindingList1.cs b/Source/LibationWinForms/grid/SortableBindingList1.cs
deleted file mode 100644
index ec545340..00000000
--- a/Source/LibationWinForms/grid/SortableBindingList1.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using Dinah.Core.DataBinding;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-
-namespace LibationWinForms
-{
- internal class SortableBindingList1 : BindingList where T : class, IMemberComparable, IHierarchical
- {
- private bool isSorted;
- private ListSortDirection listSortDirection;
- private PropertyDescriptor propertyDescriptor;
-
- public SortableBindingList1() : base(new List()) { }
- public SortableBindingList1(IEnumerable enumeration) : base(new List(enumeration)) { }
-
- protected bool SuspendSorting { get; set; }
- protected MemberComparer Comparer { get; } = new();
- protected override bool SupportsSortingCore => true;
- protected override bool SupportsSearchingCore => true;
- protected override bool IsSortedCore => isSorted;
- protected override PropertyDescriptor SortPropertyCore => propertyDescriptor;
- protected override ListSortDirection SortDirectionCore => listSortDirection;
-
- protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
- {
- Comparer.PropertyName = property.Name;
- Comparer.Direction = direction;
-
- Sort();
-
- propertyDescriptor = property;
- listSortDirection = direction;
- isSorted = true;
-
- OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
- }
-
- protected void Sort()
- {
- List itemsList = (List)Items;
-
- var sortedItems = Items.OrderBy(ge => ge, Comparer).ToList();
-
- var children = sortedItems.Where(i => i.Parent is not null).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));
-
- 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))
- itemsList.Insert(++pIndex, c);
- }
- }
-
- protected override void OnListChanged(ListChangedEventArgs e)
- {
- if (isSorted && !SuspendSorting &&
- ((e.ListChangedType == ListChangedType.ItemChanged && e.PropertyDescriptor == SortPropertyCore) ||
- e.ListChangedType == ListChangedType.ItemAdded))
- {
- var item = Items[e.NewIndex];
- Sort();
- var newIndex = Items.IndexOf(item);
-
- base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
- }
- else
- base.OnListChanged(e);
- }
-
- protected override void RemoveSortCore()
- {
- isSorted = false;
- propertyDescriptor = base.SortPropertyCore;
- listSortDirection = base.SortDirectionCore;
-
- OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
- }
- }
-}
From e778c7a59d9692dcc308b2eba59588eff8c256e6 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 21:34:43 -0600
Subject: [PATCH 09/15] Create GridView namespace
---
.../Dialogs/RemoveBooksDialog.Designer.cs | 4 +-
.../Dialogs/RemoveBooksDialog.cs | 3 +-
Source/LibationWinForms/Form1.Designer.cs | 4 +-
.../AsyncNotifyPropertyChanged.cs | 2 +-
.../DataGridViewImageButtonCell.cs | 2 +-
.../DescriptionDisplay.Designer.cs | 2 +-
.../{grid => GridView}/DescriptionDisplay.cs | 2 +-
.../DescriptionDisplay.resx | 0
.../EditTagsDataGridViewImageButtonColumn.cs | 2 +-
.../{grid => GridView}/GridEntry.cs | 2 +-
.../GridEntryBindingList.cs | 2 +-
.../ImageDisplay.Designer.cs | 2 +-
.../{grid => GridView}/ImageDisplay.cs | 2 +-
.../{grid => GridView}/ImageDisplay.resx | 0
.../LiberateButtonStatus.cs | 2 +-
.../LiberateDataGridViewImageButtonColumn.cs | 2 +-
.../{grid => GridView}/LibraryBookEntry.cs | 2 +-
.../ProductsDisplay.Designer.cs | 14 +++----
.../{grid => GridView}/ProductsDisplay.cs | 2 +-
.../{grid => GridView}/ProductsDisplay.resx | 0
.../ProductsGrid.Designer.cs | 38 +++++++++----------
.../{grid => GridView}/ProductsGrid.cs | 2 +-
.../{grid => GridView}/ProductsGrid.resx | 0
.../{grid => GridView}/SeriesEntry.cs | 2 +-
.../{ => GridView}/SyncBindingSource.cs | 2 +-
.../LibationWinForm.GridEntry.datasource | 2 +-
26 files changed, 48 insertions(+), 49 deletions(-)
rename Source/LibationWinForms/{grid => GridView}/AsyncNotifyPropertyChanged.cs (94%)
rename Source/LibationWinForms/{grid => GridView}/DataGridViewImageButtonCell.cs (92%)
rename Source/LibationWinForms/{grid => GridView}/DescriptionDisplay.Designer.cs (98%)
rename Source/LibationWinForms/{grid => GridView}/DescriptionDisplay.cs (97%)
rename Source/LibationWinForms/{grid => GridView}/DescriptionDisplay.resx (100%)
rename Source/LibationWinForms/{grid => GridView}/EditTagsDataGridViewImageButtonColumn.cs (98%)
rename Source/LibationWinForms/{grid => GridView}/GridEntry.cs (99%)
rename Source/LibationWinForms/{grid => GridView}/GridEntryBindingList.cs (99%)
rename Source/LibationWinForms/{grid => GridView}/ImageDisplay.Designer.cs (98%)
rename Source/LibationWinForms/{grid => GridView}/ImageDisplay.cs (98%)
rename Source/LibationWinForms/{grid => GridView}/ImageDisplay.resx (100%)
rename Source/LibationWinForms/{grid => GridView}/LiberateButtonStatus.cs (96%)
rename Source/LibationWinForms/{grid => GridView}/LiberateDataGridViewImageButtonColumn.cs (98%)
rename Source/LibationWinForms/{grid => GridView}/LibraryBookEntry.cs (99%)
rename Source/LibationWinForms/{grid => GridView}/ProductsDisplay.Designer.cs (70%)
rename Source/LibationWinForms/{grid => GridView}/ProductsDisplay.cs (99%)
rename Source/LibationWinForms/{grid => GridView}/ProductsDisplay.resx (100%)
rename Source/LibationWinForms/{grid => GridView}/ProductsGrid.Designer.cs (93%)
rename Source/LibationWinForms/{grid => GridView}/ProductsGrid.cs (99%)
rename Source/LibationWinForms/{grid => GridView}/ProductsGrid.resx (100%)
rename Source/LibationWinForms/{grid => GridView}/SeriesEntry.cs (99%)
rename Source/LibationWinForms/{ => GridView}/SyncBindingSource.cs (96%)
diff --git a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs
index 61974264..7240b8f3 100644
--- a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs
+++ b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs
@@ -38,7 +38,7 @@ namespace LibationWinForms.Dialogs
this.authorsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.miscDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.purchaseDateGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components);
+ this.gridEntryBindingSource = new LibationWinForms.GridView.SyncBindingSource(this.components);
this.btnRemoveBooks = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this._dataGridView)).BeginInit();
@@ -176,7 +176,7 @@ namespace LibationWinForms.Dialogs
#endregion
private System.Windows.Forms.DataGridView _dataGridView;
- private LibationWinForms.SyncBindingSource gridEntryBindingSource;
+ private LibationWinForms.GridView.SyncBindingSource gridEntryBindingSource;
private System.Windows.Forms.Button btnRemoveBooks;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.DataGridViewCheckBoxColumn removeDataGridViewCheckBoxColumn;
diff --git a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
index bb1759dc..558095f0 100644
--- a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
+++ b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
@@ -121,7 +120,7 @@ namespace LibationWinForms.Dialogs
}
}
- internal class RemovableGridEntry : LibraryBookEntry
+ internal class RemovableGridEntry : GridView.LibraryBookEntry
{
private bool _remove = false;
public RemovableGridEntry(LibraryBook libraryBook) : base(libraryBook) { }
diff --git a/Source/LibationWinForms/Form1.Designer.cs b/Source/LibationWinForms/Form1.Designer.cs
index 49c41b42..f4abad4f 100644
--- a/Source/LibationWinForms/Form1.Designer.cs
+++ b/Source/LibationWinForms/Form1.Designer.cs
@@ -72,7 +72,7 @@
this.addQuickFilterBtn = new System.Windows.Forms.Button();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.panel1 = new System.Windows.Forms.Panel();
- this.productsDisplay = new LibationWinForms.ProductsDisplay();
+ this.productsDisplay = new LibationWinForms.GridView.ProductsDisplay();
this.toggleQueueHideBtn = new System.Windows.Forms.Button();
this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl();
this.menuStrip1.SuspendLayout();
@@ -583,6 +583,6 @@
private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button toggleQueueHideBtn;
- private ProductsDisplay productsDisplay;
+ private LibationWinForms.GridView.ProductsDisplay productsDisplay;
}
}
diff --git a/Source/LibationWinForms/grid/AsyncNotifyPropertyChanged.cs b/Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs
similarity index 94%
rename from Source/LibationWinForms/grid/AsyncNotifyPropertyChanged.cs
rename to Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs
index cce5e5b9..e4532cfe 100644
--- a/Source/LibationWinForms/grid/AsyncNotifyPropertyChanged.cs
+++ b/Source/LibationWinForms/GridView/AsyncNotifyPropertyChanged.cs
@@ -2,7 +2,7 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public abstract class AsyncNotifyPropertyChanged : SynchronizeInvoker, INotifyPropertyChanged
{
diff --git a/Source/LibationWinForms/grid/DataGridViewImageButtonCell.cs b/Source/LibationWinForms/GridView/DataGridViewImageButtonCell.cs
similarity index 92%
rename from Source/LibationWinForms/grid/DataGridViewImageButtonCell.cs
rename to Source/LibationWinForms/GridView/DataGridViewImageButtonCell.cs
index f4f25afd..d53b02ed 100644
--- a/Source/LibationWinForms/grid/DataGridViewImageButtonCell.cs
+++ b/Source/LibationWinForms/GridView/DataGridViewImageButtonCell.cs
@@ -1,7 +1,7 @@
using System.Drawing;
using System.Windows.Forms;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class DataGridViewImageButtonCell : DataGridViewButtonCell
{
diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/GridView/DescriptionDisplay.Designer.cs
similarity index 98%
rename from Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs
rename to Source/LibationWinForms/GridView/DescriptionDisplay.Designer.cs
index 96012e50..be8d9496 100644
--- a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs
+++ b/Source/LibationWinForms/GridView/DescriptionDisplay.Designer.cs
@@ -1,4 +1,4 @@
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
partial class DescriptionDisplay
{
diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/GridView/DescriptionDisplay.cs
similarity index 97%
rename from Source/LibationWinForms/grid/DescriptionDisplay.cs
rename to Source/LibationWinForms/GridView/DescriptionDisplay.cs
index 3f95a92e..a39790d9 100644
--- a/Source/LibationWinForms/grid/DescriptionDisplay.cs
+++ b/Source/LibationWinForms/GridView/DescriptionDisplay.cs
@@ -5,7 +5,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public partial class DescriptionDisplay : Form
{
diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.resx b/Source/LibationWinForms/GridView/DescriptionDisplay.resx
similarity index 100%
rename from Source/LibationWinForms/grid/DescriptionDisplay.resx
rename to Source/LibationWinForms/GridView/DescriptionDisplay.resx
diff --git a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/GridView/EditTagsDataGridViewImageButtonColumn.cs
similarity index 98%
rename from Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
rename to Source/LibationWinForms/GridView/EditTagsDataGridViewImageButtonColumn.cs
index b0d9407e..065afdbb 100644
--- a/Source/LibationWinForms/grid/EditTagsDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/GridView/EditTagsDataGridViewImageButtonColumn.cs
@@ -2,7 +2,7 @@
using System.Drawing;
using System.Windows.Forms;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class EditTagsDataGridViewImageButtonColumn : DataGridViewButtonColumn
{
diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/GridView/GridEntry.cs
similarity index 99%
rename from Source/LibationWinForms/grid/GridEntry.cs
rename to Source/LibationWinForms/GridView/GridEntry.cs
index d26ae575..733bcac8 100644
--- a/Source/LibationWinForms/grid/GridEntry.cs
+++ b/Source/LibationWinForms/GridView/GridEntry.cs
@@ -8,7 +8,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
{
diff --git a/Source/LibationWinForms/grid/GridEntryBindingList.cs b/Source/LibationWinForms/GridView/GridEntryBindingList.cs
similarity index 99%
rename from Source/LibationWinForms/grid/GridEntryBindingList.cs
rename to Source/LibationWinForms/GridView/GridEntryBindingList.cs
index fb6f7df7..511e2ce6 100644
--- a/Source/LibationWinForms/grid/GridEntryBindingList.cs
+++ b/Source/LibationWinForms/GridView/GridEntryBindingList.cs
@@ -5,7 +5,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
/*
* Allows filtering and sorting of the underlying BindingList
diff --git a/Source/LibationWinForms/grid/ImageDisplay.Designer.cs b/Source/LibationWinForms/GridView/ImageDisplay.Designer.cs
similarity index 98%
rename from Source/LibationWinForms/grid/ImageDisplay.Designer.cs
rename to Source/LibationWinForms/GridView/ImageDisplay.Designer.cs
index ec1dbdf0..a1ca5caa 100644
--- a/Source/LibationWinForms/grid/ImageDisplay.Designer.cs
+++ b/Source/LibationWinForms/GridView/ImageDisplay.Designer.cs
@@ -1,4 +1,4 @@
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
partial class ImageDisplay
{
diff --git a/Source/LibationWinForms/grid/ImageDisplay.cs b/Source/LibationWinForms/GridView/ImageDisplay.cs
similarity index 98%
rename from Source/LibationWinForms/grid/ImageDisplay.cs
rename to Source/LibationWinForms/GridView/ImageDisplay.cs
index 53f75987..a6bfa574 100644
--- a/Source/LibationWinForms/grid/ImageDisplay.cs
+++ b/Source/LibationWinForms/GridView/ImageDisplay.cs
@@ -5,7 +5,7 @@ using System.Drawing;
using System.IO;
using System.Windows.Forms;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public partial class ImageDisplay : Form
{
diff --git a/Source/LibationWinForms/grid/ImageDisplay.resx b/Source/LibationWinForms/GridView/ImageDisplay.resx
similarity index 100%
rename from Source/LibationWinForms/grid/ImageDisplay.resx
rename to Source/LibationWinForms/GridView/ImageDisplay.resx
diff --git a/Source/LibationWinForms/grid/LiberateButtonStatus.cs b/Source/LibationWinForms/GridView/LiberateButtonStatus.cs
similarity index 96%
rename from Source/LibationWinForms/grid/LiberateButtonStatus.cs
rename to Source/LibationWinForms/GridView/LiberateButtonStatus.cs
index 8814eb24..3ee577fd 100644
--- a/Source/LibationWinForms/grid/LiberateButtonStatus.cs
+++ b/Source/LibationWinForms/GridView/LiberateButtonStatus.cs
@@ -1,7 +1,7 @@
using DataLayer;
using System;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class LiberateButtonStatus : IComparable
{
diff --git a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
similarity index 98%
rename from Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
rename to Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
index feb9b0e0..a237b7a0 100644
--- a/Source/LibationWinForms/grid/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
@@ -4,7 +4,7 @@ using System.Windows.Forms;
using System.Linq;
using DataLayer;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class LiberateDataGridViewImageButtonColumn : DataGridViewButtonColumn
{
diff --git a/Source/LibationWinForms/grid/LibraryBookEntry.cs b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
similarity index 99%
rename from Source/LibationWinForms/grid/LibraryBookEntry.cs
rename to Source/LibationWinForms/GridView/LibraryBookEntry.cs
index 3834e502..5fc606a1 100644
--- a/Source/LibationWinForms/grid/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
@@ -6,7 +6,7 @@ using ApplicationServices;
using DataLayer;
using Dinah.Core;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
///
/// The View Model for a LibraryBook
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs b/Source/LibationWinForms/GridView/ProductsDisplay.Designer.cs
similarity index 70%
rename from Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
rename to Source/LibationWinForms/GridView/ProductsDisplay.Designer.cs
index 8f561b0f..c4b1a543 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.Designer.cs
+++ b/Source/LibationWinForms/GridView/ProductsDisplay.Designer.cs
@@ -1,4 +1,4 @@
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
partial class ProductsDisplay
{
@@ -28,7 +28,7 @@
///
private void InitializeComponent()
{
- this.productsGrid = new LibationWinForms.grid.ProductsGrid();
+ this.productsGrid = new LibationWinForms.GridView.ProductsGrid();
this.SuspendLayout();
//
// productsGrid
@@ -39,10 +39,10 @@
this.productsGrid.Name = "productsGrid";
this.productsGrid.Size = new System.Drawing.Size(1510, 380);
this.productsGrid.TabIndex = 0;
- this.productsGrid.LiberateClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_LiberateClicked);
- this.productsGrid.CoverClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_CoverClicked);
- this.productsGrid.DetailsClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_DetailsClicked);
- this.productsGrid.DescriptionClicked += new LibationWinForms.grid.ProductsGrid.LibraryBookEntryRectangleClickedEventHandler(this.productsGrid_DescriptionClicked);
+ this.productsGrid.LiberateClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_LiberateClicked);
+ this.productsGrid.CoverClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_CoverClicked);
+ this.productsGrid.DetailsClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_DetailsClicked);
+ this.productsGrid.DescriptionClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryRectangleClickedEventHandler(this.productsGrid_DescriptionClicked);
this.productsGrid.VisibleCountChanged += new System.EventHandler(this.productsGrid_VisibleCountChanged);
//
// ProductsDisplay
@@ -59,6 +59,6 @@
#endregion
- private grid.ProductsGrid productsGrid;
+ private GridView.ProductsGrid productsGrid;
}
}
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.cs b/Source/LibationWinForms/GridView/ProductsDisplay.cs
similarity index 99%
rename from Source/LibationWinForms/grid/ProductsDisplay.cs
rename to Source/LibationWinForms/GridView/ProductsDisplay.cs
index 6fc37fa0..66de694b 100644
--- a/Source/LibationWinForms/grid/ProductsDisplay.cs
+++ b/Source/LibationWinForms/GridView/ProductsDisplay.cs
@@ -10,7 +10,7 @@ using FileLiberator;
using LibationFileManager;
using LibationWinForms.Dialogs;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public partial class ProductsDisplay : UserControl
{
diff --git a/Source/LibationWinForms/grid/ProductsDisplay.resx b/Source/LibationWinForms/GridView/ProductsDisplay.resx
similarity index 100%
rename from Source/LibationWinForms/grid/ProductsDisplay.resx
rename to Source/LibationWinForms/GridView/ProductsDisplay.resx
diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs
similarity index 93%
rename from Source/LibationWinForms/grid/ProductsGrid.Designer.cs
rename to Source/LibationWinForms/GridView/ProductsGrid.Designer.cs
index fec72094..b380ff95 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs
+++ b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs
@@ -1,4 +1,4 @@
-namespace LibationWinForms.grid
+namespace LibationWinForms.GridView
{
partial class ProductsGrid
{
@@ -31,7 +31,7 @@
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
this.gridEntryDataGridView = new System.Windows.Forms.DataGridView();
- this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn();
+ this.liberateGVColumn = new LibationWinForms.GridView.LiberateDataGridViewImageButtonColumn();
this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn();
this.titleGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.authorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
@@ -44,9 +44,9 @@
this.purchaseDateGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.myRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
- this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn();
+ this.tagAndDetailsGVColumn = new LibationWinForms.GridView.EditTagsDataGridViewImageButtonColumn();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
- this.syncBindingSource = new LibationWinForms.SyncBindingSource(this.components);
+ this.syncBindingSource = new LibationWinForms.GridView.SyncBindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).BeginInit();
this.SuspendLayout();
@@ -60,20 +60,20 @@
this.gridEntryDataGridView.AutoGenerateColumns = false;
this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
- this.liberateGVColumn,
- this.coverGVColumn,
- this.titleGVColumn,
- this.authorsGVColumn,
- this.narratorsGVColumn,
- this.lengthGVColumn,
- this.seriesGVColumn,
- this.descriptionGVColumn,
- this.categoryGVColumn,
- this.productRatingGVColumn,
- this.purchaseDateGVColumn,
- this.myRatingGVColumn,
- this.miscGVColumn,
- this.tagAndDetailsGVColumn});
+ this.liberateGVColumn,
+ this.coverGVColumn,
+ this.titleGVColumn,
+ this.authorsGVColumn,
+ this.narratorsGVColumn,
+ this.lengthGVColumn,
+ this.seriesGVColumn,
+ this.descriptionGVColumn,
+ this.categoryGVColumn,
+ this.productRatingGVColumn,
+ this.purchaseDateGVColumn,
+ this.myRatingGVColumn,
+ this.miscGVColumn,
+ this.tagAndDetailsGVColumn});
this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1;
this.gridEntryDataGridView.DataSource = this.syncBindingSource;
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
@@ -214,7 +214,7 @@
//
// syncBindingSource
//
- this.syncBindingSource.DataSource = typeof(LibationWinForms.GridEntry);
+ this.syncBindingSource.DataSource = typeof(LibationWinForms.GridView.GridEntry);
//
// ProductsGrid
//
diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/GridView/ProductsGrid.cs
similarity index 99%
rename from Source/LibationWinForms/grid/ProductsGrid.cs
rename to Source/LibationWinForms/GridView/ProductsGrid.cs
index 8e3cfe8d..5bf2a910 100644
--- a/Source/LibationWinForms/grid/ProductsGrid.cs
+++ b/Source/LibationWinForms/GridView/ProductsGrid.cs
@@ -8,7 +8,7 @@ using System.Drawing;
using System.Linq;
using System.Windows.Forms;
-namespace LibationWinForms.grid
+namespace LibationWinForms.GridView
{
public partial class ProductsGrid : UserControl
{
diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/GridView/ProductsGrid.resx
similarity index 100%
rename from Source/LibationWinForms/grid/ProductsGrid.resx
rename to Source/LibationWinForms/GridView/ProductsGrid.resx
diff --git a/Source/LibationWinForms/grid/SeriesEntry.cs b/Source/LibationWinForms/GridView/SeriesEntry.cs
similarity index 99%
rename from Source/LibationWinForms/grid/SeriesEntry.cs
rename to Source/LibationWinForms/GridView/SeriesEntry.cs
index 9646c52f..17eb8125 100644
--- a/Source/LibationWinForms/grid/SeriesEntry.cs
+++ b/Source/LibationWinForms/GridView/SeriesEntry.cs
@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class SeriesEntry : GridEntry
{
diff --git a/Source/LibationWinForms/SyncBindingSource.cs b/Source/LibationWinForms/GridView/SyncBindingSource.cs
similarity index 96%
rename from Source/LibationWinForms/SyncBindingSource.cs
rename to Source/LibationWinForms/GridView/SyncBindingSource.cs
index 42d38ad9..5faafb0b 100644
--- a/Source/LibationWinForms/SyncBindingSource.cs
+++ b/Source/LibationWinForms/GridView/SyncBindingSource.cs
@@ -4,7 +4,7 @@ using System.Threading;
using System.Windows.Forms;
// https://stackoverflow.com/a/32886415
-namespace LibationWinForms
+namespace LibationWinForms.GridView
{
public class SyncBindingSource : BindingSource
{
diff --git a/Source/LibationWinForms/Properties/DataSources/LibationWinForm.GridEntry.datasource b/Source/LibationWinForms/Properties/DataSources/LibationWinForm.GridEntry.datasource
index ce0d9a71..48143915 100644
--- a/Source/LibationWinForms/Properties/DataSources/LibationWinForm.GridEntry.datasource
+++ b/Source/LibationWinForms/Properties/DataSources/LibationWinForm.GridEntry.datasource
@@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program.
-->
- LibationWinForms.GridEntry, LibationWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
+ LibationWinForms.GridView.GridEntry, LibationWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
\ No newline at end of file
From 632b432b7c7f31bd9ee825c082fd1c6217cea81c Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 22:20:54 -0600
Subject: [PATCH 10/15] Revert to old column indexing
---
Source/LibationWinForms/Form1.PictureStorage.cs | 1 +
Source/LibationWinForms/GridView/ProductsGrid.cs | 11 +++++------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/Source/LibationWinForms/Form1.PictureStorage.cs b/Source/LibationWinForms/Form1.PictureStorage.cs
index 2a6efd09..c400eaf6 100644
--- a/Source/LibationWinForms/Form1.PictureStorage.cs
+++ b/Source/LibationWinForms/Form1.PictureStorage.cs
@@ -12,6 +12,7 @@ namespace LibationWinForms
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._300x300, Properties.Resources.default_cover_300x300.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize._500x500, Properties.Resources.default_cover_500x500.ToBytes(format));
+ PictureStorage.SetDefaultImage(PictureSize.Native, Properties.Resources.default_cover_500x500.ToBytes(format));
}
}
}
diff --git a/Source/LibationWinForms/GridView/ProductsGrid.cs b/Source/LibationWinForms/GridView/ProductsGrid.cs
index 5bf2a910..e9a3bdb1 100644
--- a/Source/LibationWinForms/GridView/ProductsGrid.cs
+++ b/Source/LibationWinForms/GridView/ProductsGrid.cs
@@ -54,16 +54,16 @@ namespace LibationWinForms.GridView
var entry = getGridEntry(e.RowIndex);
if (entry is LibraryBookEntry lbEntry)
{
- if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == liberateGVColumn.DataPropertyName)
+ if (e.ColumnIndex == liberateGVColumn.Index)
LiberateClicked?.Invoke(lbEntry);
- else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == tagAndDetailsGVColumn.DataPropertyName && entry is LibraryBookEntry)
+ else if (e.ColumnIndex == tagAndDetailsGVColumn.Index && entry is LibraryBookEntry)
DetailsClicked?.Invoke(lbEntry);
- else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == descriptionGVColumn.DataPropertyName)
+ else if (e.ColumnIndex == descriptionGVColumn.Index)
DescriptionClicked?.Invoke(lbEntry, gridEntryDataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
- else if (gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == coverGVColumn.DataPropertyName)
+ else if (e.ColumnIndex == coverGVColumn.Index)
CoverClicked?.Invoke(lbEntry);
}
- else if (entry is SeriesEntry sEntry && gridEntryDataGridView.Columns[e.ColumnIndex].DataPropertyName == liberateGVColumn.DataPropertyName)
+ else if (entry is SeriesEntry sEntry && e.ColumnIndex == liberateGVColumn.Index)
{
if (sEntry.Liberate.Expanded)
bindingList.CollapseItem(sEntry);
@@ -80,7 +80,6 @@ namespace LibationWinForms.GridView
#endregion
-
#region UI display functions
internal void BindToGrid(List dbBooks)
From 43a4d0d1d7bb99f0ce653322ce232b1839973bb1 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Mon, 23 May 2022 22:24:45 -0600
Subject: [PATCH 11/15] Cleanup
---
.../GridView/DescriptionDisplay.cs | 4 +-
Source/LibationWinForms/GridView/GridEntry.cs | 14 +++----
.../LibationWinForms/GridView/ImageDisplay.cs | 4 +-
.../LiberateDataGridViewImageButtonColumn.cs | 5 +--
.../GridView/LibraryBookEntry.cs | 10 ++---
.../GridView/ProductsDisplay.cs | 12 +++---
.../LibationWinForms/GridView/ProductsGrid.cs | 6 +--
.../LibationWinForms/GridView/SeriesEntry.cs | 16 ++++----
.../GridView/SyncBindingSource.cs | 37 +++++++++----------
9 files changed, 50 insertions(+), 58 deletions(-)
diff --git a/Source/LibationWinForms/GridView/DescriptionDisplay.cs b/Source/LibationWinForms/GridView/DescriptionDisplay.cs
index a39790d9..d3aefd52 100644
--- a/Source/LibationWinForms/GridView/DescriptionDisplay.cs
+++ b/Source/LibationWinForms/GridView/DescriptionDisplay.cs
@@ -1,7 +1,5 @@
using System;
-using System.ComponentModel;
using System.Drawing;
-using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
@@ -11,7 +9,7 @@ namespace LibationWinForms.GridView
{
private int borderThickness = 5;
- public int BorderThickness
+ public int BorderThickness
{
get => borderThickness;
set
diff --git a/Source/LibationWinForms/GridView/GridEntry.cs b/Source/LibationWinForms/GridView/GridEntry.cs
index 733bcac8..6757ef60 100644
--- a/Source/LibationWinForms/GridView/GridEntry.cs
+++ b/Source/LibationWinForms/GridView/GridEntry.cs
@@ -81,21 +81,21 @@ namespace LibationWinForms.GridView
~GridEntry()
{
PictureStorage.PictureCached -= PictureStorage_PictureCached;
- }
+ }
}
internal static class GridEntryExtensions
{
- #nullable enable
- public static IEnumerable Series(this IEnumerable gridEntries)
+#nullable enable
+ public static IEnumerable Series(this IEnumerable gridEntries)
=> gridEntries.Where(i => i is SeriesEntry).Cast();
- public static IEnumerable LibraryBooks(this IEnumerable gridEntries)
+ public static IEnumerable LibraryBooks(this IEnumerable gridEntries)
=> gridEntries.Where(i => i is LibraryBookEntry).Cast();
- public static LibraryBookEntry? FindBookByAsin(this IEnumerable gridEntries, string audibleProductID)
+ public static LibraryBookEntry? FindBookByAsin(this IEnumerable gridEntries, string audibleProductID)
=> gridEntries.FirstOrDefault(i => i.AudibleProductId == audibleProductID);
- public static SeriesEntry? FindBookSeriesEntry(this IEnumerable gridEntries, IEnumerable matchSeries)
+ public static SeriesEntry? FindBookSeriesEntry(this IEnumerable gridEntries, IEnumerable matchSeries)
=> gridEntries.Series().FirstOrDefault(i => matchSeries.Any(s => s.Series.Name == i.Series));
- public static IEnumerable EmptySeries(this IEnumerable gridEntries)
+ public static IEnumerable EmptySeries(this IEnumerable gridEntries)
=> gridEntries.Series().Where(i => i.Children.Count == 0);
}
}
diff --git a/Source/LibationWinForms/GridView/ImageDisplay.cs b/Source/LibationWinForms/GridView/ImageDisplay.cs
index a6bfa574..831b8ec9 100644
--- a/Source/LibationWinForms/GridView/ImageDisplay.cs
+++ b/Source/LibationWinForms/GridView/ImageDisplay.cs
@@ -1,6 +1,4 @@
-using FileLiberator;
-using LibationFileManager;
-using System;
+using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
diff --git a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
index a237b7a0..f7291962 100644
--- a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
@@ -1,8 +1,7 @@
-using System;
+using DataLayer;
+using System;
using System.Drawing;
using System.Windows.Forms;
-using System.Linq;
-using DataLayer;
namespace LibationWinForms.GridView
{
diff --git a/Source/LibationWinForms/GridView/LibraryBookEntry.cs b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
index 5fc606a1..8d93ebff 100644
--- a/Source/LibationWinForms/GridView/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
@@ -1,10 +1,10 @@
-using System;
+using ApplicationServices;
+using DataLayer;
+using Dinah.Core;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
-using ApplicationServices;
-using DataLayer;
-using Dinah.Core;
namespace LibationWinForms.GridView
{
@@ -183,7 +183,7 @@ namespace LibationWinForms.GridView
{ nameof(Liberate), () => Liberate },
{ nameof(DateAdded), () => DateAdded },
};
-
+
#endregion
diff --git a/Source/LibationWinForms/GridView/ProductsDisplay.cs b/Source/LibationWinForms/GridView/ProductsDisplay.cs
index 66de694b..7e1b2d8a 100644
--- a/Source/LibationWinForms/GridView/ProductsDisplay.cs
+++ b/Source/LibationWinForms/GridView/ProductsDisplay.cs
@@ -1,14 +1,14 @@
-using System;
+using ApplicationServices;
+using DataLayer;
+using FileLiberator;
+using LibationFileManager;
+using LibationWinForms.Dialogs;
+using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
-using ApplicationServices;
-using DataLayer;
-using FileLiberator;
-using LibationFileManager;
-using LibationWinForms.Dialogs;
namespace LibationWinForms.GridView
{
diff --git a/Source/LibationWinForms/GridView/ProductsGrid.cs b/Source/LibationWinForms/GridView/ProductsGrid.cs
index e9a3bdb1..a715eb8e 100644
--- a/Source/LibationWinForms/GridView/ProductsGrid.cs
+++ b/Source/LibationWinForms/GridView/ProductsGrid.cs
@@ -46,17 +46,15 @@ namespace LibationWinForms.GridView
private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// handle grid button click: https://stackoverflow.com/a/13687844
- if ( e.RowIndex < 0)
+ if (e.RowIndex < 0)
return;
- var column = gridEntryDataGridView.Columns[e.ColumnIndex];
-
var entry = getGridEntry(e.RowIndex);
if (entry is LibraryBookEntry lbEntry)
{
if (e.ColumnIndex == liberateGVColumn.Index)
LiberateClicked?.Invoke(lbEntry);
- else if (e.ColumnIndex == tagAndDetailsGVColumn.Index && entry is LibraryBookEntry)
+ else if (e.ColumnIndex == tagAndDetailsGVColumn.Index)
DetailsClicked?.Invoke(lbEntry);
else if (e.ColumnIndex == descriptionGVColumn.Index)
DescriptionClicked?.Invoke(lbEntry, gridEntryDataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
diff --git a/Source/LibationWinForms/GridView/SeriesEntry.cs b/Source/LibationWinForms/GridView/SeriesEntry.cs
index 17eb8125..65cb648e 100644
--- a/Source/LibationWinForms/GridView/SeriesEntry.cs
+++ b/Source/LibationWinForms/GridView/SeriesEntry.cs
@@ -31,14 +31,14 @@ namespace LibationWinForms.GridView
}
public override string Series { get; protected set; }
public override string Title { get; protected set; }
- public override string Length
- {
+ public override string Length
+ {
get
{
int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
return bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
- }
- protected set => throw new NotImplementedException();
+ }
+ protected set => throw new NotImplementedException();
}
public override string Authors { get; protected set; }
public override string Narrators { get; protected set; }
@@ -57,7 +57,7 @@ namespace LibationWinForms.GridView
public SeriesEntry(SeriesBook seriesBook, IEnumerable children)
{
- Children = children.Select(c=>new LibraryBookEntry(c) { Parent = this }).ToList();
+ Children = children.Select(c => new LibraryBookEntry(c) { Parent = this }).ToList();
SetSeriesBook(seriesBook);
}
public SeriesEntry(SeriesBook seriesBook, LibraryBook child)
@@ -96,9 +96,9 @@ namespace LibationWinForms.GridView
{
{ nameof(Title), () => Book.SeriesSortable() },
{ nameof(Series), () => Book.SeriesSortable() },
- { nameof(Length), () => Children.Sum(c=>c.LibraryBook.Book.LengthInMinutes) },
- { nameof(MyRating), () => Children.Average(c=>c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
- { nameof(PurchaseDate), () => Children.Min(c=>c.LibraryBook.DateAdded) },
+ { nameof(Length), () => Children.Sum(c => c.LibraryBook.Book.LengthInMinutes) },
+ { nameof(MyRating), () => Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
+ { nameof(PurchaseDate), () => Children.Min(c => c.LibraryBook.DateAdded) },
{ nameof(ProductRating), () => Children.Average(c => c.LibraryBook.Book.Rating.FirstScore()) },
{ nameof(Authors), () => string.Empty },
{ nameof(Narrators), () => string.Empty },
diff --git a/Source/LibationWinForms/GridView/SyncBindingSource.cs b/Source/LibationWinForms/GridView/SyncBindingSource.cs
index 5faafb0b..970e110a 100644
--- a/Source/LibationWinForms/GridView/SyncBindingSource.cs
+++ b/Source/LibationWinForms/GridView/SyncBindingSource.cs
@@ -1,30 +1,29 @@
-using System;
-using System.ComponentModel;
+using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
// https://stackoverflow.com/a/32886415
namespace LibationWinForms.GridView
{
- public class SyncBindingSource : BindingSource
- {
- private SynchronizationContext syncContext { get; }
+ public class SyncBindingSource : BindingSource
+ {
+ private SynchronizationContext syncContext { get; }
- public SyncBindingSource() : base()
- => syncContext = SynchronizationContext.Current;
- public SyncBindingSource(IContainer container) : base(container)
- => syncContext = SynchronizationContext.Current;
- public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
- => syncContext = SynchronizationContext.Current;
+ public SyncBindingSource() : base()
+ => syncContext = SynchronizationContext.Current;
+ public SyncBindingSource(IContainer container) : base(container)
+ => syncContext = SynchronizationContext.Current;
+ public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
+ => syncContext = SynchronizationContext.Current;
- public override bool SupportsFiltering => true;
+ public override bool SupportsFiltering => true;
protected override void OnListChanged(ListChangedEventArgs e)
- {
- if (syncContext is not null)
- syncContext.Send(_ => base.OnListChanged(e), null);
- else
- base.OnListChanged(e);
- }
- }
+ {
+ if (syncContext is not null)
+ syncContext.Send(_ => base.OnListChanged(e), null);
+ else
+ base.OnListChanged(e);
+ }
+ }
}
From ee62d9ae8de52929d5513cade4ac250e1b9a6c4a Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Tue, 24 May 2022 07:36:17 -0600
Subject: [PATCH 12/15] Attempt to fix app hang on LogMe event
---
Source/LibationWinForms/ProcessQueue/LogMe.cs | 30 +++++++++++++------
.../ProcessQueue/ProcessQueueControl.cs | 2 +-
2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/Source/LibationWinForms/ProcessQueue/LogMe.cs b/Source/LibationWinForms/ProcessQueue/LogMe.cs
index b6d61f69..06b84400 100644
--- a/Source/LibationWinForms/ProcessQueue/LogMe.cs
+++ b/Source/LibationWinForms/ProcessQueue/LogMe.cs
@@ -19,7 +19,7 @@ namespace LibationWinForms.ProcessQueue
LogErrorString += (_, text) => Serilog.Log.Logger.Error(text);
LogError += (_, tuple) => Serilog.Log.Logger.Error(tuple.Item1, tuple.Item2 ?? "Automated backup: error");
}
-
+ private static ILogForm LogForm;
public static LogMe RegisterForm(T form) where T : ILogForm
{
var logMe = new LogMe();
@@ -27,19 +27,31 @@ namespace LibationWinForms.ProcessQueue
if (form is null)
return logMe;
- logMe.LogInfo += (_, text) => form?.WriteLine(text);
+ LogForm = form;
- logMe.LogErrorString += (_, text) => form?.WriteLine(text);
-
- logMe.LogError += (_, tuple) =>
- {
- form?.WriteLine(tuple.Item2 ?? "Automated backup: error");
- form?.WriteLine("ERROR: " + tuple.Item1.Message);
- };
+ logMe.LogInfo += LogMe_LogInfo;
+ logMe.LogErrorString += LogMe_LogErrorString;
+ logMe.LogError += LogMe_LogError;
return logMe;
}
+ private static async void LogMe_LogError(object sender, (Exception, string) tuple)
+ {
+ await Task.Run(() => LogForm?.WriteLine(tuple.Item2 ?? "Automated backup: error"));
+ await Task.Run(() => LogForm?.WriteLine("ERROR: " + tuple.Item1.Message));
+ }
+
+ private static async void LogMe_LogErrorString(object sender, string text)
+ {
+ await Task.Run(() => LogForm?.WriteLine(text));
+ }
+
+ private static async void LogMe_LogInfo(object sender, string text)
+ {
+ await Task.Run(() => LogForm?.WriteLine(text));
+ }
+
public void Info(string text) => LogInfo?.Invoke(this, text);
public void Error(string text) => LogErrorString?.Invoke(this, text);
public void Error(Exception ex, string text = null) => LogError?.Invoke(this, (ex, text));
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
index 9acf1eb4..f1830f51 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
@@ -169,7 +169,7 @@ namespace LibationWinForms.ProcessQueue
if (IsDisposed) return;
var timeStamp = DateTime.Now;
- logDGV.Rows.Add(timeStamp, text.Trim());
+ Invoke(() => logDGV.Rows.Add(timeStamp, text.Trim()));
}
#region Control event handlers
From 43d6ea82cd11bb727cabe1ed6eeccb8cc41a11d5 Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Tue, 24 May 2022 08:57:11 -0600
Subject: [PATCH 13/15] Change failure behavior to match previous
implementation
---
.../ProcessQueue/ProcessBook.cs | 1 -
.../ProcessQueue/ProcessBookControl.cs | 4 +--
.../ProcessQueueControl.Designer.cs | 28 +++++++++----------
.../ProcessQueue/ProcessQueueControl.cs | 13 +++++----
4 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessBook.cs b/Source/LibationWinForms/ProcessQueue/ProcessBook.cs
index f84db515..7c9778a5 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessBook.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessBook.cs
@@ -131,7 +131,6 @@ namespace LibationWinForms.ProcessQueue
{
ProcessBookResult.Success => ProcessBookStatus.Completed,
ProcessBookResult.Cancelled => ProcessBookStatus.Cancelled,
- ProcessBookResult.FailedRetry => ProcessBookStatus.Queued,
_ => ProcessBookStatus.Failed,
};
}
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessBookControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessBookControl.cs
index 7eee6913..62062468 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessBookControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessBookControl.cs
@@ -72,8 +72,8 @@ namespace LibationWinForms.ProcessQueue
Status = ProcessBookStatus.Cancelled;
break;
case ProcessBookResult.FailedRetry:
- statusText = "Queued";
- Status = ProcessBookStatus.Queued;
+ statusText = "Error, will retry later";
+ Status = ProcessBookStatus.Failed;
break;
case ProcessBookResult.FailedSkip:
statusText = "Error, Skippping";
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
index 3e99394f..f600fd5d 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.Designer.cs
@@ -51,9 +51,9 @@
this.logEntryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.panel4 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
+ this.logCopyBtn = new System.Windows.Forms.Button();
this.clearLogBtn = new System.Windows.Forms.Button();
this.counterTimer = new System.Windows.Forms.Timer(this.components);
- this.logCopyBtn = new System.Windows.Forms.Button();
this.statusStrip1.SuspendLayout();
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
@@ -264,10 +264,21 @@
this.panel2.Size = new System.Drawing.Size(390, 25);
this.panel2.TabIndex = 1;
//
+ // logCopyBtn
+ //
+ this.logCopyBtn.Dock = System.Windows.Forms.DockStyle.Left;
+ this.logCopyBtn.Location = new System.Drawing.Point(0, 0);
+ this.logCopyBtn.Name = "logCopyBtn";
+ this.logCopyBtn.Size = new System.Drawing.Size(57, 23);
+ this.logCopyBtn.TabIndex = 1;
+ this.logCopyBtn.Text = "Copy";
+ this.logCopyBtn.UseVisualStyleBackColor = true;
+ this.logCopyBtn.Click += new System.EventHandler(this.LogCopyBtn_Click);
+ //
// clearLogBtn
//
- this.clearLogBtn.Dock = System.Windows.Forms.DockStyle.Left;
- this.clearLogBtn.Location = new System.Drawing.Point(0, 0);
+ this.clearLogBtn.Dock = System.Windows.Forms.DockStyle.Right;
+ this.clearLogBtn.Location = new System.Drawing.Point(328, 0);
this.clearLogBtn.Name = "clearLogBtn";
this.clearLogBtn.Size = new System.Drawing.Size(60, 23);
this.clearLogBtn.TabIndex = 0;
@@ -280,17 +291,6 @@
this.counterTimer.Interval = 950;
this.counterTimer.Tick += new System.EventHandler(this.CounterTimer_Tick);
//
- // logCopyBtn
- //
- this.logCopyBtn.Dock = System.Windows.Forms.DockStyle.Right;
- this.logCopyBtn.Location = new System.Drawing.Point(331, 0);
- this.logCopyBtn.Name = "logCopyBtn";
- this.logCopyBtn.Size = new System.Drawing.Size(57, 23);
- this.logCopyBtn.TabIndex = 1;
- this.logCopyBtn.Text = "Copy";
- this.logCopyBtn.UseVisualStyleBackColor = true;
- this.logCopyBtn.Click += new System.EventHandler(this.LogCopyBtn_Click);
- //
// ProcessQueueControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
diff --git a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
index f1830f51..a55dc071 100644
--- a/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
+++ b/Source/LibationWinForms/ProcessQueue/ProcessQueueControl.cs
@@ -151,12 +151,15 @@ namespace LibationWinForms.ProcessQueue
var result = await nextBook.ProcessOneAsync();
- if (result == ProcessBookResult.FailedRetry)
- Queue.Enqueue(nextBook);
- else if (result == ProcessBookResult.ValidationFail)
+ if (result == ProcessBookResult.ValidationFail)
Queue.ClearCurrent();
else if (result == ProcessBookResult.FailedAbort)
- return;
+ Queue.ClearQueue();
+ else if (result == ProcessBookResult.FailedSkip)
+ {
+ nextBook.LibraryBook.Book.UserDefinedItem.BookStatus = DataLayer.LiberatedStatus.Error;
+ ApplicationServices.LibraryCommands.UpdateUserDefinedItem(nextBook.LibraryBook.Book);
+ }
}
Queue_CompletedCountChanged(this, 0);
counterTimer.Stop();
@@ -176,7 +179,7 @@ namespace LibationWinForms.ProcessQueue
private void Queue_CompletedCountChanged(object sender, int e)
{
- int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.ValidationFail);
+ int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.FailedRetry or ProcessBookResult.ValidationFail);
int completeCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.Success);
ErrorCount = errCount;
From e26deb90923dda188a52dc6c1ebdabcfc5f5d67d Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Tue, 24 May 2022 11:15:41 -0600
Subject: [PATCH 14/15] Address comments
---
Source/LibationWinForms/GridView/GridEntry.cs | 14 ++++-
.../GridView/GridEntryBindingList.cs | 62 +++++++++++--------
.../GridView/LiberateButtonStatus.cs | 2 +-
.../LiberateDataGridViewImageButtonColumn.cs | 7 +++
.../GridView/LibraryBookEntry.cs | 18 +++---
.../LibationWinForms/GridView/SeriesEntry.cs | 28 ++++-----
6 files changed, 77 insertions(+), 54 deletions(-)
diff --git a/Source/LibationWinForms/GridView/GridEntry.cs b/Source/LibationWinForms/GridView/GridEntry.cs
index 6757ef60..6d7e9cd8 100644
--- a/Source/LibationWinForms/GridView/GridEntry.cs
+++ b/Source/LibationWinForms/GridView/GridEntry.cs
@@ -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> _memberValues { get; set; }
+ protected abstract Dictionary> 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
diff --git a/Source/LibationWinForms/GridView/GridEntryBindingList.cs b/Source/LibationWinForms/GridView/GridEntryBindingList.cs
index 511e2ce6..b5ee0f8f 100644
--- a/Source/LibationWinForms/GridView/GridEntryBindingList.cs
+++ b/Source/LibationWinForms/GridView/GridEntryBindingList.cs
@@ -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, IBindingListView
{
- private bool isSorted;
- private ListSortDirection listSortDirection;
- private PropertyDescriptor propertyDescriptor;
-
public GridEntryBindingList() : base(new List()) { }
public GridEntryBindingList(IEnumerable enumeration) : base(new List(enumeration)) { }
/// All items in the list, including those filtered out.
public List AllItems() => Items.Concat(FilterRemoved).ToList();
+ public bool SupportsFiltering => true;
+ public string Filter { get => FilterString; set => ApplyFilter(value); }
protected MemberComparer 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); }
- ///
- /// Items that were removed from the base list due to filtering
- ///
+ /// Items that were removed from the base list due to filtering
private readonly List 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,36 +171,52 @@ namespace LibationWinForms.GridView
{
var itemsList = (List)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)
{
- var item = Items[e.NewIndex];
- Sort();
- var newIndex = Items.IndexOf(item);
+ 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;
+ }
+ }
- base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
+ 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);
+ base.OnListChanged(e);
}
protected override void RemoveSortCore()
diff --git a/Source/LibationWinForms/GridView/LiberateButtonStatus.cs b/Source/LibationWinForms/GridView/LiberateButtonStatus.cs
index 3ee577fd..21c207d0 100644
--- a/Source/LibationWinForms/GridView/LiberateButtonStatus.cs
+++ b/Source/LibationWinForms/GridView/LiberateButtonStatus.cs
@@ -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; }
///
/// Defines the Liberate column's sorting behavior
diff --git a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
index f7291962..b7f0eaa7 100644
--- a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
@@ -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(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";
diff --git a/Source/LibationWinForms/GridView/LibraryBookEntry.cs b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
index 8d93ebff..6a312ea1 100644
--- a/Source/LibationWinForms/GridView/LibraryBookEntry.cs
+++ b/Source/LibationWinForms/GridView/LibraryBookEntry.cs
@@ -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; }
@@ -77,8 +78,7 @@ namespace LibationWinForms.GridView
private void setLibraryBook(LibraryBook libraryBook)
{
- LibraryBook = libraryBook;
- _memberValues = CreateMemberValueDictionary();
+ LibraryBook = libraryBook;
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 for all sorting
- public override object GetMemberValue(string memberName) => _memberValues[memberName]();
- private Dictionary> _memberValues { get; set; }
-
- ///
- /// Create getters for all member object values by name
- ///
- private Dictionary> CreateMemberValueDictionary() => new()
+ /// Create getters for all member object values by name
+ protected override Dictionary> CreateMemberValueDictionary() => new()
{
{ nameof(Title), () => Book.TitleSortable() },
{ nameof(Series), () => Book.SeriesSortable() },
diff --git a/Source/LibationWinForms/GridView/SeriesEntry.cs b/Source/LibationWinForms/GridView/SeriesEntry.cs
index 65cb648e..96d40f49 100644
--- a/Source/LibationWinForms/GridView/SeriesEntry.cs
+++ b/Source/LibationWinForms/GridView/SeriesEntry.cs
@@ -10,6 +10,7 @@ namespace LibationWinForms.GridView
{
public List 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 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 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 for all sorting
- public override object GetMemberValue(string memberName) => _memberValues[memberName]();
- private Dictionary> _memberValues { get; set; }
-
- ///
- /// Create getters for all member object values by name
- ///
- private Dictionary> CreateMemberValueDictionary() => new()
+ /// Create getters for all member object values by name
+ protected override Dictionary> CreateMemberValueDictionary() => new()
{
{ nameof(Title), () => Book.SeriesSortable() },
{ nameof(Series), () => Book.SeriesSortable() },
From 68735a45dd4f90229f4ade1243bc8d83f5a9265e Mon Sep 17 00:00:00 2001
From: Michael Bucari-Tovo
Date: Tue, 24 May 2022 11:52:33 -0600
Subject: [PATCH 15/15] Change episode color
---
.../GridView/LiberateDataGridViewImageButtonColumn.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
index b7f0eaa7..62c56538 100644
--- a/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
+++ b/Source/LibationWinForms/GridView/LiberateDataGridViewImageButtonColumn.cs
@@ -16,7 +16,7 @@ namespace LibationWinForms.GridView
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
- private static readonly Color SERIES_BG_COLOR = Color.LightSkyBlue;
+ private static readonly Color SERIES_BG_COLOR = Color.FromArgb(230, 255, 230);
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);