Make Form1 MVVM

This commit is contained in:
Michael Bucari-Tovo 2022-07-15 00:23:22 -06:00
parent 7b7e1d8574
commit 180d591b0a
15 changed files with 402 additions and 369 deletions

View File

@ -1,17 +1,236 @@
using System; using ApplicationServices;
using System.Collections.Generic; using Dinah.Core;
using System.Linq; using LibationFileManager;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI; using ReactiveUI;
namespace LibationWinForms.AvaloniaUI.ViewModels namespace LibationWinForms.AvaloniaUI.ViewModels
{ {
public class MainWindowViewModel : ViewModelBase public class MainWindowViewModel : ViewModelBase
{ {
private string _filterString;
private string _removeBooksButtonText = "Remove # Books from Libation"; private string _removeBooksButtonText = "Remove # Books from Libation";
private bool _autoScanChecked = true;
private bool _firstFilterIsDefault = true;
private bool _removeButtonsVisible = true; private bool _removeButtonsVisible = true;
private int _numAccountsScanning = 2;
private int _accountsCount = 0;
private bool _queueOpen = true;
private int _visibleCount = 1;
private LibraryCommands.LibraryStats _libraryStats;
private int _visibleNotLiberated = 1;
/// <summary> The Process Queue's viewmodel </summary>
public ProcessQueueViewModel ProcessQueueViewModel { get; } = new ProcessQueueViewModel();
/// <summary> Library filterting query </summary>
public string FilterString { get => _filterString; set => this.RaiseAndSetIfChanged(ref _filterString, value); }
/// <summary> Display text for the "Remove # Books from Libation" button </summary>
public string RemoveBooksButtonText { get => _removeBooksButtonText; set => this.RaiseAndSetIfChanged(ref _removeBooksButtonText, value); } public string RemoveBooksButtonText { get => _removeBooksButtonText; set => this.RaiseAndSetIfChanged(ref _removeBooksButtonText, value); }
public bool RemoveButtonsVisible { get => _removeButtonsVisible; set => this.RaiseAndSetIfChanged(ref _removeButtonsVisible, value); }
/// <summary> Auto scanning accounts is enables </summary>
public bool AutoScanChecked
{
get => _autoScanChecked;
set
{
if (value != _autoScanChecked)
Configuration.Instance.AutoScan = value;
this.RaiseAndSetIfChanged(ref _autoScanChecked, value);
}
}
/// <summary> Indicates that the first quick filter is the default filter </summary>
public bool FirstFilterIsDefault
{
get => _firstFilterIsDefault;
set
{
if (value != _firstFilterIsDefault)
QuickFilters.UseDefault = value;
this.RaiseAndSetIfChanged(ref _firstFilterIsDefault, value);
}
}
/// <summary> Indicates if the "Remove # Books from Libation" and "Done Removing" buttons shouls be visible </summary>
public bool RemoveButtonsVisible
{
get => _removeButtonsVisible;
set
{
this.RaiseAndSetIfChanged(ref _removeButtonsVisible, value);
this.RaisePropertyChanged(nameof(RemoveMenuItemsEnabled));
}
}
/// <summary> The number of accounts currently being scanned </summary>
public int NumAccountsScanning
{
get => _numAccountsScanning;
set
{
this.RaiseAndSetIfChanged(ref _numAccountsScanning, value);
this.RaisePropertyChanged(nameof(ActivelyScanning));
this.RaisePropertyChanged(nameof(RemoveMenuItemsEnabled));
this.RaisePropertyChanged(nameof(ScanningText));
}
}
/// <summary> Indicates that Libation is currently scanning account(s) </summary>
public bool ActivelyScanning => _numAccountsScanning > 0;
/// <summary> Indicates if the "Remove Books" menu items are enabled</summary>
public bool RemoveMenuItemsEnabled => !RemoveButtonsVisible && !ActivelyScanning;
/// <summary> The library scanning status text </summary>
public string ScanningText => _numAccountsScanning == 1 ? "Scanning..." : $"Scanning {_numAccountsScanning} accounts...";
/// <summary> The number of accounts added to Libation </summary>
public int AccountsCount
{
get => _accountsCount;
set
{
this.RaiseAndSetIfChanged(ref _accountsCount, value);
this.RaisePropertyChanged(nameof(ZeroAccounts));
this.RaisePropertyChanged(nameof(AnyAccounts));
this.RaisePropertyChanged(nameof(OneAccount));
this.RaisePropertyChanged(nameof(MultipleAccounts));
}
}
/// <summary> There are no Audible accounts </summary>
public bool ZeroAccounts => _accountsCount == 0;
/// <summary> There is at least one Audible account </summary>
public bool AnyAccounts => _accountsCount > 0;
/// <summary> There is exactly one Audible account </summary>
public bool OneAccount => _accountsCount == 1;
/// <summary> There are more than 1 Audible accounts </summary>
public bool MultipleAccounts => _accountsCount > 1;
/// <summary> The Process Queue panel is open </summary>
public bool QueueOpen
{
get => _queueOpen;
set
{
this.RaiseAndSetIfChanged(ref _queueOpen, value);
QueueHideButtonText = _queueOpen? "❱❱❱" : "❰❰❰";
this.RaisePropertyChanged(nameof(QueueHideButtonText));
}
}
/// <summary> The Process Queue's Expand/Collapse button display text </summary>
public string QueueHideButtonText { get; private set; }
/// <summary> The number of books visible in the Product Display </summary>
public int VisibleCount
{
get => _visibleCount;
set
{
this.RaiseAndSetIfChanged(ref _visibleCount, value);
this.RaisePropertyChanged(nameof(VisibleCountText));
this.RaisePropertyChanged(nameof(VisibleCountMenuItemText));
}
}
/// <summary> The Bottom-right visible book count status text </summary>
public string VisibleCountText => $"Visible: {VisibleCount}";
/// <summary> The Visible Books menu item header text </summary>
public string VisibleCountMenuItemText => $"_Visible Books {VisibleCount}";
/// <summary> The user's library statistics </summary>
public LibraryCommands.LibraryStats LibraryStats
{
get => _libraryStats;
set
{
this.RaiseAndSetIfChanged(ref _libraryStats, value);
var backupsCountText
= !LibraryStats.HasBookResults ? "No books. Begin by importing your library"
: !LibraryStats.HasPendingBooks ? $"All {"book".PluralizeWithCount(LibraryStats.booksFullyBackedUp)} backed up"
: $"BACKUPS: No progress: {LibraryStats.booksNoProgress} In process: {LibraryStats.booksDownloadedOnly} Fully backed up: {LibraryStats.booksFullyBackedUp} {(LibraryStats.booksError > 0 ? $" Errors : {LibraryStats.booksError}" : "")}";
var pdfCountText
= !LibraryStats.HasPdfResults ? ""
: LibraryStats.pdfsNotDownloaded == 0 ? $" | All {LibraryStats.pdfsDownloaded} PDFs downloaded"
: $" | PDFs: NOT d/l'ed: {LibraryStats.pdfsNotDownloaded} Downloaded: {LibraryStats.pdfsDownloaded}";
StatusCountText = backupsCountText + pdfCountText;
BookBackupsToolStripText
= LibraryStats.HasPendingBooks
? $"Begin _Book and PDF Backups: {LibraryStats.PendingBooks} remaining"
: "All books have been liberated";
PdfBackupsToolStripText
= LibraryStats.pdfsNotDownloaded > 0
? $"Begin _PDF Only Backups: {LibraryStats.pdfsNotDownloaded} remaining"
: "All PDFs have been downloaded";
this.RaisePropertyChanged(nameof(HasBookResults));
this.RaisePropertyChanged(nameof(StatusCountText));
this.RaisePropertyChanged(nameof(BookBackupsToolStripText));
this.RaisePropertyChanged(nameof(PdfBackupsToolStripText));
}
}
/// <summary> Indicates whether the library contains any books </summary>
public bool HasBookResults => LibraryStats?.HasBookResults ?? false;
/// <summary> Bottom-left library statistics display text </summary>
public string StatusCountText { get; private set; } = "[Calculating backed up book quantities] | [Calculating backed up PDFs]";
/// <summary> The "Begin Book and PDF Backup" menu item header text </summary>
public string BookBackupsToolStripText { get; private set; } = "Begin _Book and PDF Backups: 0";
/// <summary> The "Begin PDF Only Backup" menu item header text </summary>
public string PdfBackupsToolStripText { get; private set; } = "Begin _PDF Only Backups: 0";
/// <summary> The number of books visible in the Products Display that have not yet been liberated </summary>
public int VisibleNotLiberated
{
get => _visibleNotLiberated;
set
{
this.RaiseAndSetIfChanged(ref _visibleNotLiberated, value);
LiberateVisibleToolStripText
= AnyVisibleNotLiberated
? $"Liberate _Visible Books: {VisibleNotLiberated}"
: "All visible books are liberated";
LiberateVisibleToolStripText_2
= AnyVisibleNotLiberated
? $"_Liberate: {VisibleNotLiberated}"
: "All visible books are liberated";
this.RaisePropertyChanged(nameof(AnyVisibleNotLiberated));
this.RaisePropertyChanged(nameof(LiberateVisibleToolStripText));
this.RaisePropertyChanged(nameof(LiberateVisibleToolStripText_2));
}
}
/// <summary> Indicates if any of the books visible in the Products Display haven't been liberated </summary>
public bool AnyVisibleNotLiberated => VisibleNotLiberated > 0;
/// <summary> The "Liberate Visible Books" menu item header text (submenu item of the "Liberate Menu" menu item) </summary>
public string LiberateVisibleToolStripText { get; private set; } = "Liberate _Visible Books: 0";
/// <summary> The "Liberate" menu item header text (submenu item of the "Visible Books" menu item) </summary>
public string LiberateVisibleToolStripText_2 { get; private set; } = "_Liberate: 0";
} }
} }

