Files
Libation/Source/LibationWinForms/Dialogs/TrashBinDialog.cs
Michael Bucari-Tovo 659f793eb8 Improve TrashBinDialog functionality
- Use the main display grid control to display deleted books
- Added search functionality for deleted books. This required creating a temporary search index in the `InProgress` folder. The products grid control now uses an instance of `ISearchEngine` to filter its grid entries.  The main grid uses a singleton instance of `MainSearchEngine`, which merely wraps `SearchEngineCommands.Search()`.  The TrashBinDialogs use `TempSearchEngine`.
- Users can now batch select `Everyting` as well as `Audible Plus Books`

Avalonia:
  - Refactor main grid context menus to no longer require reflection
2026-01-09 16:47:37 -07:00

163 lines
4.8 KiB
C#

using ApplicationServices;
using DataLayer;
using Dinah.Core.Collections.Generic;
using LibationFileManager;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
#nullable enable
namespace LibationWinForms.Dialogs
{
public partial class TrashBinDialog : Form
{
private string lastGoodFilter = "";
private TempSearchEngine SearchEngine { get; } = new TempSearchEngine();
public TrashBinDialog()
{
InitializeComponent();
this.SetLibationIcon();
this.RestoreSizeAndLocation(Configuration.Instance);
this.FormClosing += (_, _) => this.SaveSizeAndLocation(Configuration.Instance);
deletedCheckedLbl.Text = "";
plusBookcSheckedLbl.Text = "";
productsGrid1.SearchEngine = SearchEngine;
productsGrid1.RemovableCountChanged += (_, _) => UpdateCounts();
productsGrid1.VisibleCountChanged += (_, _) => UpdateCounts();
Load += TrashBinDialog_Load;
}
private IEnumerable<LibraryBook> GetCheckedBooks() => productsGrid1.GetVisibleGridEntries().Where(i => i.Remove is true).Select(i => i.LibraryBook);
private async void TrashBinDialog_Load(object? sender, EventArgs e)
{
productsGrid1.RemoveColumnVisible = true;
await InitAsync();
}
private void UpdateCounts()
{
var visible = productsGrid1.GetVisibleGridEntries().ToArray();
var plusVisibleCount = visible.Count(e => e.LibraryBook.IsAudiblePlus);
var checkedCount = visible.Count(e => e.Remove is true);
var plusCheckedCount = visible.Count(e => e.LibraryBook.IsAudiblePlus && e.Remove is true);
deletedCheckedLbl.Text = $"Checked: {checkedCount} of {visible.Length}";
plusBookcSheckedLbl.Text = $"Checked: {plusCheckedCount} of {plusVisibleCount}";
everythingCb.CheckStateChanged -= everythingCb_CheckStateChanged;
everythingCb.CheckState = checkedCount == 0 || visible.Length == 0 ? CheckState.Unchecked
: checkedCount == visible.Length ? CheckState.Checked
: CheckState.Indeterminate;
everythingCb.CheckStateChanged += everythingCb_CheckStateChanged;
audiblePlusCb.CheckStateChanged -= audiblePlusCb_CheckStateChanged;
audiblePlusCb.CheckState = plusCheckedCount == 0 || plusVisibleCount == 0 ? CheckState.Unchecked
: plusCheckedCount == plusVisibleCount ? CheckState.Checked
: CheckState.Indeterminate;
audiblePlusCb.CheckStateChanged += audiblePlusCb_CheckStateChanged;
}
private async Task InitAsync()
{
var deletedBooks = DbContexts.GetDeletedLibraryBooks();
SearchEngine.ReindexSearchEngine(deletedBooks);
await productsGrid1.BindToGridAsync(deletedBooks);
}
private void Reload()
{
var deletedBooks = DbContexts.GetDeletedLibraryBooks();
SearchEngine.ReindexSearchEngine(deletedBooks);
productsGrid1.UpdateGrid(deletedBooks);
}
private async void permanentlyDeleteBtn_Click(object sender, EventArgs e)
{
setControlsEnabled(false);
var qtyChanges = await GetCheckedBooks().PermanentlyDeleteBooksAsync();
if (qtyChanges > 0)
Reload();
setControlsEnabled(true);
}
private async void restoreBtn_Click(object sender, EventArgs e)
{
setControlsEnabled(false);
var qtyChanges = await GetCheckedBooks().RestoreBooksAsync();
if (qtyChanges > 0)
Reload();
setControlsEnabled(true);
}
private void setControlsEnabled(bool enabled)
=> Invoke(() => productsGrid1.Enabled = restoreBtn.Enabled = permanentlyDeleteBtn.Enabled = everythingCb.Enabled = enabled);
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
searchBtn_Click(sender, e);
}
private void searchBtn_Click(object sender, EventArgs e)
{
try
{
productsGrid1.Filter(textBox1.Text);
lastGoodFilter = textBox1.Text;
}
catch
{
productsGrid1.Filter(lastGoodFilter);
}
}
private void audiblePlusCb_CheckStateChanged(object? sender, EventArgs e)
{
switch (audiblePlusCb.CheckState)
{
case CheckState.Checked:
SetVisibleChecked(e => e.IsAudiblePlus, isChecked: true);
break;
case CheckState.Unchecked:
SetVisibleChecked(e => e.IsAudiblePlus, isChecked: false);
break;
default:
audiblePlusCb.CheckState = CheckState.Unchecked;
break;
}
}
private void everythingCb_CheckStateChanged(object? sender, EventArgs e)
{
switch (everythingCb.CheckState)
{
case CheckState.Checked:
SetVisibleChecked(_ => true, isChecked: true);
break;
case CheckState.Unchecked:
SetVisibleChecked(_ => true, isChecked: false);
break;
default:
everythingCb.CheckState = CheckState.Unchecked;
break;
}
}
public void SetVisibleChecked(Func<LibraryBook, bool> predicate, bool isChecked)
{
productsGrid1.GetVisibleGridEntries().Where(e => predicate(e.LibraryBook)).ForEach(i => i.Remove = isChecked);
UpdateCounts();
}
}
}