Added RemoveBooksDialog

This commit is contained in:
Michael Bucari-Tovo 2021-08-09 01:08:35 -06:00
parent 35f54779f0
commit f621ca63e8
4 changed files with 481 additions and 0 deletions

View File

@ -0,0 +1,188 @@

namespace LibationWinForms.Dialogs
{
partial class RemoveBooksDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.gridEntryBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.btnRemoveBooks = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.removeDataGridViewCheckBoxColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.coverDataGridViewImageColumn = new System.Windows.Forms.DataGridViewImageColumn();
this.titleDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.authorsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.miscDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.DatePurchased = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridView1.AutoGenerateColumns = false;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.removeDataGridViewCheckBoxColumn,
this.coverDataGridViewImageColumn,
this.titleDataGridViewTextBoxColumn,
this.authorsDataGridViewTextBoxColumn,
this.miscDataGridViewTextBoxColumn,
this.DatePurchased});
this.dataGridView1.DataSource = this.gridEntryBindingSource;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.dataGridView1.DefaultCellStyle = dataGridViewCellStyle1;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.RowTemplate.Height = 82;
this.dataGridView1.Size = new System.Drawing.Size(800, 409);
this.dataGridView1.TabIndex = 0;
//
// gridEntryBindingSource
//
this.gridEntryBindingSource.AllowNew = false;
this.gridEntryBindingSource.DataSource = typeof(LibationWinForms.Dialogs.RemovableGridEntry);
//
// btnRemoveBooks
//
this.btnRemoveBooks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnRemoveBooks.Location = new System.Drawing.Point(570, 419);
this.btnRemoveBooks.Name = "btnRemoveBooks";
this.btnRemoveBooks.Size = new System.Drawing.Size(218, 23);
this.btnRemoveBooks.TabIndex = 1;
this.btnRemoveBooks.Text = "Remove Selected Books from Libation";
this.btnRemoveBooks.UseVisualStyleBackColor = true;
this.btnRemoveBooks.Click += new System.EventHandler(this.btnRemoveBooks_Click);
//
// label1
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 423);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(169, 15);
this.label1.TabIndex = 2;
this.label1.Text = "{0} books selected for removal.";
//
// removeDataGridViewCheckBoxColumn
//
this.removeDataGridViewCheckBoxColumn.DataPropertyName = "Remove";
this.removeDataGridViewCheckBoxColumn.FalseValue = "False";
this.removeDataGridViewCheckBoxColumn.Frozen = true;
this.removeDataGridViewCheckBoxColumn.HeaderText = "Remove";
this.removeDataGridViewCheckBoxColumn.MinimumWidth = 60;
this.removeDataGridViewCheckBoxColumn.Name = "removeDataGridViewCheckBoxColumn";
this.removeDataGridViewCheckBoxColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
this.removeDataGridViewCheckBoxColumn.TrueValue = "True";
this.removeDataGridViewCheckBoxColumn.Width = 60;
//
// coverDataGridViewImageColumn
//
this.coverDataGridViewImageColumn.DataPropertyName = "Cover";
this.coverDataGridViewImageColumn.HeaderText = "Cover";
this.coverDataGridViewImageColumn.MinimumWidth = 80;
this.coverDataGridViewImageColumn.Name = "coverDataGridViewImageColumn";
this.coverDataGridViewImageColumn.ReadOnly = true;
this.coverDataGridViewImageColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.coverDataGridViewImageColumn.Width = 80;
//
// titleDataGridViewTextBoxColumn
//
this.titleDataGridViewTextBoxColumn.DataPropertyName = "Title";
this.titleDataGridViewTextBoxColumn.HeaderText = "Title";
this.titleDataGridViewTextBoxColumn.Name = "titleDataGridViewTextBoxColumn";
this.titleDataGridViewTextBoxColumn.ReadOnly = true;
this.titleDataGridViewTextBoxColumn.Width = 200;
//
// authorsDataGridViewTextBoxColumn
//
this.authorsDataGridViewTextBoxColumn.DataPropertyName = "Authors";
this.authorsDataGridViewTextBoxColumn.HeaderText = "Authors";
this.authorsDataGridViewTextBoxColumn.Name = "authorsDataGridViewTextBoxColumn";
this.authorsDataGridViewTextBoxColumn.ReadOnly = true;
//
// miscDataGridViewTextBoxColumn
//
this.miscDataGridViewTextBoxColumn.DataPropertyName = "Misc";
this.miscDataGridViewTextBoxColumn.HeaderText = "Misc";
this.miscDataGridViewTextBoxColumn.Name = "miscDataGridViewTextBoxColumn";
this.miscDataGridViewTextBoxColumn.ReadOnly = true;
this.miscDataGridViewTextBoxColumn.Width = 150;
//
// DatePurchased
//
this.DatePurchased.DataPropertyName = "DatePurchased";
this.DatePurchased.HeaderText = "Date Purchased";
this.DatePurchased.Name = "DatePurchased";
this.DatePurchased.ReadOnly = true;
this.DatePurchased.Width = 120;
//
// RemoveBooksDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnRemoveBooks);
this.Controls.Add(this.dataGridView1);
this.Name = "RemoveBooksDialog";
this.Text = "RemoveBooksDialog";
this.Shown += new System.EventHandler(this.RemoveBooksDialog_Shown);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.BindingSource gridEntryBindingSource;
private System.Windows.Forms.Button btnRemoveBooks;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.DataGridViewCheckBoxColumn removeDataGridViewCheckBoxColumn;
private System.Windows.Forms.DataGridViewImageColumn coverDataGridViewImageColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn titleDataGridViewTextBoxColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn authorsDataGridViewTextBoxColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn miscDataGridViewTextBoxColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn DatePurchased;
}
}