View File

@ -1,5 +1,6 @@
using ApplicationServices; using ApplicationServices;
using Avalonia.Threading; using Avalonia.Threading;
using DataLayer;
using ReactiveUI; using ReactiveUI;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -19,10 +20,13 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
public Task QueueRunner { get; private set; } public Task QueueRunner { get; private set; }
public bool Running => !QueueRunner?.IsCompleted ?? false; public bool Running => !QueueRunner?.IsCompleted ?? false;
private readonly ProcessQueue.LogMe Logger;
public ProcessQueueViewModel() public ProcessQueueViewModel()
{ {
Queue.QueuededCountChanged += Queue_QueuededCountChanged; Queue.QueuededCountChanged += Queue_QueuededCountChanged;
Queue.CompletedCountChanged += Queue_CompletedCountChanged; Queue.CompletedCountChanged += Queue_CompletedCountChanged;
Logger = ProcessQueue.LogMe.RegisterForm(this);
} }
private int _completedCount; private int _completedCount;
@ -66,6 +70,73 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
})); }));
} }
#region Add Books to Queue
private bool isBookInQueue(LibraryBook libraryBook)
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
public void AddDownloadPdf(LibraryBook libraryBook)
=> AddDownloadPdf(new List<LibraryBook>() { libraryBook });
public void AddDownloadDecrypt(LibraryBook libraryBook)
=> AddDownloadDecrypt(new List<LibraryBook>() { libraryBook });
public void AddConvertMp3(LibraryBook libraryBook)
=> AddConvertMp3(new List<LibraryBook>() { libraryBook });
public void AddDownloadPdf(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddDownloadPdf();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
AddToQueue(procs);
}
public void AddDownloadDecrypt(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddDownloadDecryptBook();
pbook.AddDownloadPdf();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
AddToQueue(procs);
}
public void AddConvertMp3(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddConvertToMp3();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
AddToQueue(procs);
}
public void AddToQueue(IEnumerable<ProcessBook2> pbook) public void AddToQueue(IEnumerable<ProcessBook2> pbook)
{ {
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
@ -76,6 +147,8 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
}); });
} }
#endregion
DateTime StartingTime; DateTime StartingTime;
private async Task QueueLoop() private async Task QueueLoop()
{ {

View File

@ -12,21 +12,12 @@ namespace LibationWinForms.AvaloniaUI.Views
private System.ComponentModel.BackgroundWorker updateCountsBw = new(); private System.ComponentModel.BackgroundWorker updateCountsBw = new();
private void Configure_BackupCounts() private void Configure_BackupCounts()
{ {
// init formattable
beginBookBackupsToolStripMenuItem.Format(0);
beginPdfBackupsToolStripMenuItem.Format(0);
pdfsCountsLbl.Text = "| [Calculating backed up PDFs]";
Load += setBackupCounts; Load += setBackupCounts;
LibraryCommands.LibrarySizeChanged += setBackupCounts; LibraryCommands.LibrarySizeChanged += setBackupCounts;
LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts; LibraryCommands.BookUserDefinedItemCommitted += setBackupCounts;
updateCountsBw.DoWork += UpdateCountsBw_DoWork; updateCountsBw.DoWork += UpdateCountsBw_DoWork;
updateCountsBw.RunWorkerCompleted += exportMenuEnable; updateCountsBw.RunWorkerCompleted += updateBottomNumbersAsync;
updateCountsBw.RunWorkerCompleted += updateBottomBookNumbers;
updateCountsBw.RunWorkerCompleted += update_BeginBookBackups_menuItem;
updateCountsBw.RunWorkerCompleted += updateBottomPdfNumbersAsync;
updateCountsBw.RunWorkerCompleted += udpate_BeginPdfOnlyBackups_menuItem;
} }
private bool runBackupCountsAgain; private bool runBackupCountsAgain;
private void setBackupCounts(object _, object __) private void setBackupCounts(object _, object __)
@ -45,74 +36,9 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
} }
private void exportMenuEnable(object _, System.ComponentModel.RunWorkerCompletedEventArgs e) private void updateBottomNumbersAsync(object _, System.ComponentModel.RunWorkerCompletedEventArgs e)
{ {
var libraryStats = e.Result as LibraryCommands.LibraryStats; _viewModel.LibraryStats = e.Result as LibraryCommands.LibraryStats;
Dispatcher.UIThread.Post(() => exportLibraryToolStripMenuItem.IsEnabled = libraryStats.HasBookResults);
}
// this cannot be cleanly be FormattableToolStripMenuItem because of the optional "Errors" text
private const string backupsCountsLbl_Format = "BACKUPS: No progress: {0} In process: {1} Fully backed up: {2}";
private void updateBottomBookNumbers(object _, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
var libraryStats = e.Result as LibraryCommands.LibraryStats;
var formatString
= !libraryStats.HasBookResults ? "No books. Begin by importing your library"
: libraryStats.booksError > 0 ? backupsCountsLbl_Format + " Errors: {3}"
: libraryStats.HasPendingBooks ? backupsCountsLbl_Format
: $"All {"book".PluralizeWithCount(libraryStats.booksFullyBackedUp)} backed up";
var statusStripText = string.Format(formatString,
libraryStats.booksNoProgress,
libraryStats.booksDownloadedOnly,
libraryStats.booksFullyBackedUp,
libraryStats.booksError);
Dispatcher.UIThread.InvokeAsync(() => backupsCountsLbl.Text = statusStripText);
}
// update 'begin book backups' menu item
private void update_BeginBookBackups_menuItem(object _, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
var libraryStats = e.Result as LibraryCommands.LibraryStats;
var menuItemText
= libraryStats.HasPendingBooks
? $"{libraryStats.PendingBooks} remaining"
: "All books have been liberated";
Dispatcher.UIThread.InvokeAsync(() =>
{
beginBookBackupsToolStripMenuItem.Format(menuItemText);
beginBookBackupsToolStripMenuItem.IsEnabled = libraryStats.HasPendingBooks;
});
}
private async void updateBottomPdfNumbersAsync(object _, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
var libraryStats = e.Result as LibraryCommands.LibraryStats;
// don't need to assign the output of Format(). It just makes this logic cleaner
var statusStripText
= !libraryStats.HasPdfResults ? ""
: libraryStats.pdfsNotDownloaded > 0 ? await Dispatcher.UIThread.InvokeAsync(()=> pdfsCountsLbl.Format(libraryStats.pdfsNotDownloaded, libraryStats.pdfsDownloaded))
: $" | All {libraryStats.pdfsDownloaded} PDFs downloaded";
await Dispatcher.UIThread.InvokeAsync(() => pdfsCountsLbl.Text = statusStripText);
}
// update 'begin pdf only backups' menu item
private void udpate_BeginPdfOnlyBackups_menuItem(object _, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
var libraryStats = e.Result as LibraryCommands.LibraryStats;
var menuItemText
= libraryStats.pdfsNotDownloaded > 0
? $"{libraryStats.pdfsNotDownloaded} remaining"
: "All PDFs have been downloaded";
Dispatcher.UIThread.InvokeAsync(() =>
{
beginPdfBackupsToolStripMenuItem.Format(menuItemText);
beginPdfBackupsToolStripMenuItem.IsEnabled = libraryStats.pdfsNotDownloaded > 0;
});
} }
} }
} }

