Show AbsentFromLastScan book status in grid

This commit is contained in:
MBucari 2023-03-07 19:36:15 -07:00
parent f6dcc0db1d
commit 3ebd4ce243
17 changed files with 61 additions and 23 deletions

View File

@ -467,6 +467,7 @@ namespace ApplicationServices
var results = libraryBooks
.AsParallel()
.Where(lb => !lb.AbsentFromLastScan)
.Select(lb => Liberated_Status(lb.Book))
.ToList();
var booksFullyBackedUp = results.Count(r => r == LiberatedStatus.Liberated);

View File

@ -107,8 +107,9 @@ namespace DataLayer
=> bookList
.Where(
lb =>
lb.Book.UserDefinedItem.BookStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload
|| lb.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload
!lb.AbsentFromLastScan &&
(lb.Book.UserDefinedItem.BookStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload
|| lb.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload)
);
}
}

View File

@ -8,6 +8,8 @@
<SolidColorBrush x:Key="ProcessQueueBookCancelledBrush" Color="Khaki" />
<SolidColorBrush x:Key="ProcessQueueBookDefaultBrush" Color="{StaticResource SystemAltHighColor}" />
<SolidColorBrush x:Key="ProcessQueueBookBorderBrush" Color="Gray" />
<SolidColorBrush x:Key="DisabledGrayBrush" Color="#60D3D3D3" />
</Styles.Resources>
<Style Selector="TextBox[IsReadOnly=true]">
<Setter Property="Background" Value="LightGray" />

View File

@ -78,7 +78,6 @@ namespace LibationAvalonia.ViewModels
public abstract bool? Remove { get; set; }
public abstract LiberateButtonStatus Liberate { get; }
public abstract BookTags BookTags { get; }
public abstract bool IsSeries { get; }
public abstract bool IsEpisode { get; }
public abstract bool IsBook { get; }
public IBrush BackgroundBrush => IsEpisode ? App.SeriesEntryGridBackgroundBrush : Brushes.Transparent;

View File

@ -8,9 +8,10 @@ namespace LibationAvalonia.ViewModels
{
public class LiberateButtonStatus : ViewModelBase, IComparable
{
public LiberateButtonStatus(bool isSeries)
public LiberateButtonStatus(bool isSeries, bool isAbsent)
{
IsSeries = isSeries;
IsAbsent = isAbsent;
}
public LiberatedStatus BookStatus { get; set; }
public LiberatedStatus? PdfStatus { get; set; }
@ -26,7 +27,10 @@ namespace LibationAvalonia.ViewModels
this.RaisePropertyChanged(nameof(ToolTip));
}
}
private bool IsSeries { get; }
private bool IsAbsent { get; }
public bool IsSeries { get; }
public bool IsUnavailable => !IsSeries & IsAbsent & (BookStatus is not LiberatedStatus.Liberated || PdfStatus is not null and not LiberatedStatus.Liberated);
public Bitmap Image => GetLiberateIcon();
public string ToolTip => GetTooltip();
@ -40,6 +44,8 @@ namespace LibationAvalonia.ViewModels
if (IsSeries && !second.IsSeries) return -1;
else if (!IsSeries && second.IsSeries) return 1;
else if (IsSeries && second.IsSeries) return 0;
else if (IsUnavailable && !second.IsUnavailable) return 1;
else if (!IsUnavailable && second.IsUnavailable) return -1;
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);
@ -72,11 +78,15 @@ namespace LibationAvalonia.ViewModels
return GetFromResources($"liberate_{image_lib}{image_pdf}");
}
private string GetTooltip()
{
if (IsSeries)
return Expanded ? "Click to Collpase" : "Click to Expand";
if (IsUnavailable)
return "This book cannot be downloaded\nbecause it wasn't found during\nthe most recent library scan";
if (BookStatus == LiberatedStatus.Error)
return "Book downloaded ERROR";

View File

@ -44,13 +44,12 @@ namespace LibationAvalonia.ViewModels
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
lastStatusUpdate = DateTime.Now;
}
return new LiberateButtonStatus(IsSeries) { BookStatus = _bookStatus, PdfStatus = _pdfStatus };
return new LiberateButtonStatus(isSeries: false, LibraryBook.AbsentFromLastScan) { BookStatus = _bookStatus, PdfStatus = _pdfStatus };
}
}
public override BookTags BookTags => new() { Tags = string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated) };
public override bool IsSeries => false;
public override bool IsEpisode => Parent is not null;
public override bool IsBook => Parent is null;
@ -93,6 +92,7 @@ namespace LibationAvalonia.ViewModels
SeriesIndex = Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
this.RaisePropertyChanged(nameof(MyRating));
this.RaisePropertyChanged(nameof(Liberate));
UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged;
}

