Add debug constants and don't check updates in debug.
Refactored cell formatting Made GridEntry thread safe Moved PictureStorage set defaults into constructor.
This commit is contained in:
parent
ab82e7c99c
commit
2ef746a94c
@ -13,7 +13,11 @@
|
|||||||
<!-- <PublishSingleFile>true</PublishSingleFile> -->
|
<!-- <PublishSingleFile>true</PublishSingleFile> -->
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
|
||||||
<Version>5.4.9.79</Version>
|
<Version>5.4.9.120</Version>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@ -59,7 +59,10 @@ namespace LibationLauncher
|
|||||||
ensureSerilogConfig(config);
|
ensureSerilogConfig(config);
|
||||||
configureLogging(config);
|
configureLogging(config);
|
||||||
logStartupState(config);
|
logStartupState(config);
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
checkForUpdate(config);
|
checkForUpdate(config);
|
||||||
|
#endif
|
||||||
|
|
||||||
Application.Run(new Form1());
|
Application.Run(new Form1());
|
||||||
}
|
}
|
||||||
@ -145,7 +148,7 @@ namespace LibationLauncher
|
|||||||
CancelInstallation();
|
CancelInstallation();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region migrate to v5.0.0 re-register device if device info not in settings
|
#region migrate to v5.0.0 re-register device if device info not in settings
|
||||||
private static void migrate_to_v5_0_0(Configuration config)
|
private static void migrate_to_v5_0_0(Configuration config)
|
||||||
{
|
{
|
||||||
if (!config.Exists(nameof(config.AllowLibationFixup)))
|
if (!config.Exists(nameof(config.AllowLibationFixup)))
|
||||||
@ -187,9 +190,9 @@ namespace LibationLauncher
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region migrate to v5.2.0
|
#region migrate to v5.2.0
|
||||||
// get rid of meta-directories, combine DownloadsInProgressEnum and DecryptInProgressEnum => InProgress
|
// get rid of meta-directories, combine DownloadsInProgressEnum and DecryptInProgressEnum => InProgress
|
||||||
private static void migrate_to_v5_2_0__pre_config()
|
private static void migrate_to_v5_2_0__pre_config()
|
||||||
{
|
{
|
||||||
@ -231,9 +234,9 @@ namespace LibationLauncher
|
|||||||
if (!config.Exists(nameof(config.DecryptToLossy)))
|
if (!config.Exists(nameof(config.DecryptToLossy)))
|
||||||
config.DecryptToLossy = false;
|
config.DecryptToLossy = false;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region migrate to v5.4.1 see comment
|
#region migrate to v5.4.1 see comment
|
||||||
// this 'migration' is a bit different. it intentionally runs each time Libation is started. its job will be fulfilled when I eventually
|
// this 'migration' is a bit different. it intentionally runs each time Libation is started. its job will be fulfilled when I eventually
|
||||||
// implement the portion which removes FilePaths.json, at which time this method will be a proper migration
|
// implement the portion which removes FilePaths.json, at which time this method will be a proper migration
|
||||||
//
|
//
|
||||||
@ -297,7 +300,7 @@ namespace LibationLauncher
|
|||||||
debugStopwatch.Stop();
|
debugStopwatch.Stop();
|
||||||
var debugTotal = debugStopwatch.Elapsed;
|
var debugTotal = debugStopwatch.Elapsed;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static void ensureSerilogConfig(Configuration config)
|
private static void ensureSerilogConfig(Configuration config)
|
||||||
{
|
{
|
||||||
@ -418,6 +421,7 @@ namespace LibationLauncher
|
|||||||
if (latest is null)
|
if (latest is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
var latestVersionString = latest.TagName.Trim('v');
|
var latestVersionString = latest.TagName.Trim('v');
|
||||||
if (!Version.TryParse(latestVersionString, out var latestRelease))
|
if (!Version.TryParse(latestVersionString, out var latestRelease))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -39,8 +39,8 @@ namespace LibationWinForms.Dialogs
|
|||||||
dataGridView1.BindingContextChanged += (s, e) => UpdateSelection();
|
dataGridView1.BindingContextChanged += (s, e) => UpdateSelection();
|
||||||
|
|
||||||
var orderedGridEntries = _libraryBooks
|
var orderedGridEntries = _libraryBooks
|
||||||
.Select(lb => new RemovableGridEntry(new GridEntry(lb)))
|
.Select(lb => new RemovableGridEntry(lb))
|
||||||
.OrderByDescending(ge => ge.GridEntry.PurchaseDate)
|
.OrderByDescending(ge => ge.PurchaseDate)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
_removableGridEntries = orderedGridEntries.ToSortableBindingList();
|
_removableGridEntries = orderedGridEntries.ToSortableBindingList();
|
||||||
@ -65,7 +65,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
{
|
{
|
||||||
var rmovedBooks = await LibraryCommands.FindInactiveBooks((account) => new WinformResponder(account), _libraryBooks, _accounts);
|
var rmovedBooks = await LibraryCommands.FindInactiveBooks((account) => new WinformResponder(account), _libraryBooks, _accounts);
|
||||||
|
|
||||||
var removable = _removableGridEntries.Where(rge => rmovedBooks.Count(rb => rb.Book.AudibleProductId == rge.GridEntry.AudibleProductId) == 1);
|
var removable = _removableGridEntries.Where(rge => rmovedBooks.Count(rb => rb.Book.AudibleProductId == rge.AudibleProductId) == 1);
|
||||||
|
|
||||||
if (removable.Count() == 0)
|
if (removable.Count() == 0)
|
||||||
return;
|
return;
|
||||||
@ -110,7 +110,7 @@ namespace LibationWinForms.Dialogs
|
|||||||
|
|
||||||
var libBooks = context.GetLibrary_Flat_NoTracking();
|
var libBooks = context.GetLibrary_Flat_NoTracking();
|
||||||
|
|
||||||
var removeLibraryBooks = libBooks.Where(lb => selected.Count(rge => rge.GridEntry.AudibleProductId == lb.Book.AudibleProductId) == 1).ToArray();
|
var removeLibraryBooks = libBooks.Where(lb => selected.Count(rge => rge.AudibleProductId == lb.Book.AudibleProductId) == 1).ToArray();
|
||||||
context.Library.RemoveRange(removeLibraryBooks);
|
context.Library.RemoveRange(removeLibraryBooks);
|
||||||
context.SaveChanges();
|
context.SaveChanges();
|
||||||
BooksRemoved = true;
|
BooksRemoved = true;
|
||||||
@ -141,11 +141,8 @@ namespace LibationWinForms.Dialogs
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal class RemovableGridEntry : INotifyPropertyChanged
|
internal class RemovableGridEntry : GridEntry
|
||||||
{
|
{
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
public GridEntry GridEntry { get; }
|
|
||||||
|
|
||||||
public bool Remove
|
public bool Remove
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -161,50 +158,11 @@ namespace LibationWinForms.Dialogs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Image Cover
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _cover;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_cover = value;
|
|
||||||
NotifyPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string Title => GridEntry.Title;
|
|
||||||
public string Authors => GridEntry.Authors;
|
|
||||||
public string Misc => GridEntry.Misc;
|
|
||||||
public string DatePurchased => GridEntry.PurchaseDate;
|
|
||||||
|
|
||||||
private bool _remove = false;
|
private bool _remove = false;
|
||||||
private Image _cover;
|
|
||||||
|
|
||||||
public RemovableGridEntry(GridEntry gridEntry)
|
public RemovableGridEntry(LibraryBook libraryBook) :base(libraryBook)
|
||||||
{
|
{
|
||||||
GridEntry = gridEntry;
|
|
||||||
|
|
||||||
var picDef = new FileManager.PictureDefinition(GridEntry.LibraryBook.Book.PictureId, FileManager.PictureSize._80x80);
|
|
||||||
(bool isDefault, byte[] picture) = FileManager.PictureStorage.GetPicture(picDef);
|
|
||||||
|
|
||||||
if (isDefault)
|
|
||||||
FileManager.PictureStorage.PictureCached += PictureStorage_PictureCached;
|
|
||||||
|
|
||||||
_cover = ImageReader.ToImage(picture);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PictureStorage_PictureCached(object sender, string pictureId)
|
|
||||||
{
|
|
||||||
if (pictureId == GridEntry.LibraryBook.Book.PictureId)
|
|
||||||
{
|
|
||||||
Cover = WindowsDesktopUtilities.WinAudibleImageServer.GetImage(pictureId, FileManager.PictureSize._80x80);
|
|
||||||
FileManager.PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,15 +12,23 @@ namespace LibationWinForms
|
|||||||
internal class EditTagsDataGridViewImageButtonCell : DataGridViewImageButtonCell
|
internal class EditTagsDataGridViewImageButtonCell : DataGridViewImageButtonCell
|
||||||
{
|
{
|
||||||
private static readonly Bitmap ButtonImage = Properties.Resources.edit_tags_25x25;
|
private static readonly Bitmap ButtonImage = Properties.Resources.edit_tags_25x25;
|
||||||
|
private static readonly Color HiddenForeColor = 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)
|
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 (((string)value).Length == 0)
|
var valueString = (string)value;
|
||||||
|
|
||||||
|
DataGridView.Rows[RowIndex].DefaultCellStyle.ForeColor = valueString?.Contains("hidden") == true ? HiddenForeColor : DataGridView.DefaultCellStyle.ForeColor;
|
||||||
|
|
||||||
|
if (valueString.Length == 0)
|
||||||
{
|
{
|
||||||
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
|
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
|
||||||
DrawImage(graphics, ButtonImage, cellBounds);
|
DrawImage(graphics, ButtonImage, cellBounds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
|
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,13 +48,6 @@ namespace LibationWinForms
|
|||||||
this.Load += (_, __) => RestoreSizeAndLocation();
|
this.Load += (_, __) => RestoreSizeAndLocation();
|
||||||
this.Load += (_, __) => RefreshImportMenu();
|
this.Load += (_, __) => RefreshImportMenu();
|
||||||
|
|
||||||
// start background service
|
|
||||||
this.Load += (_, __) => startBackgroundImageDownloader();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void startBackgroundImageDownloader()
|
|
||||||
{
|
|
||||||
// load default/missing cover images. this will also initiate the background image downloader
|
|
||||||
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
|
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
|
||||||
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
|
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));
|
||||||
PictureStorage.SetDefaultImage(PictureSize._300x300, Properties.Resources.default_cover_300x300.ToBytes(format));
|
PictureStorage.SetDefaultImage(PictureSize._300x300, Properties.Resources.default_cover_300x300.ToBytes(format));
|
||||||
|
|||||||
@ -5,9 +5,11 @@ using System.ComponentModel;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading;
|
||||||
using ApplicationServices;
|
using ApplicationServices;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.Drawing;
|
using Dinah.Core.Drawing;
|
||||||
|
using Dinah.Core.Windows.Forms;
|
||||||
|
|
||||||
namespace LibationWinForms
|
namespace LibationWinForms
|
||||||
{
|
{
|
||||||
@ -32,6 +34,7 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
private Book Book => LibraryBook.Book;
|
private Book Book => LibraryBook.Book;
|
||||||
|
private SynchronizationContext SyncContext { get; } = SynchronizationContext.Current;
|
||||||
private Image _cover;
|
private Image _cover;
|
||||||
|
|
||||||
public GridEntry(LibraryBook libraryBook)
|
public GridEntry(LibraryBook libraryBook)
|
||||||
@ -72,16 +75,23 @@ namespace LibationWinForms
|
|||||||
{
|
{
|
||||||
if (pictureId == Book.PictureId)
|
if (pictureId == Book.PictureId)
|
||||||
{
|
{
|
||||||
|
//GridEntry SHOULD be UI-ignorant, but PropertyChanged
|
||||||
Cover = WindowsDesktopUtilities.WinAudibleImageServer.GetImage(pictureId, FileManager.PictureSize._80x80);
|
Cover = WindowsDesktopUtilities.WinAudibleImageServer.GetImage(pictureId, FileManager.PictureSize._80x80);
|
||||||
FileManager.PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
FileManager.PictureStorage.PictureCached -= PictureStorage_PictureCached;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
|
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
=> SyncContext.Post(
|
||||||
|
args => OnPropertyChangedAsync(args as AsyncCompletedEventArgs),
|
||||||
|
new AsyncCompletedEventArgs(null, false, new PropertyChangedEventArgs(propertyName))
|
||||||
|
);
|
||||||
|
|
||||||
#region Data Source properties
|
private void OnPropertyChangedAsync(AsyncCompletedEventArgs e) =>
|
||||||
public Image Cover
|
PropertyChanged?.Invoke(this, e.UserState as PropertyChangedEventArgs);
|
||||||
|
|
||||||
|
#region Data Source properties
|
||||||
|
public Image Cover
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
@ -38,7 +37,6 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
// sorting breaks filters. must reapply filters after sorting
|
// sorting breaks filters. must reapply filters after sorting
|
||||||
_dataGridView.Sorted += (_, __) => Filter();
|
_dataGridView.Sorted += (_, __) => Filter();
|
||||||
_dataGridView.CellFormatting += HiddenFormatting;
|
|
||||||
_dataGridView.CellContentClick += DataGridView_CellContentClick;
|
_dataGridView.CellContentClick += DataGridView_CellContentClick;
|
||||||
|
|
||||||
EnableDoubleBuffering();
|
EnableDoubleBuffering();
|
||||||
@ -133,7 +131,7 @@ namespace LibationWinForms
|
|||||||
var orderedGridEntries = lib
|
var orderedGridEntries = lib
|
||||||
.Select(lb => new GridEntry(lb)).ToList()
|
.Select(lb => new GridEntry(lb)).ToList()
|
||||||
// default load order
|
// default load order
|
||||||
.OrderByDescending(ge => ge.PurchaseDate)
|
.OrderByDescending(ge => (DateTime)ge.GetMemberValue(nameof(ge.PurchaseDate)))
|
||||||
//// more advanced example: sort by author, then series, then title
|
//// more advanced example: sort by author, then series, then title
|
||||||
//.OrderBy(ge => ge.Authors)
|
//.OrderBy(ge => ge.Authors)
|
||||||
// .ThenBy(ge => ge.Series)
|
// .ThenBy(ge => ge.Series)
|
||||||
@ -155,10 +153,10 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
public void RefreshRow(string productId)
|
public void RefreshRow(string productId)
|
||||||
{
|
{
|
||||||
var rowId = getRowIndex((ge) => ge.AudibleProductId == productId);
|
var rowIndex = getRowIndex((ge) => ge.AudibleProductId == productId);
|
||||||
|
|
||||||
// update cells incl Liberate button text
|
// update cells incl Liberate button text
|
||||||
_dataGridView.InvalidateRow(rowId);
|
_dataGridView.InvalidateRow(rowIndex);
|
||||||
|
|
||||||
// needed in case filtering by -IsLiberated and it gets changed to Liberated. want to immediately show the change
|
// needed in case filtering by -IsLiberated and it gets changed to Liberated. want to immediately show the change
|
||||||
Filter();
|
Filter();
|
||||||
@ -166,28 +164,9 @@ namespace LibationWinForms
|
|||||||
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
BackupCountsChanged?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region format text cells. ie: not buttons
|
|
||||||
|
|
||||||
private void HiddenFormatting(object sender, DataGridViewCellFormattingEventArgs e)
|
|
||||||
{
|
|
||||||
var dgv = (DataGridView)sender;
|
|
||||||
// no action needed for buttons
|
|
||||||
if (e.RowIndex < 0 || dgv.Columns[e.ColumnIndex] is DataGridViewButtonColumn)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var isHidden = getGridEntry(e.RowIndex).TagsEnumerated.Contains("hidden");
|
|
||||||
|
|
||||||
getCell(e).Style
|
|
||||||
= isHidden
|
|
||||||
? new DataGridViewCellStyle { ForeColor = Color.LightGray }
|
|
||||||
: dgv.DefaultCellStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#region Filter
|
||||||
|
|
||||||
#region filter
|
|
||||||
|
|
||||||
string _filterSearchString;
|
string _filterSearchString;
|
||||||
private void Filter() => Filter(_filterSearchString);
|
private void Filter() => Filter(_filterSearchString);
|
||||||
@ -220,7 +199,6 @@ namespace LibationWinForms
|
|||||||
|
|
||||||
private int getRowIndex(Func<GridEntry, bool> func) => _dataGridView.GetRowIdOfBoundItem(func);
|
private int getRowIndex(Func<GridEntry, bool> func) => _dataGridView.GetRowIdOfBoundItem(func);
|
||||||
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
|
||||||
private DataGridViewCell getCell(DataGridViewCellFormattingEventArgs e) => _dataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user