View File

@ -18,7 +18,7 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
if (e.Key == Key.Return) if (e.Key == Key.Return)
{ {
await performFilter(this.filterSearchTb.Text); await performFilter(_viewModel.FilterString);
// silence the 'ding' // silence the 'ding'
e.Handled = true; e.Handled = true;
@ -26,12 +26,12 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
public async void filterBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public async void filterBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
=> await performFilter(this.filterSearchTb.Text); => await performFilter(_viewModel.FilterString);
private string lastGoodFilter = ""; private string lastGoodFilter = "";
private async Task performFilter(string filterString) private async Task performFilter(string filterString)
{ {
this.filterSearchTb.Text = filterString; _viewModel.FilterString = filterString;
try try
{ {

View File

@ -19,7 +19,7 @@ namespace LibationWinForms.AvaloniaUI.Views
Serilog.Log.Logger.Information("Begin backing up all library books"); Serilog.Log.Logger.Information("Begin backing up all library books");
processBookQueue1.AddDownloadDecrypt( _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(
ApplicationServices.DbContexts ApplicationServices.DbContexts
.GetLibrary_Flat_NoTracking() .GetLibrary_Flat_NoTracking()
.UnLiberated() .UnLiberated()
@ -34,7 +34,7 @@ namespace LibationWinForms.AvaloniaUI.Views
public async void beginPdfBackupsToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs args) public async void beginPdfBackupsToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs args)
{ {
SetQueueCollapseState(false); SetQueueCollapseState(false);
await Task.Run(() => processBookQueue1.AddDownloadPdf(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking() await Task.Run(() => _viewModel.ProcessQueueViewModel.AddDownloadPdf(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
.Where(lb => lb.Book.UserDefinedItem.PdfStatus is DataLayer.LiberatedStatus.NotLiberated))); .Where(lb => lb.Book.UserDefinedItem.PdfStatus is DataLayer.LiberatedStatus.NotLiberated)));
} }
@ -51,7 +51,7 @@ namespace LibationWinForms.AvaloniaUI.Views
if (result == DialogResult.Yes) if (result == DialogResult.Yes)
{ {
SetQueueCollapseState(false); SetQueueCollapseState(false);
await Task.Run(() => processBookQueue1.AddConvertMp3(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking() await Task.Run(() => _viewModel.ProcessQueueViewModel.AddConvertMp3(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()
.Where(lb => lb.Book.UserDefinedItem.BookStatus is DataLayer.LiberatedStatus.Liberated && lb.Book.ContentType is DataLayer.ContentType.Product))); .Where(lb => lb.Book.UserDefinedItem.BookStatus is DataLayer.LiberatedStatus.Liberated && lb.Book.ContentType is DataLayer.ContentType.Product)));
} }
//Only Queue Liberated books for conversion. This isn't a perfect filter, but it's better than nothing. //Only Queue Liberated books for conversion. This isn't a perfect filter, but it's better than nothing.

View File

@ -11,7 +11,7 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
private void Configure_ProcessQueue() private void Configure_ProcessQueue()
{ {
var collapseState = !Configuration.Instance.GetNonString<bool>(nameof(splitContainer1.IsPaneOpen)); var collapseState = !Configuration.Instance.GetNonString<bool>(nameof(_viewModel.QueueOpen));
SetQueueCollapseState(collapseState); SetQueueCollapseState(collapseState);
} }
@ -23,13 +23,13 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
Serilog.Log.Logger.Information("Begin single book backup of {libraryBook}", libraryBook); Serilog.Log.Logger.Information("Begin single book backup of {libraryBook}", libraryBook);
SetQueueCollapseState(false); SetQueueCollapseState(false);
processBookQueue1.AddDownloadDecrypt(libraryBook); _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(libraryBook);
} }
else if (libraryBook.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated) else if (libraryBook.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated)
{ {
Serilog.Log.Logger.Information("Begin single pdf backup of {libraryBook}", libraryBook); Serilog.Log.Logger.Information("Begin single pdf backup of {libraryBook}", libraryBook);
SetQueueCollapseState(false); SetQueueCollapseState(false);
processBookQueue1.AddDownloadPdf(libraryBook); _viewModel.ProcessQueueViewModel.AddDownloadPdf(libraryBook);
} }
else if (libraryBook.Book.Audio_Exists()) else if (libraryBook.Book.Audio_Exists())
{ {
@ -49,14 +49,13 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
private void SetQueueCollapseState(bool collapsed) private void SetQueueCollapseState(bool collapsed)
{ {
splitContainer1.IsPaneOpen = !collapsed; _viewModel.QueueOpen = !collapsed;
toggleQueueHideBtn.Content = splitContainer1.IsPaneOpen ? "❱❱❱" : "❰❰❰";
} }
public void ToggleQueueHideBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void ToggleQueueHideBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{ {
SetQueueCollapseState(splitContainer1.IsPaneOpen); SetQueueCollapseState(_viewModel.QueueOpen);
Configuration.Instance.SetObject(nameof(splitContainer1.IsPaneOpen), splitContainer1.IsPaneOpen); Configuration.Instance.SetObject(nameof(_viewModel.QueueOpen), _viewModel.QueueOpen);
} }
} }
} }

View File

@ -11,9 +11,8 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
private void Configure_QuickFilters() private void Configure_QuickFilters()
{ {
Load += updateFirstFilterIsDefaultToolStripMenuItem; _viewModel.FirstFilterIsDefault = QuickFilters.UseDefault;
Load += updateFiltersMenu; Load += updateFiltersMenu;
QuickFilters.UseDefaultChanged += updateFirstFilterIsDefaultToolStripMenuItem;
QuickFilters.Updated += updateFiltersMenu; QuickFilters.Updated += updateFiltersMenu;
} }
@ -49,14 +48,16 @@ namespace LibationWinForms.AvaloniaUI.Views
quickFiltersToolStripMenuItem.Items = allItems; quickFiltersToolStripMenuItem.Items = allItems;
} }
private void updateFirstFilterIsDefaultToolStripMenuItem(object sender, EventArgs e)
=> firstFilterIsDefaultToolStripMenuItem_Checkbox.IsChecked = QuickFilters.UseDefault;
public void firstFilterIsDefaultToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void firstFilterIsDefaultToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
=> QuickFilters.UseDefault = firstFilterIsDefaultToolStripMenuItem_Checkbox.IsChecked != true; {
if (sender is MenuItem mi && mi.Icon is CheckBox checkBox)
{
checkBox.IsChecked = !(checkBox.IsChecked ?? false);
}
}
public void addQuickFilterBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void addQuickFilterBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
=> QuickFilters.Add(this.filterSearchTb.Text); => QuickFilters.Add(_viewModel.FilterString);
public void editQuickFiltersToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => new EditQuickFilters().ShowDialog(); public void editQuickFiltersToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) => new EditQuickFilters().ShowDialog();