View File

@ -46,7 +46,6 @@ namespace LibationAvalonia.ViewModels
public override LiberateButtonStatus Liberate { get; }
public override BookTags BookTags { get; } = new();
public override bool IsSeries => true;
public override bool IsEpisode => false;
public override bool IsBook => false;
@ -54,7 +53,7 @@ namespace LibationAvalonia.ViewModels
public SeriesEntry(LibraryBook parent, IEnumerable<LibraryBook> children)
{
Liberate = new LiberateButtonStatus(IsSeries);
Liberate = new LiberateButtonStatus(isSeries: true, isAbsent: false);
SeriesIndex = -1;
Children = children

View File

@ -157,6 +157,7 @@ namespace LibationAvalonia.Views
=> _viewModel.VisibleNotLiberated
= _viewModel.ProductsDisplay
.GetVisibleBookEntries()
.Where(lb => !lb.AbsentFromLastScan)
.Count(lb => lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.NotLiberated);
}
}

View File

@ -61,9 +61,13 @@
<controls:DataGridTemplateColumnExt CanUserSort="True" Width="75" Header="Liberate" SortMemberPath="Liberate" ClipboardContentBinding="{Binding Liberate.ToolTip}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Opacity="{Binding Opacity}" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="LiberateButton_Click" ToolTip.Tip="{Binding Liberate.ToolTip}">
<Image Source="{Binding Liberate.Image}" Stretch="None" />
</Button>
<Panel ToolTip.Tip="{Binding Liberate.ToolTip}">
<Button Opacity="{Binding Opacity}" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="LiberateButton_Click" IsVisible="{Binding !Liberate.IsUnavailable}">
<Image Source="{Binding Liberate.Image}" Stretch="None" />
</Button>
<Image Source="{Binding Liberate.Image}" Stretch="None" IsVisible="{Binding Liberate.IsUnavailable}"/>
<Panel Background="{StaticResource DisabledGrayBrush}" IsVisible="{Binding Liberate.IsUnavailable}" />
</Panel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumnExt>

View File