View File

@ -0,0 +1,217 @@
using ApplicationServices;
using DataLayer;
using InternalUtilities;
using LibationWinForms.Login;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Dinah.Core.DataBinding;
using System.Runtime.CompilerServices;
using Dinah.Core.Drawing;
using System.Collections;
namespace LibationWinForms.Dialogs
{
public partial class RemoveBooksDialog : Form
{
public bool BooksRemoved { get; private set; }
private Account[] _accounts { get; }
private List<LibraryBook> _libraryBooks;
private SortableBindingList<RemovableGridEntry> _removableGridEntries;
private string _labelFormat;
private int SelectedCount => SelectedEntries?.Count() ?? 0;
private IEnumerable<RemovableGridEntry> SelectedEntries => _removableGridEntries?.Where(b => b.Remove);
public RemoveBooksDialog(params Account[] accounts)
{
_libraryBooks = DbContexts.GetContext().GetLibrary_Flat_NoTracking();
_accounts = accounts;
InitializeComponent();
_labelFormat = label1.Text;
dataGridView1.CellContentClick += (s, e) => dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
dataGridView1.CellValueChanged += DataGridView1_CellValueChanged;
dataGridView1.BindingContextChanged += (s, e) => UpdateSelection();
var orderedGridEntries = _libraryBooks
.Select(lb => new RemovableGridEntry(new GridEntry(lb)))
.OrderByDescending(ge => ge.GridEntry.Purchase_Date)
.ToList();
_removableGridEntries = orderedGridEntries.ToSortableBindingList();
gridEntryBindingSource.DataSource = _removableGridEntries;
dataGridView1.Enabled = false;
}
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0)
{
UpdateSelection();
}
}
private async void RemoveBooksDialog_Shown(object sender, EventArgs e)
{
if (_accounts == null || _accounts.Length == 0)
return;
try
{
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);
if (removable.Count() == 0)
return;
foreach (var r in removable)
r.Remove = true;
UpdateSelection();
}
catch (Exception ex)
{
MessageBoxAlertAdmin.Show(
"Error scanning library. You may still manually select books to remove from Libation's library.",
"Error scanning library",
ex);
}
finally
{
dataGridView1.Enabled = true;
}
}
private void btnRemoveBooks_Click(object sender, EventArgs e)
{
var selected = SelectedEntries.ToList();
if (selected.Count == 0) return;
string titles = string.Join("\r\n", selected.Select(rge => "-" + rge.Title));
var result = MessageBox.Show(
this,
$"Are you sure you want to remove the following {selected.Count} books from Libation's library?\r\n\r\n{titles}",
"Remove books from Libation?",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
if (result == DialogResult.Yes)
{
using var context = DbContexts.GetContext();
var libBooks = context.GetLibrary_Flat_NoTracking();
var removeLibraryBooks = libBooks.Where(lb => selected.Count(rge => rge.GridEntry.AudibleProductId == lb.Book.AudibleProductId) == 1).ToArray();
context.Library.RemoveRange(removeLibraryBooks);
context.SaveChanges();
BooksRemoved = true;
foreach (var rEntry in selected)
_removableGridEntries.Remove(rEntry);
UpdateSelection();
}
}
private void UpdateSelection()
{
dataGridView1.Sort(dataGridView1.Columns[0], ListSortDirection.Descending);
var selectedCount = SelectedCount;
label1.Text = string.Format(_labelFormat, selectedCount);
btnRemoveBooks.Enabled = selectedCount > 0;
}
}
class CompareBool : IComparer
{
public int Compare(object x, object y)
{
var rge1 = x as RemovableGridEntry;
var rge2 = y as RemovableGridEntry;
return rge1.Remove.CompareTo(rge2.Remove);
}
}
internal class RemovableGridEntry : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public GridEntry GridEntry { get; }
public bool Remove
{
get
{
return _remove;
}
set
{
if (_remove != value)
{
_remove = value;
NotifyPropertyChanged();
}
}
}
public Image Cover
{
get
{
return _cover;
}
set
{
_cover = value;
NotifyPropertyChanged();
}
}
public string Title => GetDisplayValue(nameof(GridEntry.Title), GridEntry.Title);
public string Authors => GetDisplayValue(nameof(GridEntry.Authors), GridEntry.Authors);
public string Misc => GetDisplayValue(nameof(GridEntry.Misc), GridEntry.Misc);
public string DatePurchased => GetDisplayValue(nameof(GridEntry.Purchase_Date), GridEntry.Purchase_Date);
private bool _remove = false;
private Image _cover;
public RemovableGridEntry(GridEntry gridEntry)
{
GridEntry = gridEntry;
var picDef = new FileManager.PictureDefinition(GridEntry.GetBook().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.GetBook().PictureId)
{
Cover = WindowsDesktopUtilities.WinAudibleImageServer.GetImage(pictureId, FileManager.PictureSize._80x80);
FileManager.PictureStorage.PictureCached -= PictureStorage_PictureCached;
}
}
private string GetDisplayValue(string propertyName, string defaultValue)
{
if (GridEntry.TryDisplayValue(propertyName, out string value))
return value;
return defaultValue;
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View File

@ -0,0 +1,66 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="DatePurchased.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="gridEntryBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="RemovableGridEntry" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>LibationWinForms.Dialogs.RemovableGridEntry, LibationWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>