Add Last Download column to grid (rmcrackan/Libation#498)
This commit is contained in:
parent
bd7e45ca3c
commit
d94759d868
@ -43,6 +43,7 @@ namespace LibationAvalonia.ViewModels
|
||||
private string _narrators;
|
||||
private string _category;
|
||||
private string _misc;
|
||||
private LastDownloadStatus _lastDownload;
|
||||
private string _description;
|
||||
private Rating _productrating;
|
||||
protected Rating _myRating;
|
||||
@ -55,6 +56,7 @@ namespace LibationAvalonia.ViewModels
|
||||
public string Authors { get => _authors; protected set => this.RaiseAndSetIfChanged(ref _authors, value); }
|
||||
public string Narrators { get => _narrators; protected set => this.RaiseAndSetIfChanged(ref _narrators, value); }
|
||||
public string Category { get => _category; protected set => this.RaiseAndSetIfChanged(ref _category, value); }
|
||||
public LastDownloadStatus LastDownload { get => _lastDownload; protected set => this.RaiseAndSetIfChanged(ref _lastDownload, value); }
|
||||
public string Misc { get => _misc; protected set => this.RaiseAndSetIfChanged(ref _misc, value); }
|
||||
public string Description { get => _description; protected set => this.RaiseAndSetIfChanged(ref _description, value); }
|
||||
public Rating ProductRating { get => _productrating; protected set => this.RaiseAndSetIfChanged(ref _productrating, value); }
|
||||
@ -122,6 +124,7 @@ namespace LibationAvalonia.ViewModels
|
||||
{ typeof(bool), new ObjectComparer<bool>() },
|
||||
{ typeof(DateTime), new ObjectComparer<DateTime>() },
|
||||
{ typeof(LiberateButtonStatus), new ObjectComparer<LiberateButtonStatus>() },
|
||||
{ typeof(LastDownloadStatus), new ObjectComparer<LastDownloadStatus>() },
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
@ -87,6 +87,7 @@ namespace LibationAvalonia.ViewModels
|
||||
Narrators = Book.NarratorNames();
|
||||
Category = string.Join(" > ", Book.CategoriesNames());
|
||||
Misc = GetMiscDisplay(libraryBook);
|
||||
LastDownload = new(Book.UserDefinedItem);
|
||||
LongDescription = GetDescriptionDisplay(Book);
|
||||
Description = TrimTextToWord(LongDescription, 62);
|
||||
SeriesIndex = Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
|
||||
@ -127,6 +128,10 @@ namespace LibationAvalonia.ViewModels
|
||||
_pdfStatus = udi.PdfStatus;
|
||||
this.RaisePropertyChanged(nameof(Liberate));
|
||||
break;
|
||||
case nameof(udi.LastDownloaded):
|
||||
LastDownload = new(udi);
|
||||
this.RaisePropertyChanged(nameof(LastDownload));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,6 +154,7 @@ namespace LibationAvalonia.ViewModels
|
||||
{ nameof(Description), () => Description },
|
||||
{ nameof(Category), () => Category },
|
||||
{ nameof(Misc), () => Misc },
|
||||
{ nameof(LastDownload), () => LastDownload },
|
||||
{ nameof(BookTags), () => BookTags?.Tags ?? string.Empty },
|
||||
{ nameof(Liberate), () => Liberate },
|
||||
{ nameof(DateAdded), () => DateAdded },
|
||||
|
||||
@ -96,6 +96,7 @@ namespace LibationAvalonia.ViewModels
|
||||
Narrators = Book.NarratorNames();
|
||||
Category = string.Join(" > ", Book.CategoriesNames());
|
||||
Misc = GetMiscDisplay(LibraryBook);
|
||||
LastDownload = new();
|
||||
LongDescription = GetDescriptionDisplay(Book);
|
||||
Description = TrimTextToWord(LongDescription, 62);
|
||||
|
||||
@ -124,6 +125,7 @@ namespace LibationAvalonia.ViewModels
|
||||
{ nameof(Description), () => Description },
|
||||
{ nameof(Category), () => Category },
|
||||
{ nameof(Misc), () => Misc },
|
||||
{ nameof(LastDownload), () => LastDownload },
|
||||
{ nameof(BookTags), () => BookTags?.Tags ?? string.Empty },
|
||||
{ nameof(Liberate), () => Liberate },
|
||||
{ nameof(DateAdded), () => DateAdded },
|
||||
|
||||
@ -183,6 +183,16 @@
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Width="102" Header="Last
Download" CanUserSort="True" SortMemberPath="LastDownload" ClipboardContentBinding="{Binding LastDownload}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<Panel Background="{Binding BackgroundBrush}" ToolTip.Tip="{Binding LastDownload.ToolTipText}" DoubleTapped="Version_DoubleClick">
|
||||
<TextBlock Text="{Binding LastDownload}" TextWrapping="WrapWithOverflow" FontSize="10" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt CanUserSort="True" Width="100" Header="Tags" SortMemberPath="BookTags" ClipboardContentBinding="{Binding BookTags.Tags}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
|
||||
@ -306,6 +306,12 @@ namespace LibationAvalonia.Views
|
||||
imageDisplayDialog.Close();
|
||||
}
|
||||
|
||||
public void Version_DoubleClick(object sender, Avalonia.Input.TappedEventArgs args)
|
||||
{
|
||||
if (sender is Control panel && panel.DataContext is LibraryBookEntry lbe && lbe.LastDownload.IsValid)
|
||||
lbe.LastDownload.OpenReleaseUrl();
|
||||
}
|
||||
|
||||
public void Cover_Click(object sender, Avalonia.Input.TappedEventArgs args)
|
||||
{
|
||||
if (sender is not Image tblock || tblock.DataContext is not GridEntry gEntry)
|
||||
|
||||
41
Source/LibationUiBase/LastDownloadStatus.cs
Normal file
41
Source/LibationUiBase/LastDownloadStatus.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using DataLayer;
|
||||
using System;
|
||||
|
||||
namespace LibationUiBase
|
||||
{
|
||||
public class LastDownloadStatus : IComparable
|
||||
{
|
||||
public bool IsValid => LastDownloadedVersion is not null && LastDownloaded.HasValue;
|
||||
public Version LastDownloadedVersion { get; }
|
||||
public DateTime? LastDownloaded { get; }
|
||||
public string ToolTipText => IsValid ? $"Double click to open v{LastDownloadedVersion.ToString(3)} release notes" : "";
|
||||
|
||||
public LastDownloadStatus() { }
|
||||
public LastDownloadStatus(UserDefinedItem udi)
|
||||
{
|
||||
LastDownloadedVersion = udi.LastDownloadedVersion;
|
||||
LastDownloaded = udi.LastDownloaded;
|
||||
}
|
||||
|
||||
public void OpenReleaseUrl()
|
||||
{
|
||||
if (IsValid)
|
||||
Dinah.Core.Go.To.Url($"{AppScaffolding.LibationScaffolding.RepositoryUrl}/releases/tag/v{LastDownloadedVersion.ToString(3)}");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
=> IsValid ? $"{dateString()}\n\nLibation v{LastDownloadedVersion.ToString(3)}" : "";
|
||||
|
||||
//Call ToShortDateString to use current culture's date format.
|
||||
private string dateString() => $"{LastDownloaded.Value.ToShortDateString()} {LastDownloaded.Value:HH:mm}";
|
||||
|
||||
public int CompareTo(object obj)
|
||||
{
|
||||
if (obj is not LastDownloadStatus second) return -1;
|
||||
else if (IsValid && !second.IsValid) return -1;
|
||||
else if (!IsValid && second.IsValid) return 1;
|
||||
else if (!IsValid && !second.IsValid) return 0;
|
||||
else return LastDownloaded.Value.CompareTo(second.LastDownloaded.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,6 @@ namespace LibationWinForms.GridView
|
||||
// per standard INotifyPropertyChanged pattern:
|
||||
// https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-property-change-notification
|
||||
public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||
=> this.UIThreadAsync(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
|
||||
=> this.UIThreadSync(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ namespace LibationWinForms.GridView
|
||||
public string Narrators { get; protected set; }
|
||||
public string Category { get; protected set; }
|
||||
public string Misc { get; protected set; }
|
||||
public virtual LastDownloadStatus LastDownload { get; protected set; } = new();
|
||||
public string Description { get; protected set; }
|
||||
public string ProductRating { get; protected set; }
|
||||
protected Rating _myRating;
|
||||
@ -120,6 +121,7 @@ namespace LibationWinForms.GridView
|
||||
{ typeof(bool), new ObjectComparer<bool>() },
|
||||
{ typeof(DateTime), new ObjectComparer<DateTime>() },
|
||||
{ typeof(LiberateButtonStatus), new ObjectComparer<LiberateButtonStatus>() },
|
||||
{ typeof(LastDownloadStatus), new ObjectComparer<LastDownloadStatus>() },
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
using LibationUiBase;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace LibationWinForms.GridView
|
||||
{
|
||||
public class LastDownloadedGridViewColumn : DataGridViewColumn
|
||||
{
|
||||
public LastDownloadedGridViewColumn() : base(new LastDownloadedGridViewCell()) { }
|
||||
public override DataGridViewCell CellTemplate
|
||||
{
|
||||
get => base.CellTemplate;
|
||||
set
|
||||
{
|
||||
if (value is not LastDownloadedGridViewCell)
|
||||
throw new InvalidCastException($"Must be a {nameof(LastDownloadedGridViewCell)}");
|
||||
|
||||
base.CellTemplate = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LastDownloadedGridViewCell : DataGridViewTextBoxCell
|
||||
{
|
||||
private LastDownloadStatus LastDownload => (LastDownloadStatus)Value;
|
||||
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
|
||||
{
|
||||
ToolTipText = ((LastDownloadStatus)value).ToolTipText;
|
||||
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
|
||||
}
|
||||
|
||||
protected override void OnDoubleClick(DataGridViewCellEventArgs e)
|
||||
{
|
||||
LastDownload.OpenReleaseUrl();
|
||||
base.OnDoubleClick(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
using ApplicationServices;
|
||||
using DataLayer;
|
||||
using Dinah.Core;
|
||||
using LibationUiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@ -24,6 +25,8 @@ namespace LibationWinForms.GridView
|
||||
private LiberatedStatus _bookStatus;
|
||||
private LiberatedStatus? _pdfStatus;
|
||||
|
||||
public override LastDownloadStatus LastDownload { get; protected set; }
|
||||
|
||||
public override RemoveStatus Remove
|
||||
{
|
||||
get
|
||||
@ -87,6 +90,7 @@ namespace LibationWinForms.GridView
|
||||
Narrators = Book.NarratorNames();
|
||||
Category = string.Join(" > ", Book.CategoriesNames());
|
||||
Misc = GetMiscDisplay(libraryBook);
|
||||
LastDownload = new(Book.UserDefinedItem);
|
||||
LongDescription = GetDescriptionDisplay(Book);
|
||||
Description = TrimTextToWord(LongDescription, 62);
|
||||
SeriesIndex = Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
|
||||
@ -126,6 +130,10 @@ namespace LibationWinForms.GridView
|
||||
_pdfStatus = udi.PdfStatus;
|
||||
NotifyPropertyChanged(nameof(Liberate));
|
||||
break;
|
||||
case nameof(udi.LastDownloaded):
|
||||
LastDownload = new(udi);
|
||||
NotifyPropertyChanged(nameof(LastDownload));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,6 +161,7 @@ namespace LibationWinForms.GridView
|
||||
{ nameof(Description), () => Description },
|
||||
{ nameof(Category), () => Category },
|
||||
{ nameof(Misc), () => Misc },
|
||||
{ nameof(LastDownload), () => LastDownload },
|
||||
{ nameof(DisplayTags), () => DisplayTags },
|
||||
{ nameof(Liberate), () => Liberate },
|
||||
{ nameof(DateAdded), () => DateAdded },
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
this.purchaseDateGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.myRatingGVColumn = new LibationWinForms.GridView.MyRatingGridViewColumn();
|
||||
this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.lastDownloadedGVColumn = new LastDownloadedGridViewColumn();
|
||||
this.tagAndDetailsGVColumn = new LibationWinForms.GridView.EditTagsDataGridViewImageButtonColumn();
|
||||
this.showHideColumnsContextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.syncBindingSource = new LibationWinForms.GridView.SyncBindingSource(this.components);
|
||||
@ -75,7 +76,8 @@
|
||||
this.purchaseDateGVColumn,
|
||||
this.myRatingGVColumn,
|
||||
this.miscGVColumn,
|
||||
this.tagAndDetailsGVColumn});
|
||||
this.lastDownloadedGVColumn,
|
||||
this.tagAndDetailsGVColumn});
|
||||
this.gridEntryDataGridView.ContextMenuStrip = this.showHideColumnsContextMenuStrip;
|
||||
this.gridEntryDataGridView.DataSource = this.syncBindingSource;
|
||||
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||
@ -216,6 +218,15 @@
|
||||
this.miscGVColumn.ReadOnly = true;
|
||||
this.miscGVColumn.Width = 135;
|
||||
//
|
||||
// lastDownloadedGVColumn
|
||||
//
|
||||
this.lastDownloadedGVColumn.DataPropertyName = "LastDownload";
|
||||
this.lastDownloadedGVColumn.HeaderText = "Last Download";
|
||||
this.lastDownloadedGVColumn.Name = "lastDownloadedGVColumn";
|
||||
this.lastDownloadedGVColumn.ReadOnly = true;
|
||||
this.lastDownloadedGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
|
||||
this.lastDownloadedGVColumn.Width = 108;
|
||||
//
|
||||
// tagAndDetailsGVColumn
|
||||
//
|
||||
this.tagAndDetailsGVColumn.DataPropertyName = "DisplayTags";
|
||||
@ -268,6 +279,7 @@
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn purchaseDateGVColumn;
|
||||
private MyRatingGridViewColumn myRatingGVColumn;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn;
|
||||
private LastDownloadedGridViewColumn lastDownloadedGVColumn;
|
||||
private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,6 +122,7 @@ namespace LibationWinForms.GridView
|
||||
{ nameof(Description), () => Description },
|
||||
{ nameof(Category), () => Category },
|
||||
{ nameof(Misc), () => Misc },
|
||||
{ nameof(LastDownload), () => LastDownload },
|
||||
{ nameof(DisplayTags), () => string.Empty },
|
||||
{ nameof(Liberate), () => Liberate },
|
||||
{ nameof(DateAdded), () => DateAdded },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user