@ -34,7 +34,7 @@ namespace LibationAvalonia.Views
List<LibraryBook> sampleEntries = new()
{
//context.GetLibraryBook_Flat_NoTracking("B00DCD0OXU"),
context.GetLibraryBook_Flat_NoTracking("B017V4IM1G"),
context.GetLibraryBook_Flat_NoTracking("B002V8H7G4"),
context.GetLibraryBook_Flat_NoTracking("B017V4IWVG"),
context.GetLibraryBook_Flat_NoTracking("B017V4JA2Q"),
context.GetLibraryBook_Flat_NoTracking("B017V4NUPO"),
@ -84,7 +84,7 @@ namespace LibationAvalonia.Views
{
var entry = args.GridEntry;
if (entry.IsSeries)
if (entry.Liberate.IsSeries)
return;
var setDownloadMenuItem = new MenuItem()
@ -135,7 +135,7 @@ namespace LibationAvalonia.Views
var convertToMp3MenuItem = new MenuItem
{
Header = "_Convert to Mp3",
IsEnabled = entry.Book.UserDefinedItem.BookStatus != LiberatedStatus.NotLiberated
IsEnabled = entry.Book.UserDefinedItem.BookStatus is LiberatedStatus.Liberated
};
convertToMp3MenuItem.Click += (_, _) => ConvertToMp3Clicked?.Invoke(this, entry.LibraryBook);

View File

@ -27,7 +27,7 @@ namespace LibationWinForms
=> await Task.Run(setLiberatedVisibleMenuItem);
void setLiberatedVisibleMenuItem()
{
var notLiberated = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
var notLiberated = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == LiberatedStatus.NotLiberated && !lb.AbsentFromLastScan);
this.UIThreadSync(() =>
{
if (notLiberated > 0)

View File

@ -8,7 +8,15 @@ namespace LibationWinForms.GridView
public LiberatedStatus BookStatus { get; set; }
public LiberatedStatus? PdfStatus { get; set; }
public bool Expanded { get; set; }
public bool IsSeries { get; init; }
public bool IsSeries { get; }
private bool IsAbsent { get; }
public bool IsUnavailable => !IsSeries & IsAbsent & (BookStatus is not LiberatedStatus.Liberated || PdfStatus is not null and not LiberatedStatus.Liberated);
public LiberateButtonStatus(bool isSeries, bool isAbsent)
{
IsSeries = isSeries;
IsAbsent = isAbsent;
}
/// <summary>
/// Defines the Liberate column's sorting behavior
@ -20,6 +28,8 @@ namespace LibationWinForms.GridView
if (IsSeries && !second.IsSeries) return -1;
else if (!IsSeries && second.IsSeries) return 1;
else if (IsSeries && second.IsSeries) return 0;
else if (IsUnavailable && !second.IsUnavailable) return 1;
else if (!IsUnavailable && second.IsUnavailable) return -1;
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);

View File

@ -17,11 +17,14 @@ namespace LibationWinForms.GridView
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
private static readonly Color SERIES_BG_COLOR = Color.FromArgb(230, 255, 230);
private static readonly Brush DISABLED_GRAY = new SolidBrush(Color.FromArgb(0x60, Color.LightGray));
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 (value is LiberateButtonStatus status)
{
if (status.BookStatus is LiberatedStatus.Error)
if (status.BookStatus is LiberatedStatus.Error || status.IsUnavailable)
//Don't paint the button graphic
paintParts ^= DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.SelectionBackground;
if (rowIndex >= 0 && DataGridView.GetBoundItem<GridEntry>(rowIndex) is LibraryBookEntry lbEntry && lbEntry.Parent is not null)
@ -41,7 +44,14 @@ namespace LibationWinForms.GridView
DrawButtonImage(graphics, buttonImage, cellBounds);
ToolTipText = mouseoverText;
if (status.IsUnavailable)
{
//Create the "disabled" look by painting a transparent gray box over the buttom image.
graphics.FillRectangle(DISABLED_GRAY, cellBounds);
ToolTipText = "This book cannot be downloaded\r\nbecause it wasn't found during\r\nthe most recent library scan";
}
else
ToolTipText = mouseoverText;
}
}
}

View File

@ -52,7 +52,7 @@ namespace LibationWinForms.GridView
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
lastStatusUpdate = DateTime.Now;
}
return new LiberateButtonStatus { BookStatus = _bookStatus, PdfStatus = _pdfStatus, IsSeries = false };
return new LiberateButtonStatus(isSeries: false, LibraryBook.AbsentFromLastScan) { BookStatus = _bookStatus, PdfStatus = _pdfStatus };
}
}
public override string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);

View File

@ -200,7 +200,8 @@ namespace LibationWinForms.GridView
private void productsGrid_LiberateClicked(LibraryBookEntry liveGridEntry)
{
if (liveGridEntry.LibraryBook.Book.UserDefinedItem.BookStatus is not LiberatedStatus.Error)
if (liveGridEntry.LibraryBook.Book.UserDefinedItem.BookStatus is not LiberatedStatus.Error
&& !liveGridEntry.Liberate.IsUnavailable)
LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
}

View File

@ -180,7 +180,7 @@ namespace LibationWinForms.GridView
var convertToMp3MenuItem = new ToolStripMenuItem
{
Text = "&Convert to Mp3",
Enabled = entry.Book.UserDefinedItem.BookStatus != LiberatedStatus.NotLiberated
Enabled = entry.Book.UserDefinedItem.BookStatus is LiberatedStatus.Liberated
};
convertToMp3MenuItem.Click += (_, e) => ConvertToMp3Clicked?.Invoke(entry as LibraryBookEntry);

View File

@ -62,7 +62,7 @@ namespace LibationWinForms.GridView
private SeriesEntry(LibraryBook parent)
{
Liberate = new LiberateButtonStatus { IsSeries = true };
Liberate = new LiberateButtonStatus(isSeries: true, isAbsent: false);
SeriesIndex = -1;
LibraryBook = parent;
LoadCover();