View File

@ -14,7 +14,6 @@ namespace LibationWinForms.AvaloniaUI.Views
return; return;
_viewModel.RemoveButtonsVisible = false; _viewModel.RemoveButtonsVisible = false;
removeLibraryBooksToolStripMenuItem.Click += removeLibraryBooksToolStripMenuItem_Click;
} }
public async void removeBooksBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public async void removeBooksBtn_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
@ -29,9 +28,7 @@ namespace LibationWinForms.AvaloniaUI.Views
productsDisplay.CloseRemoveBooksColumn(); productsDisplay.CloseRemoveBooksColumn();
//Restore the filter //Restore the filter
filterSearchTb.IsEnabled = true; await performFilter(_viewModel.FilterString);
filterSearchTb.IsVisible = true;
await performFilter(filterSearchTb.Text);
} }
public void removeLibraryBooksToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public void removeLibraryBooksToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
@ -77,8 +74,6 @@ namespace LibationWinForms.AvaloniaUI.Views
//For removing books within a filter set, use //For removing books within a filter set, use
//Visible Books > Remove from library //Visible Books > Remove from library
filterSearchTb.IsEnabled = false;
filterSearchTb.IsVisible = false;
productsDisplay.Filter(null); productsDisplay.Filter(null);
_viewModel.RemoveButtonsVisible = true; _viewModel.RemoveButtonsVisible = true;

View File

@ -1,5 +1,6 @@
using ApplicationServices; using ApplicationServices;
using AudibleUtilities; using AudibleUtilities;
using Avalonia.Controls;
using Dinah.Core; using Dinah.Core;
using LibationFileManager; using LibationFileManager;
using System; using System;
@ -42,8 +43,8 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
}; };
// load init state to menu checkbox _viewModel.AutoScanChecked = Configuration.Instance.AutoScan;
Load += updateAutoScanLibraryToolStripMenuItem;
// if enabled: begin on load // if enabled: begin on load
Load += startAutoScan; Load += startAutoScan;
@ -52,7 +53,6 @@ namespace LibationWinForms.AvaloniaUI.Views
AccountsSettingsPersister.Saved += accountsPostSave; AccountsSettingsPersister.Saved += accountsPostSave;
// when autoscan setting is changed, update menu checkbox and run autoscan // when autoscan setting is changed, update menu checkbox and run autoscan
Configuration.Instance.AutoScanChanged += updateAutoScanLibraryToolStripMenuItem;
Configuration.Instance.AutoScanChanged += startAutoScan; Configuration.Instance.AutoScanChanged += startAutoScan;
} }
@ -84,7 +84,12 @@ namespace LibationWinForms.AvaloniaUI.Views
else else
autoScanTimer.Stop(); autoScanTimer.Stop();
} }
private void updateAutoScanLibraryToolStripMenuItem(object sender, EventArgs e) => autoScanLibraryToolStripMenuItemCheckbox.IsChecked = Configuration.Instance.AutoScan; public void autoScanLibraryToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void autoScanLibraryToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs args) => Configuration.Instance.AutoScan = autoScanLibraryToolStripMenuItemCheckbox.IsChecked != true; {
if (sender is MenuItem mi && mi.Icon is CheckBox checkBox)
{
checkBox.IsChecked = !(checkBox.IsChecked ?? false);
}
}
} }
} }

View File

