diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj
index a0c9d5bc..1382447b 100644
--- a/AppScaffolding/AppScaffolding.csproj
+++ b/AppScaffolding/AppScaffolding.csproj
@@ -3,7 +3,7 @@
net5.0
- 6.0.5.1
+ 6.0.6.1
diff --git a/DataLayer/EfClasses/UserDefinedItem.cs b/DataLayer/EfClasses/UserDefinedItem.cs
index 1686d3a1..52deb335 100644
--- a/DataLayer/EfClasses/UserDefinedItem.cs
+++ b/DataLayer/EfClasses/UserDefinedItem.cs
@@ -106,6 +106,11 @@ namespace DataLayer
#endregion
#region LiberatedStatuses
+ ///
+ /// Occurs when , , or values change.
+ /// This signals the change of the in-memory value; it does not ensure that the new value has been persisted.
+ ///
+ public static event EventHandler ItemChanged;
private LiberatedStatus _bookStatus;
private LiberatedStatus? _pdfStatus;
@@ -132,13 +137,41 @@ namespace DataLayer
ItemChanged?.Invoke(this, nameof(PdfStatus));
}
}
+ }
+ #endregion
+
+ #region batch changes
+ public static event EventHandler Batch_ItemChanged;
+ public void BatchMode_UpdateBookStatus(LiberatedStatus value)
+ {
+ if (_bookStatus != value)
+ {
+ _bookStatus = value;
+ batchFlag = true;
+ }
+ }
+
+ // don't overwrite current with null. Therefore input is "LiberatedStatus" not "LiberatedStatus?"
+ public void BatchMode_UpdatePdfStatus(LiberatedStatus value)
+ {
+ if (_pdfStatus != value)
+ {
+ _pdfStatus = value;
+ batchFlag = true;
+ }
+ }
+
+ private static bool batchFlag = false;
+
+ public static void BatchMode_Finalize()
+ {
+ if (batchFlag)
+ Batch_ItemChanged?.Invoke(null, null);
+
+ batchFlag = false;
}
#endregion
- ///
- /// Occurs when , , or values change.
- /// This signals the change of the in-memory value; it does not ensure that the new value has been persisted.
- ///
- public static event EventHandler ItemChanged;
+
public override string ToString() => $"{Book} {Rating} {Tags}";
}
}
diff --git a/LibationSearchEngine/SearchEngine.cs b/LibationSearchEngine/SearchEngine.cs
index 01fdde9b..dd12ae45 100644
--- a/LibationSearchEngine/SearchEngine.cs
+++ b/LibationSearchEngine/SearchEngine.cs
@@ -315,7 +315,7 @@ namespace LibationSearchEngine
var docs = searcher.Search(query, 1);
var scoreDoc = docs.ScoreDocs.SingleOrDefault();
if (scoreDoc == null)
- throw new Exception("document not found");
+ return;
var document = searcher.Doc(scoreDoc.Doc);
diff --git a/LibationWinForms/Form1.cs b/LibationWinForms/Form1.cs
index 38922123..b02257bb 100644
--- a/LibationWinForms/Form1.cs
+++ b/LibationWinForms/Form1.cs
@@ -34,6 +34,8 @@ namespace LibationWinForms
this.FormClosing += (_, _) => this.SaveSizeAndLocation(Configuration.Instance);
LibraryCommands.LibrarySizeChanged += reloadGridAndUpdateBottomNumbers;
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts;
+ // used by async migrations to update ui when complete
+ DataLayer.UserDefinedItem.Batch_ItemChanged += reloadGridAndUpdateBottomNumbers;
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
diff --git a/LibationWinForms/GridEntry.cs b/LibationWinForms/GridEntry.cs
index 10f6e11a..5396cac2 100644
--- a/LibationWinForms/GridEntry.cs
+++ b/LibationWinForms/GridEntry.cs
@@ -27,17 +27,16 @@ namespace LibationWinForms
#endregion
+ public event EventHandler Committed;
+
private Book Book => LibraryBook.Book;
private Image _cover;
- private Action Refilter { get; }
- public GridEntry(LibraryBook libraryBook, Action refilterOnChanged = null)
+ public GridEntry(LibraryBook libraryBook)
{
LibraryBook = libraryBook;
- Refilter = refilterOnChanged;
_memberValues = CreateMemberValueDictionary();
-
//Get cover art. If it's default, subscribe to PictureCached
{
(bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(new FileManager.PictureDefinition(Book.PictureId, FileManager.PictureSize._80x80));
@@ -142,7 +141,7 @@ namespace LibationWinForms
Book.UserDefinedItem.BookStatus = displayStatus;
- Refilter?.Invoke();
+ Committed?.Invoke(this, null);
}
#endregion
diff --git a/LibationWinForms/ProductsGrid.cs b/LibationWinForms/ProductsGrid.cs
index 2f7a3196..9fcfe145 100644
--- a/LibationWinForms/ProductsGrid.cs
+++ b/LibationWinForms/ProductsGrid.cs
@@ -3,9 +3,9 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
-using DataLayer;
using Dinah.Core;
using Dinah.Core.DataBinding;
+using Dinah.Core.Threading;
using Dinah.Core.Windows.Forms;
using LibationWinForms.Dialogs;
@@ -130,7 +130,12 @@ namespace LibationWinForms
}
var orderedGridEntries = lib
- .Select(lb => new GridEntry(lb, Filter)).ToList()
+ .Select(lb =>
+ {
+ var entry = new GridEntry(lb);
+ entry.Committed += (_, __) => Filter();
+ return entry;
+ }).ToList()
// default load order
.OrderByDescending(ge => (DateTime)ge.GetMemberValue(nameof(ge.PurchaseDate)))
//// more advanced example: sort by author, then series, then title
@@ -166,8 +171,11 @@ namespace LibationWinForms
var bindingContext = BindingContext[_dataGridView.DataSource];
bindingContext.SuspendBinding();
{
- for (var r = _dataGridView.RowCount - 1; r >= 0; r--)
- _dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).AudibleProductId);
+ this.UIThreadSync(() =>
+ {
+ for (var r = _dataGridView.RowCount - 1; r >= 0; r--)
+ _dataGridView.Rows[r].Visible = productIds.Contains(getGridEntry(r).AudibleProductId);
+ });
}
//Causes repainting of the DataGridView
diff --git a/LibationWinForms/Program.cs b/LibationWinForms/Program.cs
index 80be122a..cde703b9 100644
--- a/LibationWinForms/Program.cs
+++ b/LibationWinForms/Program.cs
@@ -259,22 +259,25 @@ namespace LibationWinForms
// assign these strings and enums/ints unconditionally. EFCore will only update if changed
if (fileType == FileType.PDF)
- book.UserDefinedItem.PdfStatus = LiberatedStatus.Liberated;
+ book.UserDefinedItem.BatchMode_UpdatePdfStatus(LiberatedStatus.Liberated);
if (fileType == FileType.Audio)
{
var lhack = libhackFiles.FirstOrDefault(f => f.ContainsInsensitive(asin));
if (lhack is null)
- book.UserDefinedItem.BookStatus = LiberatedStatus.Liberated;
+ book.UserDefinedItem.BatchMode_UpdateBookStatus(LiberatedStatus.Liberated);
else
{
- book.UserDefinedItem.BookStatus = LiberatedStatus.Error;
+ book.UserDefinedItem.BatchMode_UpdateBookStatus(LiberatedStatus.Error);
libhackFilesToDelete.Add(lhack);
}
}
}
+ // in order: save to db, full reindex from db, refresh ui
context.SaveChanges();
+ ApplicationServices.SearchEngineCommands.FullReIndex();
+ UserDefinedItem.BatchMode_Finalize();
// only do this after save changes
foreach (var libhackFile in libhackFilesToDelete)