@ -22,31 +22,7 @@ namespace LibationWinForms.AvaloniaUI.Views
private void refreshImportMenu(object _, EventArgs __) private void refreshImportMenu(object _, EventArgs __)
{ {
using var persister = AudibleApiStorage.GetAccountsSettingsPersister(); using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
var count = persister.AccountsSettings.Accounts.Count; _viewModel.AccountsCount = persister.AccountsSettings.Accounts.Count;
autoScanLibraryToolStripMenuItem.IsVisible = count > 0;
noAccountsYetAddAccountToolStripMenuItem.IsVisible = count == 0;
scanLibraryToolStripMenuItem.IsVisible = count == 1;
scanLibraryOfAllAccountsToolStripMenuItem.IsVisible = count > 1;
scanLibraryOfSomeAccountsToolStripMenuItem.IsVisible = count > 1;
removeLibraryBooksToolStripMenuItem.IsVisible = count > 0;
//Avalonia will not fire the Click event for a MenuItem with children,
//so if only 1 account, remove the children. Otherwise add children
//for multiple accounts.
removeLibraryBooksToolStripMenuItem.Items = null;
if (count > 1)
{
removeLibraryBooksToolStripMenuItem.Items =
new List<Control>
{
removeSomeAccountsToolStripMenuItem,
removeAllAccountsToolStripMenuItem
};
}
} }
public async void noAccountsYetAddAccountToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) public async void noAccountsYetAddAccountToolStripMenuItem_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)

View File

@ -9,36 +9,18 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
private void Configure_ScanNotification() private void Configure_ScanNotification()
{ {
scanningToolStripMenuItem.IsVisible = false; _viewModel.NumAccountsScanning = 0;
LibraryCommands.ScanBegin += LibraryCommands_ScanBegin; LibraryCommands.ScanBegin += LibraryCommands_ScanBegin;
LibraryCommands.ScanEnd += LibraryCommands_ScanEnd; LibraryCommands.ScanEnd += LibraryCommands_ScanEnd;
} }
private void LibraryCommands_ScanBegin(object sender, int accountsLength) private void LibraryCommands_ScanBegin(object sender, int accountsLength)
{ {
removeLibraryBooksToolStripMenuItem.IsEnabled = false; _viewModel.NumAccountsScanning = accountsLength;
removeAllAccountsToolStripMenuItem.IsEnabled = false;
removeSomeAccountsToolStripMenuItem.IsEnabled = false;
scanLibraryToolStripMenuItem.IsEnabled = false;
scanLibraryOfAllAccountsToolStripMenuItem.IsEnabled = false;
scanLibraryOfSomeAccountsToolStripMenuItem.IsEnabled = false;
this.scanningToolStripMenuItem.IsVisible = true;
this.scanningToolStripMenuItem_Text.Text
= (accountsLength == 1)
? "Scanning..."
: $"Scanning {accountsLength} accounts...";
} }
private void LibraryCommands_ScanEnd(object sender, EventArgs e) private void LibraryCommands_ScanEnd(object sender, EventArgs e)
{ {
removeLibraryBooksToolStripMenuItem.IsEnabled = true; _viewModel.NumAccountsScanning = 0;
removeAllAccountsToolStripMenuItem.IsEnabled = true;
removeSomeAccountsToolStripMenuItem.IsEnabled = true;
scanLibraryToolStripMenuItem.IsEnabled = true;
scanLibraryOfAllAccountsToolStripMenuItem.IsEnabled = true;
scanLibraryOfSomeAccountsToolStripMenuItem.IsEnabled = true;
this.scanningToolStripMenuItem.IsVisible = false;
} }
} }
} }

View File

@ -13,14 +13,6 @@ namespace LibationWinForms.AvaloniaUI.Views
{ {
private void Configure_VisibleBooks() private void Configure_VisibleBooks()
{ {
// init formattable
visibleCountLbl.Format(0);
liberateVisibleToolStripMenuItem_VisibleBooksMenu.Format(0);
liberateVisibleToolStripMenuItem_LiberateMenu.Format(0);
// top menu strip
visibleBooksToolStripMenuItem.Format(0);
LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync; LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync;
} }
@ -35,7 +27,7 @@ namespace LibationWinForms.AvaloniaUI.Views
Serilog.Log.Logger.Information("Begin backing up visible library books"); Serilog.Log.Logger.Information("Begin backing up visible library books");
processBookQueue1.AddDownloadDecrypt( _viewModel.ProcessQueueViewModel.AddDownloadDecrypt(
productsDisplay productsDisplay
.GetVisibleBookEntries() .GetVisibleBookEntries()
.UnLiberated() .UnLiberated()
@ -107,44 +99,14 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
public async void productsDisplay_VisibleCountChanged(object sender, int qty) public async void productsDisplay_VisibleCountChanged(object sender, int qty)
{ {
Dispatcher.UIThread.Post(() => _viewModel.VisibleCount = qty;
{
// bottom-left visible count
visibleCountLbl.Format(qty);
// top menu strip
visibleBooksToolStripMenuItem.Format(qty);
visibleBooksToolStripMenuItem.IsEnabled = qty > 0;
});
//Not used for anything?
var notLiberatedCount = productsDisplay.GetVisibleBookEntries().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
await Task.Run(setLiberatedVisibleMenuItem); await Task.Run(setLiberatedVisibleMenuItem);
} }
void setLiberatedVisibleMenuItem() void setLiberatedVisibleMenuItem()
{ => _viewModel.VisibleNotLiberated
var notLiberated = productsDisplay.GetVisibleBookEntries().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated); = productsDisplay
.GetVisibleBookEntries()
Dispatcher.UIThread.Post(() => .Count(lb => lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.NotLiberated);
{
if (notLiberated > 0)
{
liberateVisibleToolStripMenuItem_VisibleBooksMenu.Format(notLiberated);
liberateVisibleToolStripMenuItem_VisibleBooksMenu.IsEnabled = true;
liberateVisibleToolStripMenuItem_LiberateMenu.Format(notLiberated);
liberateVisibleToolStripMenuItem_LiberateMenu.IsEnabled = true;
}
else
{
liberateVisibleToolStripMenuItem_VisibleBooksMenu.Header = "All visible books are liberated";
liberateVisibleToolStripMenuItem_VisibleBooksMenu.IsEnabled = false;
liberateVisibleToolStripMenuItem_LiberateMenu.Header = "All visible books are liberated";
liberateVisibleToolStripMenuItem_LiberateMenu.IsEnabled = false;
}
});
}
} }
} }

View File

@ -25,6 +25,9 @@
<Setter Property="Height" Value="25"/> <Setter Property="Height" Value="25"/>
</Style> </Style>
</Menu.Styles> </Menu.Styles>
<!-- Import Menu -->
<MenuItem Header="_Import"> <MenuItem Header="_Import">
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<MenuItem.Styles> <MenuItem.Styles>
@ -32,20 +35,26 @@
<Setter Property="Height" Value="NaN"/> <Setter Property="Height" Value="NaN"/>
</Style> </Style>
</MenuItem.Styles> </MenuItem.Styles>
<MenuItem Name="autoScanLibraryToolStripMenuItem" Click="autoScanLibraryToolStripMenuItem_Click" Header="A_uto Scan Library"> <MenuItem IsVisible="{Binding AnyAccounts}" Click="autoScanLibraryToolStripMenuItem_Click" Header="A_uto Scan Library">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox Name="autoScanLibraryToolStripMenuItemCheckbox" BorderThickness="0" IsHitTestVisible="False" /> <CheckBox BorderThickness="0" IsChecked="{Binding AutoScanChecked, Mode=TwoWay}" IsHitTestVisible="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Name="noAccountsYetAddAccountToolStripMenuItem" Click="noAccountsYetAddAccountToolStripMenuItem_Click" Header="No accounts yet. A_dd Account..." /> <MenuItem IsVisible="{Binding !AnyAccounts}" Click="noAccountsYetAddAccountToolStripMenuItem_Click" Header="No accounts yet. A_dd Account..." />
<MenuItem Name="scanLibraryToolStripMenuItem" Click="scanLibraryToolStripMenuItem_Click" Header="Scan _Library" /> <!-- Scan Library -->
<MenuItem Name="scanLibraryOfAllAccountsToolStripMenuItem" Click="scanLibraryOfAllAccountsToolStripMenuItem_Click" Header="Scan Library of _All Accounts" /> <MenuItem IsVisible="{Binding OneAccount}" IsEnabled="{Binding !ActivelyScanning}" Click="scanLibraryToolStripMenuItem_Click" Header="Scan _Library" />
<MenuItem Name="scanLibraryOfSomeAccountsToolStripMenuItem" Click="scanLibraryOfSomeAccountsToolStripMenuItem_Click" Header="Scan Library of _Some Accounts" /> <MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding !ActivelyScanning}" Click="scanLibraryOfAllAccountsToolStripMenuItem_Click" Header="Scan Library of _All Accounts" />
<MenuItem Name="removeLibraryBooksToolStripMenuItem" Click="removeLibraryBooksToolStripMenuItem_Click" Header="_Remove Library Books"> <MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding !ActivelyScanning}" Click="scanLibraryOfSomeAccountsToolStripMenuItem_Click" Header="Scan Library of _Some Accounts" />
<MenuItem Name="removeAllAccountsToolStripMenuItem" Click="removeAllAccountsToolStripMenuItem_Click" Header="All Accounts" /> <Separator />
<MenuItem Name="removeSomeAccountsToolStripMenuItem" Click="removeSomeAccountsToolStripMenuItem_Click" Header="Some Accounts" /> <!-- Remove Books -->
</MenuItem> <MenuItem IsVisible="{Binding OneAccount}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Click="removeLibraryBooksToolStripMenuItem_Click" Header="_Remove Library Books" />
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Click="removeAllAccountsToolStripMenuItem_Click" Header="_Remove Books from All Accounts" />
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Click="removeSomeAccountsToolStripMenuItem_Click" Header="_Remove Books from Some Accounts" />
</MenuItem> </MenuItem>
<!-- Liberate Menu -->
<MenuItem Header="_Liberate"> <MenuItem Header="_Liberate">
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<MenuItem.Styles> <MenuItem.Styles>
@ -53,11 +62,14 @@
<Setter Property="Height" Value="NaN"/> <Setter Property="Height" Value="NaN"/>
</Style> </Style>
</MenuItem.Styles> </MenuItem.Styles>
<controls:FormattableMenuItem Name="beginBookBackupsToolStripMenuItem" Click="beginBookBackupsToolStripMenuItem_Click" FormatText="Begin _Book and PDF Backups: {0}" /> <MenuItem Click="beginBookBackupsToolStripMenuItem_Click" Header="{Binding BookBackupsToolStripText}" />
<controls:FormattableMenuItem Name="beginPdfBackupsToolStripMenuItem" Click="beginPdfBackupsToolStripMenuItem_Click" FormatText="Begin _PDF Only Backups: {0}" /> <MenuItem Click="beginPdfBackupsToolStripMenuItem_Click" Header="{Binding PdfBackupsToolStripText}" />
<MenuItem Click="convertAllM4bToMp3ToolStripMenuItem_Click" Header="Convert all _M4b to Mp3 [Long-running]..." /> <MenuItem Click="convertAllM4bToMp3ToolStripMenuItem_Click" Header="Convert all _M4b to Mp3 [Long-running]..." />
<controls:FormattableMenuItem Name="liberateVisibleToolStripMenuItem_LiberateMenu" Click="liberateVisible" FormatText="Liberate _Visible Books: {0}" /> <MenuItem Click="liberateVisible" Header="{Binding LiberateVisibleToolStripText}" IsEnabled="{Binding AnyVisibleNotLiberated}" />
</MenuItem> </MenuItem>
<!-- Export Menu -->
<MenuItem Header="E_xport"> <MenuItem Header="E_xport">
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<MenuItem.Styles> <MenuItem.Styles>
@ -65,8 +77,11 @@
<Setter Property="Height" Value="NaN"/> <Setter Property="Height" Value="NaN"/>
</Style> </Style>
</MenuItem.Styles> </MenuItem.Styles>
<MenuItem Name="exportLibraryToolStripMenuItem" Click="exportLibraryToolStripMenuItem_Click" Header="E_xport Library" /> <MenuItem IsEnabled="{Binding HasBookResults}" Click="exportLibraryToolStripMenuItem_Click" Header="E_xport Library" />
</MenuItem> </MenuItem>
<!-- Quick Filters Menu -->
<MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters"> <MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters">
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<MenuItem.Styles> <MenuItem.Styles>
@ -74,26 +89,32 @@
<Setter Property="Height" Value="NaN"/> <Setter Property="Height" Value="NaN"/>
</Style> </Style>
</MenuItem.Styles> </MenuItem.Styles>
<MenuItem Name="firstFilterIsDefaultToolStripMenuItem" Click="firstFilterIsDefaultToolStripMenuItem_Click" Header="Start Libation with 1st filter _Default"> <MenuItem Click="firstFilterIsDefaultToolStripMenuItem_Click" Header="Start Libation with 1st filter _Default">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox Name="firstFilterIsDefaultToolStripMenuItem_Checkbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox> <CheckBox BorderThickness="0" IsChecked="{Binding FirstFilterIsDefault, Mode=TwoWay}" IsHitTestVisible="False" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Name="editQuickFiltersToolStripMenuItem" Click="editQuickFiltersToolStripMenuItem_Click" Header="_Edit quick filters..." /> <MenuItem Click="editQuickFiltersToolStripMenuItem_Click" Header="_Edit quick filters..." />
<Separator /> <Separator />
</MenuItem> </MenuItem>
<controls:FormattableMenuItem Name="visibleBooksToolStripMenuItem" FormatText="_Visible Books: {0}" >
<!-- Visible Books Menu -->
<MenuItem Header="{Binding VisibleCountMenuItemText}" >
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<controls:FormattableMenuItem.Styles> <MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter"> <Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/> <Setter Property="Height" Value="NaN"/>
</Style> </Style>
</controls:FormattableMenuItem.Styles> </MenuItem.Styles>
<controls:FormattableMenuItem Name="liberateVisibleToolStripMenuItem_VisibleBooksMenu" Click="liberateVisible" FormatText="_Liberate: {0}" /> <MenuItem Click="liberateVisible" Header="{Binding LiberateVisibleToolStripText_2}" IsEnabled="{Binding AnyVisibleNotLiberated}" />
<MenuItem Click="replaceTagsToolStripMenuItem_Click" Header="Replace _Tags..." /> <MenuItem Click="replaceTagsToolStripMenuItem_Click" Header="Replace _Tags..." />
<MenuItem Name="setDownloadedToolStripMenuItem" Click="setDownloadedToolStripMenuItem_Click" Header="Set '_Downloaded' status..." /> <MenuItem Click="setDownloadedToolStripMenuItem_Click" Header="Set '_Downloaded' status..." />
<MenuItem Name="removeToolStripMenuItem" Click="removeToolStripMenuItem_Click" Header="_Remove from library..." /> <MenuItem Click="removeToolStripMenuItem_Click" Header="_Remove from library..." />
</controls:FormattableMenuItem> </MenuItem>
<!-- Settings Menu -->
<MenuItem Header="_Settings"> <MenuItem Header="_Settings">
<!-- Remove height style property for menu item --> <!-- Remove height style property for menu item -->
<MenuItem.Styles> <MenuItem.Styles>
@ -107,9 +128,9 @@
<MenuItem Click="aboutToolStripMenuItem_Click" Header="A_bout..." /> <MenuItem Click="aboutToolStripMenuItem_Click" Header="A_bout..." />
</MenuItem> </MenuItem>
</Menu> </Menu>
<StackPanel Name="scanningToolStripMenuItem" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel IsVisible="{Binding ActivelyScanning}" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Image Width="16" Height="16" Source="/AvaloniaUI/Assets/import_16x16.png" /> <Image Width="16" Height="16" Source="/AvaloniaUI/Assets/import_16x16.png" />
<TextBlock Name="scanningToolStripMenuItem_Text" Margin="5,0,5,0" VerticalAlignment="Center" Text="Scanning..."/> <TextBlock Margin="5,0,5,0" VerticalAlignment="Center" Text="{Binding ScanningText}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
@ -123,29 +144,29 @@
</Grid.Styles> </Grid.Styles>
<StackPanel Grid.Column="0" Orientation="Horizontal"> <StackPanel Grid.Column="0" Orientation="Horizontal">
<Button Name="filterHelpBtn" Click="filterHelpBtn_Click" Height="30" Width="30" Content="?"/> <Button Click="filterHelpBtn_Click" Height="30" Width="30" Content="?"/>
<Button Name="addQuickFilterBtn" Click="addQuickFilterBtn_Click" Height="30" Width="150" Margin="10,0,10,0" Content="Add To Quick Filters"/> <Button Click="addQuickFilterBtn_Click" Height="30" Width="150" Margin="10,0,10,0" Content="Add To Quick Filters"/>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <StackPanel Grid.Column="1" Orientation="Horizontal">
<Button IsVisible="{Binding RemoveButtonsVisible}" Click="removeBooksBtn_Click" Height="30" Width="220" Content="{Binding RemoveBooksButtonText}"/> <Button IsVisible="{Binding RemoveButtonsVisible}" Click="removeBooksBtn_Click" Height="30" Width="220" Content="{Binding RemoveBooksButtonText}"/>
<Button IsVisible="{Binding RemoveButtonsVisible}" Click="doneRemovingBtn_Click" Width="160" Margin="10,0,0,0" Content="Done Removing Books"/> <Button IsVisible="{Binding RemoveButtonsVisible}" Click="doneRemovingBtn_Click" Height="30" Width="160" Margin="10,0,0,0" Content="Done Removing Books"/>
</StackPanel> </StackPanel>
<TextBox Grid.Column="1" Name="filterSearchTb" KeyDown="filterSearchTb_KeyPress" /> <TextBox Grid.Column="1" IsVisible="{Binding !RemoveButtonsVisible}" Text="{Binding FilterString, Mode=TwoWay}" KeyDown="filterSearchTb_KeyPress" />
<StackPanel Grid.Column="2" Height="30" Orientation="Horizontal"> <StackPanel Grid.Column="2" Height="30" Orientation="Horizontal">
<Button Name="filterBtn" Click="filterBtn_Click" Height="30" Width="80" Margin="10,0,10,0" Content="Filter"/> <Button Click="filterBtn_Click" Height="30" Width="80" Margin="10,0,10,0" Content="Filter"/>
<Button Name="toggleQueueHideBtn" Click="ToggleQueueHideBtn_Click" Height="30" Width="30" Content="❱❱❱"/> <Button Click="ToggleQueueHideBtn_Click" Height="30" Width="30" Content="{Binding QueueHideButtonText}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
<Border Grid.Row="2" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}"> <Border Grid.Row="2" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}">
<SplitView Name="splitContainer1" IsPaneOpen="True" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right"> <SplitView IsPaneOpen="{Binding QueueOpen}" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right">
<!-- Process Queue --> <!-- Process Queue -->
<SplitView.Pane> <SplitView.Pane>
<views:ProcessQueueControl2 Name="processBookQueue1"/> <views:ProcessQueueControl2 DataContext="{Binding ProcessQueueViewModel}"/>
</SplitView.Pane> </SplitView.Pane>
<!-- Product Display Grid --> <!-- Product Display Grid -->
@ -160,11 +181,8 @@
<!-- Bottom Status Strip --> <!-- Bottom Status Strip -->
<Grid Grid.Row="3" Margin="0,10,0,0" VerticalAlignment="Bottom" ColumnDefinitions="*,Auto"> <Grid Grid.Row="3" Margin="0,10,0,0" VerticalAlignment="Bottom" ColumnDefinitions="*,Auto">
<controls:FormattableTextBlock FontSize="14" Name="visibleCountLbl" Grid.Column="0" FormatText="Visible {0}" VerticalAlignment="Center" /> <TextBlock FontSize="14" Grid.Column="0" Text="{Binding VisibleCountText}" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> <TextBlock FontSize="14" Grid.Column="1" Text="{Binding StatusCountText}" VerticalAlignment="Center" HorizontalAlignment="Right" />
<TextBlock FontSize="14" Name="backupsCountsLbl" Text="[Calculating backed up book quantities]" VerticalAlignment="Center" />
<controls:FormattableTextBlock FontSize="14" Name="pdfsCountsLbl" FormatText=" | PDFs: NOT d/l'ed: {0} Downloaded: {1}" VerticalAlignment="Center" />
</StackPanel>
</Grid> </Grid>
</Grid> </Grid>
</Border> </Border>

View File

@ -62,62 +62,8 @@ namespace LibationWinForms.AvaloniaUI.Views
private void FindAllControls() private void FindAllControls()
{ {
{
autoScanLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(autoScanLibraryToolStripMenuItem));
autoScanLibraryToolStripMenuItemCheckbox = this.FindControl<CheckBox>(nameof(autoScanLibraryToolStripMenuItemCheckbox));
noAccountsYetAddAccountToolStripMenuItem = this.FindControl<MenuItem>(nameof(noAccountsYetAddAccountToolStripMenuItem));
scanLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(scanLibraryToolStripMenuItem));
scanLibraryOfAllAccountsToolStripMenuItem = this.FindControl<MenuItem>(nameof(scanLibraryOfAllAccountsToolStripMenuItem));
scanLibraryOfSomeAccountsToolStripMenuItem = this.FindControl<MenuItem>(nameof(scanLibraryOfSomeAccountsToolStripMenuItem));
removeLibraryBooksToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeLibraryBooksToolStripMenuItem));
{
removeAllAccountsToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeAllAccountsToolStripMenuItem));
removeSomeAccountsToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeSomeAccountsToolStripMenuItem));
}
}
{
beginBookBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginBookBackupsToolStripMenuItem));
beginPdfBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginPdfBackupsToolStripMenuItem));
liberateVisibleToolStripMenuItem_LiberateMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_LiberateMenu));
}
{
exportLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportLibraryToolStripMenuItem));
}
quickFiltersToolStripMenuItem = this.FindControl<MenuItem>(nameof(quickFiltersToolStripMenuItem)); quickFiltersToolStripMenuItem = this.FindControl<MenuItem>(nameof(quickFiltersToolStripMenuItem));
{
firstFilterIsDefaultToolStripMenuItem = this.FindControl<MenuItem>(nameof(firstFilterIsDefaultToolStripMenuItem));
firstFilterIsDefaultToolStripMenuItem_Checkbox = this.FindControl<CheckBox>(nameof(firstFilterIsDefaultToolStripMenuItem_Checkbox));
editQuickFiltersToolStripMenuItem = this.FindControl<MenuItem>(nameof(editQuickFiltersToolStripMenuItem));
}
visibleBooksToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(visibleBooksToolStripMenuItem));
{
liberateVisibleToolStripMenuItem_VisibleBooksMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_VisibleBooksMenu));
setDownloadedToolStripMenuItem = this.FindControl<MenuItem>(nameof(setDownloadedToolStripMenuItem));
removeToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeToolStripMenuItem));
}
scanningToolStripMenuItem = this.FindControl<StackPanel>(nameof(scanningToolStripMenuItem));
scanningToolStripMenuItem_Text = this.FindControl<TextBlock>(nameof(scanningToolStripMenuItem_Text));
filterHelpBtn = this.FindControl<Button>(nameof(filterHelpBtn));
addQuickFilterBtn = this.FindControl<Button>(nameof(addQuickFilterBtn));
filterSearchTb = this.FindControl<TextBox>(nameof(filterSearchTb));
filterBtn = this.FindControl<Button>(nameof(filterBtn));
toggleQueueHideBtn = this.FindControl<Button>(nameof(toggleQueueHideBtn));
splitContainer1 = this.FindControl<SplitView>(nameof(splitContainer1));
productsDisplay = this.FindControl<ProductsDisplay2>(nameof(productsDisplay)); productsDisplay = this.FindControl<ProductsDisplay2>(nameof(productsDisplay));
processBookQueue1 = this.FindControl<ProcessQueueControl2>(nameof(processBookQueue1));
visibleCountLbl = this.FindControl<FormattableTextBlock>(nameof(visibleCountLbl));
backupsCountsLbl = this.FindControl<TextBlock>(nameof(backupsCountsLbl));
pdfsCountsLbl = this.FindControl<FormattableTextBlock>(nameof(pdfsCountsLbl));
} }
protected override void OnDataContextChanged(EventArgs e) protected override void OnDataContextChanged(EventArgs e)

View File

@ -13,19 +13,17 @@ namespace LibationWinForms.AvaloniaUI.Views
public partial class ProcessQueueControl2 : UserControl public partial class ProcessQueueControl2 : UserControl
{ {
private TrackedQueue2<ProcessBook2> Queue => _viewModel.Items; private TrackedQueue2<ProcessBook2> Queue => _viewModel.Items;
private readonly ProcessQueueViewModel _viewModel; private ProcessQueueViewModel _viewModel => DataContext as ProcessQueueViewModel;
private readonly ProcessQueue.LogMe Logger;
public ProcessQueueControl2() public ProcessQueueControl2()
{ {
InitializeComponent(); InitializeComponent();
DataContext = _viewModel = new ProcessQueueViewModel();
Logger = ProcessQueue.LogMe.RegisterForm(_viewModel);
ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked; ProcessBookControl2.PositionButtonClicked += ProcessBookControl2_ButtonClicked;
ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked; ProcessBookControl2.CancelButtonClicked += ProcessBookControl2_CancelButtonClicked;
#region Design Mode Testing #region Design Mode Testing
/*
if (Design.IsDesignMode) if (Design.IsDesignMode)
{ {
using var context = DbContexts.GetContext(); using var context = DbContexts.GetContext();
@ -77,6 +75,7 @@ namespace LibationWinForms.AvaloniaUI.Views
_viewModel.Items.Enqueue(testList); _viewModel.Items.Enqueue(testList);
return; return;
} }
*/
#endregion #endregion
} }
@ -85,74 +84,6 @@ namespace LibationWinForms.AvaloniaUI.Views
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
#region Add Books to Queue
private bool isBookInQueue(LibraryBook libraryBook)
=> Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId);
public void AddDownloadPdf(LibraryBook libraryBook)
=> AddDownloadPdf(new List<LibraryBook>() { libraryBook });
public void AddDownloadDecrypt(LibraryBook libraryBook)
=> AddDownloadDecrypt(new List<LibraryBook>() { libraryBook });
public void AddConvertMp3(LibraryBook libraryBook)
=> AddConvertMp3(new List<LibraryBook>() { libraryBook });
public void AddDownloadPdf(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddDownloadPdf();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
_viewModel.AddToQueue(procs);
}
public void AddDownloadDecrypt(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddDownloadDecryptBook();
pbook.AddDownloadPdf();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
_viewModel.AddToQueue(procs);
}
public void AddConvertMp3(IEnumerable<LibraryBook> entries)
{
List<ProcessBook2> procs = new();
foreach (var entry in entries)
{
if (isBookInQueue(entry))
continue;
ProcessBook2 pbook = new(entry, Logger);
pbook.AddConvertToMp3();
procs.Add(pbook);
}
Serilog.Log.Logger.Information("Queueing {count} books", procs.Count);
_viewModel.AddToQueue(procs);
}
#endregion
#region Control event handlers #region Control event handlers
private async void ProcessBookControl2_CancelButtonClicked(ProcessBook2 item) private async void ProcessBookControl2_CancelButtonClicked(ProcessBook2 item)