Merge pull request #255 from Mbucari/master

Implemented Episode grouping and refactored ProductsGrid
This commit is contained in:
rmcrackan 2022-05-24 13:59:12 -04:00 committed by GitHub
commit b37472a954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1845 additions and 1202 deletions

View File

@ -12,7 +12,7 @@ namespace DataLayer
public float StoryRating { get; private set; } public float StoryRating { get; private set; }
private Rating() { } private Rating() { }
internal Rating(float overallRating, float performanceRating, float storyRating) public Rating(float overallRating, float performanceRating, float storyRating)
{ {
OverallRating = overallRating; OverallRating = overallRating;
PerformanceRating = performanceRating; PerformanceRating = performanceRating;

View File

@ -38,7 +38,7 @@ namespace LibationWinForms.Dialogs
this.authorsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.authorsDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.miscDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.miscDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.purchaseDateGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.purchaseDateGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components); this.gridEntryBindingSource = new LibationWinForms.GridView.SyncBindingSource(this.components);
this.btnRemoveBooks = new System.Windows.Forms.Button(); this.btnRemoveBooks = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this._dataGridView)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this._dataGridView)).BeginInit();
@ -176,7 +176,7 @@ namespace LibationWinForms.Dialogs
#endregion #endregion
private System.Windows.Forms.DataGridView _dataGridView; private System.Windows.Forms.DataGridView _dataGridView;
private LibationWinForms.SyncBindingSource gridEntryBindingSource; private LibationWinForms.GridView.SyncBindingSource gridEntryBindingSource;
private System.Windows.Forms.Button btnRemoveBooks; private System.Windows.Forms.Button btnRemoveBooks;
private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label1;
private System.Windows.Forms.DataGridViewCheckBoxColumn removeDataGridViewCheckBoxColumn; private System.Windows.Forms.DataGridViewCheckBoxColumn removeDataGridViewCheckBoxColumn;

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
@ -121,10 +120,8 @@ namespace LibationWinForms.Dialogs
} }
} }
internal class RemovableGridEntry : GridEntry internal class RemovableGridEntry : GridView.LibraryBookEntry
{ {
private static readonly IComparer BoolComparer = new ObjectComparer<bool>();
private bool _remove = false; private bool _remove = false;
public RemovableGridEntry(LibraryBook libraryBook) : base(libraryBook) { } public RemovableGridEntry(LibraryBook libraryBook) : base(libraryBook) { }
@ -147,12 +144,5 @@ namespace LibationWinForms.Dialogs
return Remove; return Remove;
return base.GetMemberValue(memberName); return base.GetMemberValue(memberName);
} }
public override IComparer GetMemberComparer(Type memberType)
{
if (memberType == typeof(bool))
return BoolComparer;
return base.GetMemberComparer(memberType);
}
} }
} }

View File

@ -28,111 +28,100 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.gridPanel = new System.Windows.Forms.Panel(); this.filterHelpBtn = new System.Windows.Forms.Button();
this.filterHelpBtn = new System.Windows.Forms.Button(); this.filterBtn = new System.Windows.Forms.Button();
this.filterBtn = new System.Windows.Forms.Button(); this.filterSearchTb = new System.Windows.Forms.TextBox();
this.filterSearchTb = new System.Windows.Forms.TextBox(); this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.importToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.autoScanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.autoScanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.noAccountsYetAddAccountToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.noAccountsYetAddAccountToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.scanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scanLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.scanLibraryOfAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scanLibraryOfAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.scanLibraryOfSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scanLibraryOfSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeLibraryBooksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeLibraryBooksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeAllAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeSomeAccountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.liberateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.beginBookBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
this.beginBookBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem(); this.beginPdfBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
this.beginPdfBackupsToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem(); this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.convertAllM4bToMp3ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.liberateVisible2ToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
this.liberateVisible2ToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem(); this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportLibraryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.quickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.firstFilterIsDefaultToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.firstFilterIsDefaultToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.editQuickFiltersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.scanningToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.visibleBooksToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
this.visibleBooksToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem(); this.liberateVisibleToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem();
this.liberateVisibleToolStripMenuItem = new LibationWinForms.FormattableToolStripMenuItem(); this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.replaceTagsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.setDownloadedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.accountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.accountsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.basicSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.basicSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel();
this.visibleCountLbl = new LibationWinForms.FormattableToolStripStatusLabel(); this.springLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.springLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel();
this.backupsCountsLbl = new System.Windows.Forms.ToolStripStatusLabel(); this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel();
this.pdfsCountsLbl = new LibationWinForms.FormattableToolStripStatusLabel(); this.addQuickFilterBtn = new System.Windows.Forms.Button();
this.addQuickFilterBtn = new System.Windows.Forms.Button(); this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.panel1 = new System.Windows.Forms.Panel();
this.panel1 = new System.Windows.Forms.Panel(); this.productsDisplay = new LibationWinForms.GridView.ProductsDisplay();
this.toggleQueueHideBtn = new System.Windows.Forms.Button(); this.toggleQueueHideBtn = new System.Windows.Forms.Button();
this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl(); this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
this.statusStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout(); this.splitContainer1.SuspendLayout();
this.panel1.SuspendLayout(); this.panel1.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
// gridPanel // filterHelpBtn
// //
this.gridPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) this.filterHelpBtn.Location = new System.Drawing.Point(15, 3);
| System.Windows.Forms.AnchorStyles.Left) this.filterHelpBtn.Margin = new System.Windows.Forms.Padding(15, 3, 4, 3);
this.filterHelpBtn.Name = "filterHelpBtn";
this.filterHelpBtn.Size = new System.Drawing.Size(26, 27);
this.filterHelpBtn.TabIndex = 3;
this.filterHelpBtn.Text = "?";
this.filterHelpBtn.UseVisualStyleBackColor = true;
this.filterHelpBtn.Click += new System.EventHandler(this.filterHelpBtn_Click);
//
// filterBtn
//
this.filterBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.filterBtn.Location = new System.Drawing.Point(916, 3);
this.filterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.filterBtn.Name = "filterBtn";
this.filterBtn.Size = new System.Drawing.Size(88, 27);
this.filterBtn.TabIndex = 2;
this.filterBtn.Text = "Filter";
this.filterBtn.UseVisualStyleBackColor = true;
this.filterBtn.Click += new System.EventHandler(this.filterBtn_Click);
//
// filterSearchTb
//
this.filterSearchTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.gridPanel.Location = new System.Drawing.Point(15, 33); this.filterSearchTb.Location = new System.Drawing.Point(196, 7);
this.gridPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.filterSearchTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.gridPanel.Name = "gridPanel"; this.filterSearchTb.Name = "filterSearchTb";
this.gridPanel.Size = new System.Drawing.Size(864, 558); this.filterSearchTb.Size = new System.Drawing.Size(712, 23);
this.gridPanel.TabIndex = 5; this.filterSearchTb.TabIndex = 1;
// this.filterSearchTb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filterSearchTb_KeyPress);
// filterHelpBtn //
// // menuStrip1
this.filterHelpBtn.Location = new System.Drawing.Point(15, 3); //
this.filterHelpBtn.Margin = new System.Windows.Forms.Padding(15, 3, 4, 3); this.menuStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
this.filterHelpBtn.Name = "filterHelpBtn"; this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.filterHelpBtn.Size = new System.Drawing.Size(26, 27);
this.filterHelpBtn.TabIndex = 3;
this.filterHelpBtn.Text = "?";
this.filterHelpBtn.UseVisualStyleBackColor = true;
this.filterHelpBtn.Click += new System.EventHandler(this.filterHelpBtn_Click);
//
// filterBtn
//
this.filterBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.filterBtn.Location = new System.Drawing.Point(748, 3);
this.filterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.filterBtn.Name = "filterBtn";
this.filterBtn.Size = new System.Drawing.Size(88, 27);
this.filterBtn.TabIndex = 2;
this.filterBtn.Text = "Filter";
this.filterBtn.UseVisualStyleBackColor = true;
this.filterBtn.Click += new System.EventHandler(this.filterBtn_Click);
//
// filterSearchTb
//
this.filterSearchTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.filterSearchTb.Location = new System.Drawing.Point(196, 7);
this.filterSearchTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.filterSearchTb.Name = "filterSearchTb";
this.filterSearchTb.Size = new System.Drawing.Size(544, 23);
this.filterSearchTb.TabIndex = 1;
this.filterSearchTb.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.filterSearchTb_KeyPress);
//
// menuStrip1
//
this.menuStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.importToolStripMenuItem, this.importToolStripMenuItem,
this.liberateToolStripMenuItem, this.liberateToolStripMenuItem,
this.exportToolStripMenuItem, this.exportToolStripMenuItem,
@ -140,402 +129,415 @@
this.scanningToolStripMenuItem, this.scanningToolStripMenuItem,
this.visibleBooksToolStripMenuItem, this.visibleBooksToolStripMenuItem,
this.settingsToolStripMenuItem}); this.settingsToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2); this.menuStrip1.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2);
this.menuStrip1.Size = new System.Drawing.Size(893, 24); this.menuStrip1.Size = new System.Drawing.Size(1061, 24);
this.menuStrip1.TabIndex = 0; this.menuStrip1.TabIndex = 0;
this.menuStrip1.Text = "menuStrip1"; this.menuStrip1.Text = "menuStrip1";
// //
// importToolStripMenuItem // importToolStripMenuItem
// //
this.importToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.importToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.autoScanLibraryToolStripMenuItem, this.autoScanLibraryToolStripMenuItem,
this.noAccountsYetAddAccountToolStripMenuItem, this.noAccountsYetAddAccountToolStripMenuItem,
this.scanLibraryToolStripMenuItem, this.scanLibraryToolStripMenuItem,
this.scanLibraryOfAllAccountsToolStripMenuItem, this.scanLibraryOfAllAccountsToolStripMenuItem,
this.scanLibraryOfSomeAccountsToolStripMenuItem, this.scanLibraryOfSomeAccountsToolStripMenuItem,
this.removeLibraryBooksToolStripMenuItem}); this.removeLibraryBooksToolStripMenuItem});
this.importToolStripMenuItem.Name = "importToolStripMenuItem"; this.importToolStripMenuItem.Name = "importToolStripMenuItem";
this.importToolStripMenuItem.Size = new System.Drawing.Size(55, 20); this.importToolStripMenuItem.Size = new System.Drawing.Size(55, 20);
this.importToolStripMenuItem.Text = "&Import"; this.importToolStripMenuItem.Text = "&Import";
// //
// autoScanLibraryToolStripMenuItem // autoScanLibraryToolStripMenuItem
// //
this.autoScanLibraryToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.autoScanLibraryToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.autoScanLibraryToolStripMenuItem.Name = "autoScanLibraryToolStripMenuItem"; this.autoScanLibraryToolStripMenuItem.Name = "autoScanLibraryToolStripMenuItem";
this.autoScanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.autoScanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.autoScanLibraryToolStripMenuItem.Text = "A&uto Scan Library"; this.autoScanLibraryToolStripMenuItem.Text = "A&uto Scan Library";
this.autoScanLibraryToolStripMenuItem.Click += new System.EventHandler(this.autoScanLibraryToolStripMenuItem_Click); this.autoScanLibraryToolStripMenuItem.Click += new System.EventHandler(this.autoScanLibraryToolStripMenuItem_Click);
// //
// noAccountsYetAddAccountToolStripMenuItem // noAccountsYetAddAccountToolStripMenuItem
// //
this.noAccountsYetAddAccountToolStripMenuItem.Name = "noAccountsYetAddAccountToolStripMenuItem"; this.noAccountsYetAddAccountToolStripMenuItem.Name = "noAccountsYetAddAccountToolStripMenuItem";
this.noAccountsYetAddAccountToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.noAccountsYetAddAccountToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.noAccountsYetAddAccountToolStripMenuItem.Text = "No accounts yet. A&dd Account..."; this.noAccountsYetAddAccountToolStripMenuItem.Text = "No accounts yet. A&dd Account...";
this.noAccountsYetAddAccountToolStripMenuItem.Click += new System.EventHandler(this.noAccountsYetAddAccountToolStripMenuItem_Click); this.noAccountsYetAddAccountToolStripMenuItem.Click += new System.EventHandler(this.noAccountsYetAddAccountToolStripMenuItem_Click);
// //
// scanLibraryToolStripMenuItem // scanLibraryToolStripMenuItem
// //
this.scanLibraryToolStripMenuItem.Name = "scanLibraryToolStripMenuItem"; this.scanLibraryToolStripMenuItem.Name = "scanLibraryToolStripMenuItem";
this.scanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.scanLibraryToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.scanLibraryToolStripMenuItem.Text = "Scan &Library"; this.scanLibraryToolStripMenuItem.Text = "Scan &Library";
this.scanLibraryToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryToolStripMenuItem_Click); this.scanLibraryToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryToolStripMenuItem_Click);
// //
// scanLibraryOfAllAccountsToolStripMenuItem // scanLibraryOfAllAccountsToolStripMenuItem
// //
this.scanLibraryOfAllAccountsToolStripMenuItem.Name = "scanLibraryOfAllAccountsToolStripMenuItem"; this.scanLibraryOfAllAccountsToolStripMenuItem.Name = "scanLibraryOfAllAccountsToolStripMenuItem";
this.scanLibraryOfAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.scanLibraryOfAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.scanLibraryOfAllAccountsToolStripMenuItem.Text = "Scan Library of &All Accounts"; this.scanLibraryOfAllAccountsToolStripMenuItem.Text = "Scan Library of &All Accounts";
this.scanLibraryOfAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfAllAccountsToolStripMenuItem_Click); this.scanLibraryOfAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfAllAccountsToolStripMenuItem_Click);
// //
// scanLibraryOfSomeAccountsToolStripMenuItem // scanLibraryOfSomeAccountsToolStripMenuItem
// //
this.scanLibraryOfSomeAccountsToolStripMenuItem.Name = "scanLibraryOfSomeAccountsToolStripMenuItem"; this.scanLibraryOfSomeAccountsToolStripMenuItem.Name = "scanLibraryOfSomeAccountsToolStripMenuItem";
this.scanLibraryOfSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.scanLibraryOfSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.scanLibraryOfSomeAccountsToolStripMenuItem.Text = "Scan Library of &Some Accounts..."; this.scanLibraryOfSomeAccountsToolStripMenuItem.Text = "Scan Library of &Some Accounts...";
this.scanLibraryOfSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfSomeAccountsToolStripMenuItem_Click); this.scanLibraryOfSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.scanLibraryOfSomeAccountsToolStripMenuItem_Click);
// //
// removeLibraryBooksToolStripMenuItem // removeLibraryBooksToolStripMenuItem
// //
this.removeLibraryBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.removeLibraryBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.removeAllAccountsToolStripMenuItem, this.removeAllAccountsToolStripMenuItem,
this.removeSomeAccountsToolStripMenuItem}); this.removeSomeAccountsToolStripMenuItem});
this.removeLibraryBooksToolStripMenuItem.Name = "removeLibraryBooksToolStripMenuItem"; this.removeLibraryBooksToolStripMenuItem.Name = "removeLibraryBooksToolStripMenuItem";
this.removeLibraryBooksToolStripMenuItem.Size = new System.Drawing.Size(247, 22); this.removeLibraryBooksToolStripMenuItem.Size = new System.Drawing.Size(247, 22);
this.removeLibraryBooksToolStripMenuItem.Text = "Remove Library Books"; this.removeLibraryBooksToolStripMenuItem.Text = "Remove Library Books";
this.removeLibraryBooksToolStripMenuItem.Click += new System.EventHandler(this.removeLibraryBooksToolStripMenuItem_Click); this.removeLibraryBooksToolStripMenuItem.Click += new System.EventHandler(this.removeLibraryBooksToolStripMenuItem_Click);
// //
// removeAllAccountsToolStripMenuItem // removeAllAccountsToolStripMenuItem
// //
this.removeAllAccountsToolStripMenuItem.Name = "removeAllAccountsToolStripMenuItem"; this.removeAllAccountsToolStripMenuItem.Name = "removeAllAccountsToolStripMenuItem";
this.removeAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); this.removeAllAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
this.removeAllAccountsToolStripMenuItem.Text = "All Accounts"; this.removeAllAccountsToolStripMenuItem.Text = "All Accounts";
this.removeAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeAllAccountsToolStripMenuItem_Click); this.removeAllAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeAllAccountsToolStripMenuItem_Click);
// //
// removeSomeAccountsToolStripMenuItem // removeSomeAccountsToolStripMenuItem
// //
this.removeSomeAccountsToolStripMenuItem.Name = "removeSomeAccountsToolStripMenuItem"; this.removeSomeAccountsToolStripMenuItem.Name = "removeSomeAccountsToolStripMenuItem";
this.removeSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22); this.removeSomeAccountsToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
this.removeSomeAccountsToolStripMenuItem.Text = "Some Accounts"; this.removeSomeAccountsToolStripMenuItem.Text = "Some Accounts";
this.removeSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeSomeAccountsToolStripMenuItem_Click); this.removeSomeAccountsToolStripMenuItem.Click += new System.EventHandler(this.removeSomeAccountsToolStripMenuItem_Click);
// //
// liberateToolStripMenuItem // liberateToolStripMenuItem
// //
this.liberateToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.liberateToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.beginBookBackupsToolStripMenuItem, this.beginBookBackupsToolStripMenuItem,
this.beginPdfBackupsToolStripMenuItem, this.beginPdfBackupsToolStripMenuItem,
this.convertAllM4bToMp3ToolStripMenuItem, this.convertAllM4bToMp3ToolStripMenuItem,
this.liberateVisible2ToolStripMenuItem}); this.liberateVisible2ToolStripMenuItem});
this.liberateToolStripMenuItem.Name = "liberateToolStripMenuItem"; this.liberateToolStripMenuItem.Name = "liberateToolStripMenuItem";
this.liberateToolStripMenuItem.Size = new System.Drawing.Size(61, 20); this.liberateToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
this.liberateToolStripMenuItem.Text = "&Liberate"; this.liberateToolStripMenuItem.Text = "&Liberate";
// //
// beginBookBackupsToolStripMenuItem // beginBookBackupsToolStripMenuItem
// //
this.beginBookBackupsToolStripMenuItem.FormatText = "Begin &Book and PDF Backups: {0}"; this.beginBookBackupsToolStripMenuItem.FormatText = "Begin &Book and PDF Backups: {0}";
this.beginBookBackupsToolStripMenuItem.Name = "beginBookBackupsToolStripMenuItem"; this.beginBookBackupsToolStripMenuItem.Name = "beginBookBackupsToolStripMenuItem";
this.beginBookBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22); this.beginBookBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
this.beginBookBackupsToolStripMenuItem.Text = "Begin &Book and PDF Backups: {0}"; this.beginBookBackupsToolStripMenuItem.Text = "Begin &Book and PDF Backups: {0}";
this.beginBookBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginBookBackupsToolStripMenuItem_Click); this.beginBookBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginBookBackupsToolStripMenuItem_Click);
// //
// beginPdfBackupsToolStripMenuItem // beginPdfBackupsToolStripMenuItem
// //
this.beginPdfBackupsToolStripMenuItem.FormatText = "Begin &PDF Only Backups: {0}"; this.beginPdfBackupsToolStripMenuItem.FormatText = "Begin &PDF Only Backups: {0}";
this.beginPdfBackupsToolStripMenuItem.Name = "beginPdfBackupsToolStripMenuItem"; this.beginPdfBackupsToolStripMenuItem.Name = "beginPdfBackupsToolStripMenuItem";
this.beginPdfBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22); this.beginPdfBackupsToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
this.beginPdfBackupsToolStripMenuItem.Text = "Begin &PDF Only Backups: {0}"; this.beginPdfBackupsToolStripMenuItem.Text = "Begin &PDF Only Backups: {0}";
this.beginPdfBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginPdfBackupsToolStripMenuItem_Click); this.beginPdfBackupsToolStripMenuItem.Click += new System.EventHandler(this.beginPdfBackupsToolStripMenuItem_Click);
// //
// convertAllM4bToMp3ToolStripMenuItem // convertAllM4bToMp3ToolStripMenuItem
// //
this.convertAllM4bToMp3ToolStripMenuItem.Name = "convertAllM4bToMp3ToolStripMenuItem"; this.convertAllM4bToMp3ToolStripMenuItem.Name = "convertAllM4bToMp3ToolStripMenuItem";
this.convertAllM4bToMp3ToolStripMenuItem.Size = new System.Drawing.Size(293, 22); this.convertAllM4bToMp3ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
this.convertAllM4bToMp3ToolStripMenuItem.Text = "Convert all &M4b to Mp3 [Long-running]..."; this.convertAllM4bToMp3ToolStripMenuItem.Text = "Convert all &M4b to Mp3 [Long-running]...";
this.convertAllM4bToMp3ToolStripMenuItem.Click += new System.EventHandler(this.convertAllM4bToMp3ToolStripMenuItem_Click); this.convertAllM4bToMp3ToolStripMenuItem.Click += new System.EventHandler(this.convertAllM4bToMp3ToolStripMenuItem_Click);
// //
// liberateVisible2ToolStripMenuItem // liberateVisible2ToolStripMenuItem
// //
this.liberateVisible2ToolStripMenuItem.FormatText = "Liberate &Visible Books: {0}"; this.liberateVisible2ToolStripMenuItem.FormatText = "Liberate &Visible Books: {0}";
this.liberateVisible2ToolStripMenuItem.Name = "liberateVisible2ToolStripMenuItem"; this.liberateVisible2ToolStripMenuItem.Name = "liberateVisible2ToolStripMenuItem";
this.liberateVisible2ToolStripMenuItem.Size = new System.Drawing.Size(293, 22); this.liberateVisible2ToolStripMenuItem.Size = new System.Drawing.Size(293, 22);
this.liberateVisible2ToolStripMenuItem.Text = "Liberate &Visible Books: {0}"; this.liberateVisible2ToolStripMenuItem.Text = "Liberate &Visible Books: {0}";
this.liberateVisible2ToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible); this.liberateVisible2ToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
// //
// exportToolStripMenuItem // exportToolStripMenuItem
// //
this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.exportLibraryToolStripMenuItem}); this.exportLibraryToolStripMenuItem});
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem"; this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
this.exportToolStripMenuItem.Size = new System.Drawing.Size(53, 20); this.exportToolStripMenuItem.Size = new System.Drawing.Size(53, 20);
this.exportToolStripMenuItem.Text = "E&xport"; this.exportToolStripMenuItem.Text = "E&xport";
// //
// exportLibraryToolStripMenuItem // exportLibraryToolStripMenuItem
// //
this.exportLibraryToolStripMenuItem.Name = "exportLibraryToolStripMenuItem"; this.exportLibraryToolStripMenuItem.Name = "exportLibraryToolStripMenuItem";
this.exportLibraryToolStripMenuItem.Size = new System.Drawing.Size(156, 22); this.exportLibraryToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
this.exportLibraryToolStripMenuItem.Text = "E&xport Library..."; this.exportLibraryToolStripMenuItem.Text = "E&xport Library...";
this.exportLibraryToolStripMenuItem.Click += new System.EventHandler(this.exportLibraryToolStripMenuItem_Click); this.exportLibraryToolStripMenuItem.Click += new System.EventHandler(this.exportLibraryToolStripMenuItem_Click);
// //
// quickFiltersToolStripMenuItem // quickFiltersToolStripMenuItem
// //
this.quickFiltersToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.quickFiltersToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.firstFilterIsDefaultToolStripMenuItem, this.firstFilterIsDefaultToolStripMenuItem,
this.editQuickFiltersToolStripMenuItem, this.editQuickFiltersToolStripMenuItem,
this.toolStripSeparator1}); this.toolStripSeparator1});
this.quickFiltersToolStripMenuItem.Name = "quickFiltersToolStripMenuItem"; this.quickFiltersToolStripMenuItem.Name = "quickFiltersToolStripMenuItem";
this.quickFiltersToolStripMenuItem.Size = new System.Drawing.Size(84, 20); this.quickFiltersToolStripMenuItem.Size = new System.Drawing.Size(84, 20);
this.quickFiltersToolStripMenuItem.Text = "Quick &Filters"; this.quickFiltersToolStripMenuItem.Text = "Quick &Filters";
// //
// firstFilterIsDefaultToolStripMenuItem // firstFilterIsDefaultToolStripMenuItem
// //
this.firstFilterIsDefaultToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.firstFilterIsDefaultToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.firstFilterIsDefaultToolStripMenuItem.Name = "firstFilterIsDefaultToolStripMenuItem"; this.firstFilterIsDefaultToolStripMenuItem.Name = "firstFilterIsDefaultToolStripMenuItem";
this.firstFilterIsDefaultToolStripMenuItem.Size = new System.Drawing.Size(256, 22); this.firstFilterIsDefaultToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.firstFilterIsDefaultToolStripMenuItem.Text = "Start Libation with 1st filter &Default"; this.firstFilterIsDefaultToolStripMenuItem.Text = "Start Libation with 1st filter &Default";
this.firstFilterIsDefaultToolStripMenuItem.Click += new System.EventHandler(this.firstFilterIsDefaultToolStripMenuItem_Click); this.firstFilterIsDefaultToolStripMenuItem.Click += new System.EventHandler(this.firstFilterIsDefaultToolStripMenuItem_Click);
// //
// editQuickFiltersToolStripMenuItem // editQuickFiltersToolStripMenuItem
// //
this.editQuickFiltersToolStripMenuItem.Name = "editQuickFiltersToolStripMenuItem"; this.editQuickFiltersToolStripMenuItem.Name = "editQuickFiltersToolStripMenuItem";
this.editQuickFiltersToolStripMenuItem.Size = new System.Drawing.Size(256, 22); this.editQuickFiltersToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.editQuickFiltersToolStripMenuItem.Text = "&Edit quick filters..."; this.editQuickFiltersToolStripMenuItem.Text = "&Edit quick filters...";
this.editQuickFiltersToolStripMenuItem.Click += new System.EventHandler(this.editQuickFiltersToolStripMenuItem_Click); this.editQuickFiltersToolStripMenuItem.Click += new System.EventHandler(this.editQuickFiltersToolStripMenuItem_Click);
// //
// toolStripSeparator1 // toolStripSeparator1
// //
this.toolStripSeparator1.Name = "toolStripSeparator1"; this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(253, 6); this.toolStripSeparator1.Size = new System.Drawing.Size(253, 6);
// //
// scanningToolStripMenuItem // scanningToolStripMenuItem
// //
this.scanningToolStripMenuItem.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right; this.scanningToolStripMenuItem.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.scanningToolStripMenuItem.Enabled = false; this.scanningToolStripMenuItem.Enabled = false;
this.scanningToolStripMenuItem.Image = global::LibationWinForms.Properties.Resources.import_16x16; this.scanningToolStripMenuItem.Image = global::LibationWinForms.Properties.Resources.import_16x16;
this.scanningToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; this.scanningToolStripMenuItem.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None;
this.scanningToolStripMenuItem.Name = "scanningToolStripMenuItem"; this.scanningToolStripMenuItem.Name = "scanningToolStripMenuItem";
this.scanningToolStripMenuItem.Size = new System.Drawing.Size(93, 20); this.scanningToolStripMenuItem.Size = new System.Drawing.Size(93, 20);
this.scanningToolStripMenuItem.Text = "Scanning..."; this.scanningToolStripMenuItem.Text = "Scanning...";
this.scanningToolStripMenuItem.Visible = false; this.scanningToolStripMenuItem.Visible = false;
// //
// visibleBooksToolStripMenuItem // visibleBooksToolStripMenuItem
// //
this.visibleBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.visibleBooksToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.liberateVisibleToolStripMenuItem, this.liberateVisibleToolStripMenuItem,
this.replaceTagsToolStripMenuItem, this.replaceTagsToolStripMenuItem,
this.setDownloadedToolStripMenuItem, this.setDownloadedToolStripMenuItem,
this.removeToolStripMenuItem}); this.removeToolStripMenuItem});
this.visibleBooksToolStripMenuItem.FormatText = "&Visible Books: {0}"; this.visibleBooksToolStripMenuItem.FormatText = "&Visible Books: {0}";
this.visibleBooksToolStripMenuItem.Name = "visibleBooksToolStripMenuItem"; this.visibleBooksToolStripMenuItem.Name = "visibleBooksToolStripMenuItem";
this.visibleBooksToolStripMenuItem.Size = new System.Drawing.Size(108, 20); this.visibleBooksToolStripMenuItem.Size = new System.Drawing.Size(108, 20);
this.visibleBooksToolStripMenuItem.Text = "&Visible Books: {0}"; this.visibleBooksToolStripMenuItem.Text = "&Visible Books: {0}";
// //
// liberateVisibleToolStripMenuItem // liberateVisibleToolStripMenuItem
// //
this.liberateVisibleToolStripMenuItem.FormatText = "&Liberate: {0}"; this.liberateVisibleToolStripMenuItem.FormatText = "&Liberate: {0}";
this.liberateVisibleToolStripMenuItem.Name = "liberateVisibleToolStripMenuItem"; this.liberateVisibleToolStripMenuItem.Name = "liberateVisibleToolStripMenuItem";
this.liberateVisibleToolStripMenuItem.Size = new System.Drawing.Size(209, 22); this.liberateVisibleToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.liberateVisibleToolStripMenuItem.Text = "&Liberate: {0}"; this.liberateVisibleToolStripMenuItem.Text = "&Liberate: {0}";
this.liberateVisibleToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible); this.liberateVisibleToolStripMenuItem.Click += new System.EventHandler(this.liberateVisible);
// //
// replaceTagsToolStripMenuItem // replaceTagsToolStripMenuItem
// //
this.replaceTagsToolStripMenuItem.Name = "replaceTagsToolStripMenuItem"; this.replaceTagsToolStripMenuItem.Name = "replaceTagsToolStripMenuItem";
this.replaceTagsToolStripMenuItem.Size = new System.Drawing.Size(209, 22); this.replaceTagsToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.replaceTagsToolStripMenuItem.Text = "Replace &Tags..."; this.replaceTagsToolStripMenuItem.Text = "Replace &Tags...";
this.replaceTagsToolStripMenuItem.Click += new System.EventHandler(this.replaceTagsToolStripMenuItem_Click); this.replaceTagsToolStripMenuItem.Click += new System.EventHandler(this.replaceTagsToolStripMenuItem_Click);
// //
// setDownloadedToolStripMenuItem // setDownloadedToolStripMenuItem
// //
this.setDownloadedToolStripMenuItem.Name = "setDownloadedToolStripMenuItem"; this.setDownloadedToolStripMenuItem.Name = "setDownloadedToolStripMenuItem";
this.setDownloadedToolStripMenuItem.Size = new System.Drawing.Size(209, 22); this.setDownloadedToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.setDownloadedToolStripMenuItem.Text = "Set \'&Downloaded\' status..."; this.setDownloadedToolStripMenuItem.Text = "Set \'&Downloaded\' status...";
this.setDownloadedToolStripMenuItem.Click += new System.EventHandler(this.setDownloadedToolStripMenuItem_Click); this.setDownloadedToolStripMenuItem.Click += new System.EventHandler(this.setDownloadedToolStripMenuItem_Click);
// //
// removeToolStripMenuItem // removeToolStripMenuItem
// //
this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
this.removeToolStripMenuItem.Size = new System.Drawing.Size(209, 22); this.removeToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.removeToolStripMenuItem.Text = "&Remove from library..."; this.removeToolStripMenuItem.Text = "&Remove from library...";
this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click);
// //
// settingsToolStripMenuItem // settingsToolStripMenuItem
// //
this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.settingsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.accountsToolStripMenuItem, this.accountsToolStripMenuItem,
this.basicSettingsToolStripMenuItem, this.basicSettingsToolStripMenuItem,
this.toolStripSeparator2, this.toolStripSeparator2,
this.aboutToolStripMenuItem}); this.aboutToolStripMenuItem});
this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20); this.settingsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
this.settingsToolStripMenuItem.Text = "&Settings"; this.settingsToolStripMenuItem.Text = "&Settings";
// //
// accountsToolStripMenuItem // accountsToolStripMenuItem
// //
this.accountsToolStripMenuItem.Name = "accountsToolStripMenuItem"; this.accountsToolStripMenuItem.Name = "accountsToolStripMenuItem";
this.accountsToolStripMenuItem.Size = new System.Drawing.Size(133, 22); this.accountsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.accountsToolStripMenuItem.Text = "&Accounts..."; this.accountsToolStripMenuItem.Text = "&Accounts...";
this.accountsToolStripMenuItem.Click += new System.EventHandler(this.accountsToolStripMenuItem_Click); this.accountsToolStripMenuItem.Click += new System.EventHandler(this.accountsToolStripMenuItem_Click);
// //
// basicSettingsToolStripMenuItem // basicSettingsToolStripMenuItem
// //
this.basicSettingsToolStripMenuItem.Name = "basicSettingsToolStripMenuItem"; this.basicSettingsToolStripMenuItem.Name = "basicSettingsToolStripMenuItem";
this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(133, 22); this.basicSettingsToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.basicSettingsToolStripMenuItem.Text = "&Settings..."; this.basicSettingsToolStripMenuItem.Text = "&Settings...";
this.basicSettingsToolStripMenuItem.Click += new System.EventHandler(this.basicSettingsToolStripMenuItem_Click); this.basicSettingsToolStripMenuItem.Click += new System.EventHandler(this.basicSettingsToolStripMenuItem_Click);
// //
// toolStripSeparator2 // toolStripSeparator2
// //
this.toolStripSeparator2.Name = "toolStripSeparator2"; this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(130, 6); this.toolStripSeparator2.Size = new System.Drawing.Size(130, 6);
// //
// aboutToolStripMenuItem // aboutToolStripMenuItem
// //
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(133, 22); this.aboutToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.aboutToolStripMenuItem.Text = "A&bout..."; this.aboutToolStripMenuItem.Text = "A&bout...";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
// //
// statusStrip1 // statusStrip1
// //
this.statusStrip1.ImageScalingSize = new System.Drawing.Size(40, 40); this.statusStrip1.ImageScalingSize = new System.Drawing.Size(40, 40);
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.visibleCountLbl, this.visibleCountLbl,
this.springLbl, this.springLbl,
this.backupsCountsLbl, this.backupsCountsLbl,
this.pdfsCountsLbl}); this.pdfsCountsLbl});
this.statusStrip1.Location = new System.Drawing.Point(0, 618); this.statusStrip1.Location = new System.Drawing.Point(0, 618);
this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0); this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 16, 0);
this.statusStrip1.Size = new System.Drawing.Size(893, 22); this.statusStrip1.Size = new System.Drawing.Size(1061, 22);
this.statusStrip1.TabIndex = 6; this.statusStrip1.TabIndex = 6;
this.statusStrip1.Text = "statusStrip1"; this.statusStrip1.Text = "statusStrip1";
// //
// visibleCountLbl // visibleCountLbl
// //
this.visibleCountLbl.FormatText = "Visible: {0}"; this.visibleCountLbl.FormatText = "Visible: {0}";
this.visibleCountLbl.Name = "visibleCountLbl"; this.visibleCountLbl.Name = "visibleCountLbl";
this.visibleCountLbl.Size = new System.Drawing.Size(61, 17); this.visibleCountLbl.Size = new System.Drawing.Size(61, 17);
this.visibleCountLbl.Text = "Visible: {0}"; this.visibleCountLbl.Text = "Visible: {0}";
// //
// springLbl // springLbl
// //
this.springLbl.Name = "springLbl"; this.springLbl.Name = "springLbl";
this.springLbl.Size = new System.Drawing.Size(379, 17); this.springLbl.Size = new System.Drawing.Size(547, 17);
this.springLbl.Spring = true; this.springLbl.Spring = true;
// //
// backupsCountsLbl // backupsCountsLbl
// //
this.backupsCountsLbl.Name = "backupsCountsLbl"; this.backupsCountsLbl.Name = "backupsCountsLbl";
this.backupsCountsLbl.Size = new System.Drawing.Size(218, 17); this.backupsCountsLbl.Size = new System.Drawing.Size(218, 17);
this.backupsCountsLbl.Text = "[Calculating backed up book quantities]"; this.backupsCountsLbl.Text = "[Calculating backed up book quantities]";
// //
// pdfsCountsLbl // pdfsCountsLbl
// //
this.pdfsCountsLbl.FormatText = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}"; this.pdfsCountsLbl.FormatText = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
this.pdfsCountsLbl.Name = "pdfsCountsLbl"; this.pdfsCountsLbl.Name = "pdfsCountsLbl";
this.pdfsCountsLbl.Size = new System.Drawing.Size(218, 17); this.pdfsCountsLbl.Size = new System.Drawing.Size(218, 17);
this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}"; this.pdfsCountsLbl.Text = "| PDFs: NOT d/l\'ed: {0} Downloaded: {1}";
// //
// addQuickFilterBtn // addQuickFilterBtn
// //
this.addQuickFilterBtn.Location = new System.Drawing.Point(50, 3); this.addQuickFilterBtn.Location = new System.Drawing.Point(50, 3);
this.addQuickFilterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.addQuickFilterBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.addQuickFilterBtn.Name = "addQuickFilterBtn"; this.addQuickFilterBtn.Name = "addQuickFilterBtn";
this.addQuickFilterBtn.Size = new System.Drawing.Size(137, 27); this.addQuickFilterBtn.Size = new System.Drawing.Size(137, 27);
this.addQuickFilterBtn.TabIndex = 4; this.addQuickFilterBtn.TabIndex = 4;
this.addQuickFilterBtn.Text = "Add To Quick Filters"; this.addQuickFilterBtn.Text = "Add To Quick Filters";
this.addQuickFilterBtn.UseVisualStyleBackColor = true; this.addQuickFilterBtn.UseVisualStyleBackColor = true;
this.addQuickFilterBtn.Click += new System.EventHandler(this.addQuickFilterBtn_Click); this.addQuickFilterBtn.Click += new System.EventHandler(this.addQuickFilterBtn_Click);
// //
// splitContainer1 // splitContainer1
// //
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0); this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Name = "splitContainer1";
// //
// splitContainer1.Panel1 // splitContainer1.Panel1
// //
this.splitContainer1.Panel1.Controls.Add(this.panel1); this.splitContainer1.Panel1.Controls.Add(this.panel1);
this.splitContainer1.Panel1.Controls.Add(this.menuStrip1); this.splitContainer1.Panel1.Controls.Add(this.menuStrip1);
this.splitContainer1.Panel1.Controls.Add(this.statusStrip1); this.splitContainer1.Panel1.Controls.Add(this.statusStrip1);
// //
// splitContainer1.Panel2 // splitContainer1.Panel2
// //
this.splitContainer1.Panel2.Controls.Add(this.processBookQueue1); this.splitContainer1.Panel2.Controls.Add(this.processBookQueue1);
this.splitContainer1.Size = new System.Drawing.Size(1231, 640); this.splitContainer1.Size = new System.Drawing.Size(1463, 640);
this.splitContainer1.SplitterDistance = 893; this.splitContainer1.SplitterDistance = 1061;
this.splitContainer1.SplitterWidth = 8; this.splitContainer1.SplitterWidth = 8;
this.splitContainer1.TabIndex = 7; this.splitContainer1.TabIndex = 7;
// //
// panel1 // panel1
// //
this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.panel1.Controls.Add(this.toggleQueueHideBtn); this.panel1.Controls.Add(this.productsDisplay);
this.panel1.Controls.Add(this.gridPanel); this.panel1.Controls.Add(this.toggleQueueHideBtn);
this.panel1.Controls.Add(this.addQuickFilterBtn); this.panel1.Controls.Add(this.addQuickFilterBtn);
this.panel1.Controls.Add(this.filterHelpBtn); this.panel1.Controls.Add(this.filterHelpBtn);
this.panel1.Controls.Add(this.filterSearchTb); this.panel1.Controls.Add(this.filterSearchTb);
this.panel1.Controls.Add(this.filterBtn); this.panel1.Controls.Add(this.filterBtn);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 24); this.panel1.Location = new System.Drawing.Point(0, 24);
this.panel1.Margin = new System.Windows.Forms.Padding(0); this.panel1.Margin = new System.Windows.Forms.Padding(0);
this.panel1.Name = "panel1"; this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(893, 594); this.panel1.Size = new System.Drawing.Size(1061, 594);
this.panel1.TabIndex = 7; this.panel1.TabIndex = 7;
// //
// toggleQueueHideBtn // productsDisplay
// //
this.toggleQueueHideBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.productsDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
this.toggleQueueHideBtn.Location = new System.Drawing.Point(845, 3); | System.Windows.Forms.AnchorStyles.Left)
this.toggleQueueHideBtn.Margin = new System.Windows.Forms.Padding(4, 3, 15, 3); | System.Windows.Forms.AnchorStyles.Right)));
this.toggleQueueHideBtn.Name = "toggleQueueHideBtn"; this.productsDisplay.AutoScroll = true;
this.toggleQueueHideBtn.Size = new System.Drawing.Size(33, 27); this.productsDisplay.Location = new System.Drawing.Point(15, 36);
this.toggleQueueHideBtn.TabIndex = 8; this.productsDisplay.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.toggleQueueHideBtn.Text = "❱❱❱"; this.productsDisplay.Name = "productsDisplay";
this.toggleQueueHideBtn.UseVisualStyleBackColor = true; this.productsDisplay.Size = new System.Drawing.Size(1031, 555);
this.toggleQueueHideBtn.Click += new System.EventHandler(this.ToggleQueueHideBtn_Click); this.productsDisplay.TabIndex = 9;
// this.productsDisplay.VisibleCountChanged += new System.EventHandler<int>(this.productsDisplay_VisibleCountChanged);
// processBookQueue1 this.productsDisplay.LiberateClicked += new System.EventHandler<DataLayer.LibraryBook>(this.ProductsDisplay_LiberateClicked);
// this.productsDisplay.InitialLoaded += new System.EventHandler(this.productsDisplay_InitialLoaded);
this.processBookQueue1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; //
this.processBookQueue1.Dock = System.Windows.Forms.DockStyle.Fill; // toggleQueueHideBtn
this.processBookQueue1.Location = new System.Drawing.Point(0, 0); //
this.processBookQueue1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); this.toggleQueueHideBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.processBookQueue1.Name = "processBookQueue1"; this.toggleQueueHideBtn.Location = new System.Drawing.Point(1013, 3);
this.processBookQueue1.Size = new System.Drawing.Size(330, 640); this.toggleQueueHideBtn.Margin = new System.Windows.Forms.Padding(4, 3, 15, 3);
this.processBookQueue1.TabIndex = 0; this.toggleQueueHideBtn.Name = "toggleQueueHideBtn";
// this.toggleQueueHideBtn.Size = new System.Drawing.Size(33, 27);
// Form1 this.toggleQueueHideBtn.TabIndex = 8;
// this.toggleQueueHideBtn.Text = "❱❱❱";
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.toggleQueueHideBtn.UseVisualStyleBackColor = true;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.toggleQueueHideBtn.Click += new System.EventHandler(this.ToggleQueueHideBtn_Click);
this.ClientSize = new System.Drawing.Size(1231, 640); //
this.Controls.Add(this.splitContainer1); // processBookQueue1
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); //
this.MainMenuStrip = this.menuStrip1; this.processBookQueue1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.processBookQueue1.Dock = System.Windows.Forms.DockStyle.Fill;
this.Name = "Form1"; this.processBookQueue1.Location = new System.Drawing.Point(0, 0);
this.Text = "Libation: Liberate your Library"; this.processBookQueue1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.Load += new System.EventHandler(this.Form1_Load); this.processBookQueue1.Name = "processBookQueue1";
this.menuStrip1.ResumeLayout(false); this.processBookQueue1.Size = new System.Drawing.Size(394, 640);
this.menuStrip1.PerformLayout(); this.processBookQueue1.TabIndex = 0;
this.statusStrip1.ResumeLayout(false); //
this.statusStrip1.PerformLayout(); // Form1
this.splitContainer1.Panel1.ResumeLayout(false); //
this.splitContainer1.Panel1.PerformLayout(); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.splitContainer1.Panel2.ResumeLayout(false); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.ClientSize = new System.Drawing.Size(1463, 640);
this.splitContainer1.ResumeLayout(false); this.Controls.Add(this.splitContainer1);
this.panel1.ResumeLayout(false); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.panel1.PerformLayout(); this.MainMenuStrip = this.menuStrip1;
this.ResumeLayout(false); this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "Form1";
this.Text = "Libation: Liberate your Library";
this.Load += new System.EventHandler(this.Form1_Load);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
} }
#endregion #endregion
private System.Windows.Forms.Panel gridPanel;
private System.Windows.Forms.MenuStrip menuStrip1; private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem importToolStripMenuItem;
private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.StatusStrip statusStrip1;
@ -581,5 +583,6 @@
private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1; private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button toggleQueueHideBtn; private System.Windows.Forms.Button toggleQueueHideBtn;
private LibationWinForms.GridView.ProductsDisplay productsDisplay;
} }
} }

View File

@ -30,7 +30,7 @@ namespace LibationWinForms
try try
{ {
productsGrid.Filter(filterString); productsDisplay.Filter(filterString);
lastGoodFilter = filterString; lastGoodFilter = filterString;
} }
catch (Exception ex) catch (Exception ex)

View File

@ -12,6 +12,7 @@ namespace LibationWinForms
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));
PictureStorage.SetDefaultImage(PictureSize._500x500, Properties.Resources.default_cover_500x500.ToBytes(format)); PictureStorage.SetDefaultImage(PictureSize._500x500, Properties.Resources.default_cover_500x500.ToBytes(format));
PictureStorage.SetDefaultImage(PictureSize.Native, Properties.Resources.default_cover_500x500.ToBytes(format));
} }
} }
} }

View File

@ -14,14 +14,13 @@ namespace LibationWinForms
int WidthChange = 0; int WidthChange = 0;
private void Configure_ProcessQueue() private void Configure_ProcessQueue()
{ {
productsGrid.LiberateClicked += ProductsGrid_LiberateClicked;
processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut; processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut;
var coppalseState = Configuration.Instance.GetNonString<bool>(nameof(splitContainer1.Panel2Collapsed)); var coppalseState = Configuration.Instance.GetNonString<bool>(nameof(splitContainer1.Panel2Collapsed));
WidthChange = splitContainer1.Panel2.Width + splitContainer1.SplitterWidth; WidthChange = splitContainer1.Panel2.Width + splitContainer1.SplitterWidth;
SetQueueCollapseState(coppalseState); SetQueueCollapseState(coppalseState);
} }
private void ProductsGrid_LiberateClicked(object sender, LibraryBook e) private void ProductsDisplay_LiberateClicked(object sender, LibraryBook e)
{ {
if (e.Book.UserDefinedItem.BookStatus != LiberatedStatus.Liberated) if (e.Book.UserDefinedItem.BookStatus != LiberatedStatus.Liberated)
{ {

View File

@ -14,12 +14,6 @@ namespace LibationWinForms
Load += updateFiltersMenu; Load += updateFiltersMenu;
QuickFilters.UseDefaultChanged += updateFirstFilterIsDefaultToolStripMenuItem; QuickFilters.UseDefaultChanged += updateFirstFilterIsDefaultToolStripMenuItem;
QuickFilters.Updated += updateFiltersMenu; QuickFilters.Updated += updateFiltersMenu;
productsGrid.InitialLoaded += (_, __) =>
{
if (QuickFilters.UseDefault)
performFilter(QuickFilters.Filters.FirstOrDefault());
};
} }
private object quickFilterTag { get; } = new(); private object quickFilterTag { get; } = new();
@ -56,5 +50,11 @@ namespace LibationWinForms
private void addQuickFilterBtn_Click(object sender, EventArgs e) => QuickFilters.Add(this.filterSearchTb.Text); private void addQuickFilterBtn_Click(object sender, EventArgs e) => QuickFilters.Add(this.filterSearchTb.Text);
private void editQuickFiltersToolStripMenuItem_Click(object sender, EventArgs e) => new EditQuickFilters().ShowDialog(); private void editQuickFiltersToolStripMenuItem_Click(object sender, EventArgs e) => new EditQuickFilters().ShowDialog();
private void productsDisplay_InitialLoaded(object sender, EventArgs e)
{
if (QuickFilters.UseDefault)
performFilter(QuickFilters.Filters.FirstOrDefault());
}
} }
} }

View File

@ -17,28 +17,16 @@ namespace LibationWinForms
liberateVisibleToolStripMenuItem.Format(0); liberateVisibleToolStripMenuItem.Format(0);
liberateVisible2ToolStripMenuItem.Format(0); liberateVisible2ToolStripMenuItem.Format(0);
// bottom-left visible count
productsGrid.VisibleCountChanged += (_, qty) => visibleCountLbl.Format(qty);
// top menu strip // top menu strip
visibleBooksToolStripMenuItem.Format(0); visibleBooksToolStripMenuItem.Format(0);
productsGrid.VisibleCountChanged += (_, qty) => {
visibleBooksToolStripMenuItem.Format(qty);
visibleBooksToolStripMenuItem.Enabled = qty > 0;
var notLiberatedCount = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
};
productsGrid.VisibleCountChanged += setLiberatedVisibleMenuItemAsync;
LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync; LibraryCommands.BookUserDefinedItemCommitted += setLiberatedVisibleMenuItemAsync;
} }
private async void setLiberatedVisibleMenuItemAsync(object _, int __)
=> await Task.Run(setLiberatedVisibleMenuItem);
private async void setLiberatedVisibleMenuItemAsync(object _, EventArgs __) private async void setLiberatedVisibleMenuItemAsync(object _, EventArgs __)
=> await Task.Run(setLiberatedVisibleMenuItem); => await Task.Run(setLiberatedVisibleMenuItem);
void setLiberatedVisibleMenuItem() void setLiberatedVisibleMenuItem()
{ {
var notLiberated = productsGrid.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated); var notLiberated = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
this.UIThreadSync(() => this.UIThreadSync(() =>
{ {
if (notLiberated > 0) if (notLiberated > 0)
@ -63,7 +51,7 @@ namespace LibationWinForms
private async void liberateVisible(object sender, EventArgs e) private async void liberateVisible(object sender, EventArgs e)
{ {
SetQueueCollapseState(false); SetQueueCollapseState(false);
await Task.Run(() => processBookQueue1.AddDownloadDecrypt(productsGrid.GetVisible())); await Task.Run(() => processBookQueue1.AddDownloadDecrypt(productsDisplay.GetVisible()));
} }
private void replaceTagsToolStripMenuItem_Click(object sender, EventArgs e) private void replaceTagsToolStripMenuItem_Click(object sender, EventArgs e)
@ -73,7 +61,7 @@ namespace LibationWinForms
if (result != DialogResult.OK) if (result != DialogResult.OK)
return; return;
var visibleLibraryBooks = productsGrid.GetVisible(); var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog( var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks, visibleLibraryBooks,
@ -95,7 +83,7 @@ namespace LibationWinForms
if (result != DialogResult.OK) if (result != DialogResult.OK)
return; return;
var visibleLibraryBooks = productsGrid.GetVisible(); var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog( var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks, visibleLibraryBooks,
@ -112,7 +100,7 @@ namespace LibationWinForms
private async void removeToolStripMenuItem_Click(object sender, EventArgs e) private async void removeToolStripMenuItem_Click(object sender, EventArgs e)
{ {
var visibleLibraryBooks = productsGrid.GetVisible(); var visibleLibraryBooks = productsDisplay.GetVisible();
var confirmationResult = MessageBoxLib.ShowConfirmationDialog( var confirmationResult = MessageBoxLib.ShowConfirmationDialog(
visibleLibraryBooks, visibleLibraryBooks,
@ -125,5 +113,20 @@ namespace LibationWinForms
var visibleIds = visibleLibraryBooks.Select(lb => lb.Book.AudibleProductId).ToList(); var visibleIds = visibleLibraryBooks.Select(lb => lb.Book.AudibleProductId).ToList();
await LibraryCommands.RemoveBooksAsync(visibleIds); await LibraryCommands.RemoveBooksAsync(visibleIds);
} }
private async void productsDisplay_VisibleCountChanged(object sender, int qty)
{
// bottom-left visible count
visibleCountLbl.Format(qty);
// top menu strip
visibleBooksToolStripMenuItem.Format(qty);
visibleBooksToolStripMenuItem.Enabled = qty > 0;
//Not used for anything?
var notLiberatedCount = productsDisplay.GetVisible().Count(lb => lb.Book.UserDefinedItem.BookStatus == DataLayer.LiberatedStatus.NotLiberated);
await Task.Run(setLiberatedVisibleMenuItem);
}
} }
} }

View File

@ -12,24 +12,10 @@ namespace LibationWinForms
{ {
public partial class Form1 : Form public partial class Form1 : Form
{ {
private ProductsGrid productsGrid { get; }
public Form1() public Form1()
{ {
InitializeComponent(); InitializeComponent();
if (this.DesignMode)
return;
{
// I'd actually like these lines to be handled in the designer, but I'm currently getting this error when I try:
// Failed to create component 'ProductsGrid'. The error message follows:
// 'Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Object reference not set to an instance of an object.
// Since the designer's choking on it, I'm keeping it below the DesignMode check to be safe
productsGrid = new ProductsGrid { Dock = DockStyle.Fill };
gridPanel.Controls.Add(productsGrid);
}
// Pre-requisite: // Pre-requisite:
// Before calling anything else, including subscribing to events, ensure database exists. If we wait and let it happen lazily, race conditions and errors are likely during new installs // Before calling anything else, including subscribing to events, ensure database exists. If we wait and let it happen lazily, race conditions and errors are likely during new installs
using var _ = DbContexts.GetContext(); using var _ = DbContexts.GetContext();
@ -67,8 +53,8 @@ namespace LibationWinForms
// Configure_Grid(); // since it's just this, can keep here. If it needs more, then give grid it's own 'partial class Form1' // Configure_Grid(); // since it's just this, can keep here. If it needs more, then give grid it's own 'partial class Form1'
{ {
this.Load += (_, __) => productsGrid.Display(); this.Load += (_, __) => productsDisplay.Display();
LibraryCommands.LibrarySizeChanged += (_, __) => this.UIThreadAsync(() => productsGrid.Display()); LibraryCommands.LibrarySizeChanged += (_, __) => this.UIThreadAsync(() => productsDisplay.Display());
} }
} }

View File

@ -57,12 +57,48 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="filterHelpBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="filterBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="filterSearchTb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="menuStrip1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>132, 17</value> <value>132, 17</value>
</metadata> </metadata>
<metadata name="statusStrip1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="addQuickFilterBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="splitContainer1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="panel1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="productsDisplay.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="toggleQueueHideBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="processBookQueue1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>

View File

@ -2,7 +2,7 @@
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public abstract class AsyncNotifyPropertyChanged : SynchronizeInvoker, INotifyPropertyChanged public abstract class AsyncNotifyPropertyChanged : SynchronizeInvoker, INotifyPropertyChanged
{ {

View File

@ -1,7 +1,7 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public class DataGridViewImageButtonCell : DataGridViewButtonCell public class DataGridViewImageButtonCell : DataGridViewButtonCell
{ {

View File

@ -1,4 +1,4 @@
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
partial class DescriptionDisplay partial class DescriptionDisplay
{ {

View File

@ -1,17 +1,15 @@
using System; using System;
using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public partial class DescriptionDisplay : Form public partial class DescriptionDisplay : Form
{ {
private int borderThickness = 5; private int borderThickness = 5;
public int BorderThickness public int BorderThickness
{ {
get => borderThickness; get => borderThickness;
set set

View File

@ -1,7 +1,8 @@
using System.Drawing; using Dinah.Core.Windows.Forms;
using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public class EditTagsDataGridViewImageButtonColumn : DataGridViewButtonColumn public class EditTagsDataGridViewImageButtonColumn : DataGridViewButtonColumn
{ {
@ -18,6 +19,12 @@ namespace LibationWinForms
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 (rowIndex >= 0 && DataGridView.GetBoundItem<GridEntry>(rowIndex) is SeriesEntry)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
return;
}
var tagsString = (string)value; var tagsString = (string)value;
var foreColor = tagsString?.Contains("hidden") == true ? HiddenForeColor : DataGridView.DefaultCellStyle.ForeColor; var foreColor = tagsString?.Contains("hidden") == true ? HiddenForeColor : DataGridView.DefaultCellStyle.ForeColor;

View File

@ -0,0 +1,113 @@
using DataLayer;
using Dinah.Core.DataBinding;
using Dinah.Core.Drawing;
using LibationFileManager;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace LibationWinForms.GridView
{
public abstract class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
{
protected abstract Book Book { get; }
private Image _cover;
#region Model properties exposed to the view
public Image Cover
{
get => _cover;
protected set
{
_cover = value;
NotifyPropertyChanged();
}
}
public new bool InvokeRequired => base.InvokeRequired;
public abstract DateTime DateAdded { get; }
public abstract float SeriesIndex { get; }
public abstract string ProductRating { get; protected set; }
public abstract string PurchaseDate { get; protected set; }
public abstract string MyRating { get; protected set; }
public abstract string Series { get; protected set; }
public abstract string Title { get; protected set; }
public abstract string Length { get; protected set; }
public abstract string Authors { get; protected set; }
public abstract string Narrators { get; protected set; }
public abstract string Category { get; protected set; }
public abstract string Misc { get; protected set; }
public abstract string Description { get; protected set; }
public abstract string DisplayTags { get; }
public abstract LiberateButtonStatus Liberate { get; }
#endregion
#region Sorting
public GridEntry() => _memberValues = CreateMemberValueDictionary();
private Dictionary<string, Func<object>> _memberValues { get; set; }
protected abstract Dictionary<string, Func<object>> CreateMemberValueDictionary();
// These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
// Used by GridEntryBindingList for all sorting
public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
public IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
#endregion
protected void LoadCover()
{
// Get cover art. If it's default, subscribe to PictureCached
{
(bool isDefault, byte[] picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80));
if (isDefault)
PictureStorage.PictureCached += PictureStorage_PictureCached;
// Mutable property. Set the field so PropertyChanged isn't fired.
_cover = ImageReader.ToImage(picture);
}
}
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)
{
if (e.Definition.PictureId == Book.PictureId)
{
Cover = ImageReader.ToImage(e.Picture);
PictureStorage.PictureCached -= PictureStorage_PictureCached;
}
}
// Instantiate comparers for every exposed member object type.
private static readonly Dictionary<Type, IComparer> _memberTypeComparers = new()
{
{ typeof(string), new ObjectComparer<string>() },
{ typeof(int), new ObjectComparer<int>() },
{ typeof(float), new ObjectComparer<float>() },
{ typeof(bool), new ObjectComparer<bool>() },
{ typeof(DateTime), new ObjectComparer<DateTime>() },
{ typeof(LiberateButtonStatus), new ObjectComparer<LiberateButtonStatus>() },
};
~GridEntry()
{
PictureStorage.PictureCached -= PictureStorage_PictureCached;
}
}
internal static class GridEntryExtensions
{
#nullable enable
public static IEnumerable<SeriesEntry> Series(this IEnumerable<GridEntry> gridEntries)
=> gridEntries.Where(i => i is SeriesEntry).Cast<SeriesEntry>();
public static IEnumerable<LibraryBookEntry> LibraryBooks(this IEnumerable<GridEntry> gridEntries)
=> gridEntries.Where(i => i is LibraryBookEntry).Cast<LibraryBookEntry>();
public static LibraryBookEntry? FindBookByAsin(this IEnumerable<LibraryBookEntry> gridEntries, string audibleProductID)
=> gridEntries.FirstOrDefault(i => i.AudibleProductId == audibleProductID);
public static SeriesEntry? FindBookSeriesEntry(this IEnumerable<GridEntry> gridEntries, IEnumerable<SeriesBook> matchSeries)
=> gridEntries.Series().FirstOrDefault(i => matchSeries.Any(s => s.Series.Name == i.Series));
public static IEnumerable<SeriesEntry> EmptySeries(this IEnumerable<GridEntry> gridEntries)
=> gridEntries.Series().Where(i => i.Children.Count == 0);
}
}

View File

@ -0,0 +1,231 @@
using ApplicationServices;
using Dinah.Core.DataBinding;
using LibationSearchEngine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace LibationWinForms.GridView
{
/*
* Allows filtering and sorting of the underlying BindingList<GridEntry>
* by implementing IBindingListView and using SearchEngineCommands
*
* When filtering is applied, the filtered-out items are removed
* from the base list and added to the private FilterRemoved list.
* When filtering is removed, items in the FilterRemoved list are
* added back to the base list.
*
* Remove is overridden to ensure that removed items are removed from
* the base list (visible items) as well as the FilterRemoved list.
*/
internal class GridEntryBindingList : BindingList<GridEntry>, IBindingListView
{
public GridEntryBindingList() : base(new List<GridEntry>()) { }
public GridEntryBindingList(IEnumerable<GridEntry> enumeration) : base(new List<GridEntry>(enumeration)) { }
/// <returns>All items in the list, including those filtered out.</returns>
public List<GridEntry> AllItems() => Items.Concat(FilterRemoved).ToList();
public bool SupportsFiltering => true;
public string Filter { get => FilterString; set => ApplyFilter(value); }
protected MemberComparer<GridEntry> Comparer { get; } = new();
protected override bool SupportsSortingCore => true;
protected override bool SupportsSearchingCore => true;
protected override bool IsSortedCore => isSorted;
protected override PropertyDescriptor SortPropertyCore => propertyDescriptor;
protected override ListSortDirection SortDirectionCore => listSortDirection;
/// <summary> Items that were removed from the base list due to filtering </summary>
private readonly List<GridEntry> FilterRemoved = new();
private string FilterString;
private SearchResultSet SearchResults;
private bool isSorted;
private ListSortDirection listSortDirection;
private PropertyDescriptor propertyDescriptor;
#region Unused - Advanced Filtering
public bool SupportsAdvancedSorting => false;
//This ApplySort overload is only called if SupportsAdvancedSorting is true.
//Otherwise BindingList.ApplySort() is used
public void ApplySort(ListSortDescriptionCollection sorts) => throw new NotImplementedException();
public ListSortDescriptionCollection SortDescriptions => throw new NotImplementedException();
#endregion
public new void Remove(GridEntry entry)
{
FilterRemoved.Remove(entry);
base.Remove(entry);
}
private void ApplyFilter(string filterString)
{
if (filterString != FilterString)
RemoveFilter();
FilterString = filterString;
SearchResults = SearchEngineCommands.Search(filterString);
var booksFilteredIn = Items.LibraryBooks().Join(SearchResults.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => (GridEntry)lbe);
//Find all series containing children that match the search criteria
var seriesFilteredIn = Items.Series().Where(s => s.Children.Join(SearchResults.Docs, lbe => lbe.AudibleProductId, d => d.ProductId, (lbe, d) => lbe).Any());
var filteredOut = Items.Except(booksFilteredIn.Concat(seriesFilteredIn)).ToList();
foreach (var item in filteredOut)
{
FilterRemoved.Add(item);
base.Remove(item);
}
}
public void CollapseAll()
{
foreach (var series in Items.Series().ToList())
CollapseItem(series);
}
public void ExpandAll()
{
foreach (var series in Items.Series().ToList())
ExpandItem(series);
}
public void CollapseItem(SeriesEntry sEntry)
{
foreach (var episode in Items.LibraryBooks().Where(b => b.Parent == sEntry).ToList())
{
FilterRemoved.Add(episode);
base.Remove(episode);
}
sEntry.Liberate.Expanded = false;
}
public void ExpandItem(SeriesEntry sEntry)
{
var sindex = Items.IndexOf(sEntry);
foreach (var episode in FilterRemoved.LibraryBooks().Where(b => b.Parent == sEntry).ToList())
{
if (SearchResults is null || SearchResults.Docs.Any(d => d.ProductId == episode.AudibleProductId))
{
FilterRemoved.Remove(episode);
InsertItem(++sindex, episode);
}
}
sEntry.Liberate.Expanded = true;
}
public void RemoveFilter()
{
if (FilterString is null) return;
int visibleCount = Items.Count;
foreach (var item in FilterRemoved.ToList())
{
if (item is SeriesEntry || (item is LibraryBookEntry lbe && (lbe.Parent is null || lbe.Parent.Liberate.Expanded)))
{
FilterRemoved.Remove(item);
InsertItem(visibleCount++, item);
}
}
if (IsSortedCore)
Sort();
else
//No user sort is applied, so do default sorting by DateAdded, descending
{
Comparer.PropertyName = nameof(GridEntry.DateAdded);
Comparer.Direction = ListSortDirection.Descending;
Sort();
}
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
FilterString = null;
SearchResults = null;
}
protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
{
Comparer.PropertyName = property.Name;
Comparer.Direction = direction;
Sort();
propertyDescriptor = property;
listSortDirection = direction;
isSorted = true;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
protected void Sort()
{
var itemsList = (List<GridEntry>)Items;
var children = itemsList.LibraryBooks().Where(i => i.Parent is not null).ToList();
var sortedItems = itemsList.Except(children).OrderBy(ge => ge, Comparer).ToList();
itemsList.Clear();
//Only add parentless items at this stage. After these items are added in the
//correct sorting order, go back and add the children beneath their parents.
itemsList.AddRange(sortedItems);
foreach (var parent in children.Select(c => c.Parent).Distinct())
{
var pIndex = itemsList.IndexOf(parent);
//children should always be sorted by series index.
foreach (var c in children.Where(c => c.Parent == parent).OrderBy(c => c.SeriesIndex))
itemsList.Insert(++pIndex, c);
}
}
protected override void OnListChanged(ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemChanged)
{
if (Items[e.NewIndex] is LibraryBookEntry lbItem)
{
SearchResults = SearchEngineCommands.Search(FilterString);
if (!SearchResults.Docs.Any(d => d.ProductId == lbItem.AudibleProductId))
{
FilterRemoved.Add(lbItem);
base.Remove(lbItem);
return;
}
}
if (isSorted && e.PropertyDescriptor == SortPropertyCore)
{
var item = Items[e.NewIndex];
Sort();
var newIndex = Items.IndexOf(item);
base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemMoved, newIndex, e.NewIndex));
return;
}
}
base.OnListChanged(e);
}
protected override void RemoveSortCore()
{
isSorted = false;
propertyDescriptor = base.SortPropertyCore;
listSortDirection = base.SortDirectionCore;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}
}

View File

@ -1,4 +1,4 @@
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
partial class ImageDisplay partial class ImageDisplay
{ {

View File

@ -1,11 +1,9 @@
using FileLiberator; using System;
using LibationFileManager;
using System;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public partial class ImageDisplay : Form public partial class ImageDisplay : Form
{ {

View File

@ -0,0 +1,28 @@
using DataLayer;
using System;
namespace LibationWinForms.GridView
{
public class LiberateButtonStatus : IComparable
{
public LiberatedStatus BookStatus { get; set; }
public LiberatedStatus? PdfStatus { get; set; }
public bool Expanded { get; set; }
public bool IsSeries { get; init; }
/// <summary>
/// Defines the Liberate column's sorting behavior
/// </summary>
public int CompareTo(object obj)
{
if (obj is not LiberateButtonStatus second) return -1;
if (IsSeries && !second.IsSeries) return -1;
else if (!IsSeries && second.IsSeries) return 1;
else if (IsSeries && second.IsSeries) return 0;
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

@ -1,10 +1,10 @@
using System; using DataLayer;
using Dinah.Core.Windows.Forms;
using System;
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using System.Linq;
using DataLayer;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
public class LiberateDataGridViewImageButtonColumn : DataGridViewButtonColumn public class LiberateDataGridViewImageButtonColumn : DataGridViewButtonColumn
{ {
@ -16,19 +16,35 @@ namespace LibationWinForms
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
{ {
private static readonly Color SERIES_BG_COLOR = Color.FromArgb(230, 255, 230);
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)
{ {
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);
if (value is (LiberatedStatus, LiberatedStatus) or (LiberatedStatus, null)) if (value is LiberateButtonStatus status)
{ {
var (bookState, pdfState) = ((LiberatedStatus bookState, LiberatedStatus? pdfState))value; if (rowIndex >= 0 && DataGridView.GetBoundItem<GridEntry>(rowIndex) is LibraryBookEntry lbEntry && lbEntry.Parent is not null)
{
DataGridView.Rows[rowIndex].DefaultCellStyle.BackColor = SERIES_BG_COLOR;
}
(string mouseoverText, Bitmap buttonImage) = GetLiberateDisplay(bookState, pdfState); if (status.IsSeries)
{
var imageName = status.Expanded ? "minus" : "plus";
DrawButtonImage(graphics, buttonImage, cellBounds); var bmp = (Bitmap)Properties.Resources.ResourceManager.GetObject(imageName);
DrawButtonImage(graphics, bmp, cellBounds);
ToolTipText = mouseoverText; ToolTipText = status.Expanded ? "Click to Collpase" : "Click to Expand";
}
else
{
(string mouseoverText, Bitmap buttonImage) = GetLiberateDisplay(status.BookStatus, status.PdfStatus);
DrawButtonImage(graphics, buttonImage, cellBounds);
ToolTipText = mouseoverText;
}
} }
} }

View File

@ -1,23 +1,17 @@
using System; using ApplicationServices;
using System.Collections; using DataLayer;
using Dinah.Core;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing;
using System.Linq; using System.Linq;
using ApplicationServices;
using DataLayer;
using Dinah.Core.DataBinding;
using Dinah.Core;
using Dinah.Core.Drawing;
using LibationFileManager;
using System.Threading.Tasks;
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
/// <summary> /// <summary>
/// The View Model for a LibraryBook /// The View Model for a LibraryBook
/// </summary> /// </summary>
internal class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable public class LibraryBookEntry : GridEntry
{ {
#region implementation properties NOT exposed to the view #region implementation properties NOT exposed to the view
// hide from public fields from Data Source GUI with [Browsable(false)] // hide from public fields from Data Source GUI with [Browsable(false)]
@ -30,37 +24,30 @@ namespace LibationWinForms
public string LongDescription { get; private set; } public string LongDescription { get; private set; }
#endregion #endregion
protected override Book Book => LibraryBook.Book;
#region Model properties exposed to the view #region Model properties exposed to the view
private Image _cover;
private DateTime lastStatusUpdate = default; private DateTime lastStatusUpdate = default;
private LiberatedStatus _bookStatus; private LiberatedStatus _bookStatus;
private LiberatedStatus? _pdfStatus; private LiberatedStatus? _pdfStatus;
public Image Cover
{
get => _cover;
private set
{
_cover = value;
NotifyPropertyChanged();
}
}
public string ProductRating { get; private set; } public override DateTime DateAdded => LibraryBook.DateAdded;
public string PurchaseDate { get; private set; } public override float SeriesIndex => Book.SeriesLink.FirstOrDefault()?.Index ?? 0;
public string MyRating { get; private set; } public override string ProductRating { get; protected set; }
public string Series { get; private set; } public override string PurchaseDate { get; protected set; }
public string Title { get; private set; } public override string MyRating { get; protected set; }
public string Length { get; private set; } public override string Series { get; protected set; }
public string Authors { get; private set; } public override string Title { get; protected set; }
public string Narrators { get; private set; } public override string Length { get; protected set; }
public string Category { get; private set; } public override string Authors { get; protected set; }
public string Misc { get; private set; } public override string Narrators { get; protected set; }
public string Description { get; private set; } public override string Category { get; protected set; }
public string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated); public override string Misc { get; protected set; }
public override string Description { get; protected set; }
public override string DisplayTags => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
// these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint // these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate public override LiberateButtonStatus Liberate
{ {
get get
{ {
@ -71,16 +58,14 @@ namespace LibationWinForms
_pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book); _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book);
lastStatusUpdate = DateTime.Now; lastStatusUpdate = DateTime.Now;
} }
return (_bookStatus, _pdfStatus); return new LiberateButtonStatus { BookStatus = _bookStatus, PdfStatus = _pdfStatus, IsSeries = false };
} }
} }
#endregion #endregion
// alias public LibraryBookEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
private Book Book => LibraryBook.Book;
public GridEntry(LibraryBook libraryBook) => setLibraryBook(libraryBook);
public SeriesEntry Parent { get; init; }
public void UpdateLibraryBook(LibraryBook libraryBook) public void UpdateLibraryBook(LibraryBook libraryBook)
{ {
if (AudibleProductId != libraryBook.Book.AudibleProductId) if (AudibleProductId != libraryBook.Book.AudibleProductId)
@ -93,19 +78,9 @@ namespace LibationWinForms
private void setLibraryBook(LibraryBook libraryBook) private void setLibraryBook(LibraryBook libraryBook)
{ {
LibraryBook = libraryBook; LibraryBook = libraryBook;
_memberValues = CreateMemberValueDictionary();
// Get cover art. If it's default, subscribe to PictureCached LoadCover();
{
(bool isDefault, byte[] picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80));
if (isDefault)
PictureStorage.PictureCached += PictureStorage_PictureCached;
// Mutable property. Set the field so PropertyChanged isn't fired.
_cover = ImageReader.ToImage(picture);
}
// Immutable properties // Immutable properties
{ {
@ -126,14 +101,6 @@ namespace LibationWinForms
UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged; UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged;
} }
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)
{
if (e.Definition.PictureId == Book.PictureId)
{
Cover = ImageReader.ToImage(e.Picture);
PictureStorage.PictureCached -= PictureStorage_PictureCached;
}
}
#region detect changes to the model, update the view, and save to database. #region detect changes to the model, update the view, and save to database.
@ -152,16 +119,19 @@ namespace LibationWinForms
{ {
case nameof(udi.Tags): case nameof(udi.Tags):
Book.UserDefinedItem.Tags = udi.Tags; Book.UserDefinedItem.Tags = udi.Tags;
SearchEngineCommands.UpdateBookTags(Book);
NotifyPropertyChanged(nameof(DisplayTags)); NotifyPropertyChanged(nameof(DisplayTags));
break; break;
case nameof(udi.BookStatus): case nameof(udi.BookStatus):
Book.UserDefinedItem.BookStatus = udi.BookStatus; Book.UserDefinedItem.BookStatus = udi.BookStatus;
_bookStatus = udi.BookStatus; _bookStatus = udi.BookStatus;
SearchEngineCommands.UpdateLiberatedStatus(Book);
NotifyPropertyChanged(nameof(Liberate)); NotifyPropertyChanged(nameof(Liberate));
break; break;
case nameof(udi.PdfStatus): case nameof(udi.PdfStatus):
Book.UserDefinedItem.PdfStatus = udi.PdfStatus; Book.UserDefinedItem.PdfStatus = udi.PdfStatus;
_pdfStatus = udi.PdfStatus; _pdfStatus = udi.PdfStatus;
SearchEngineCommands.UpdateLiberatedStatus(Book);
NotifyPropertyChanged(nameof(Liberate)); NotifyPropertyChanged(nameof(Liberate));
break; break;
} }
@ -190,17 +160,9 @@ namespace LibationWinForms
#endregion #endregion
#region Data Sorting #region Data Sorting
// These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
// Used by Dinah.Core.DataBinding.SortableBindingList<T> for all sorting
public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
public virtual IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
private Dictionary<string, Func<object>> _memberValues { get; set; } /// <summary>Create getters for all member object values by name </summary>
protected override Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
/// <summary>
/// Create getters for all member object values by name
/// </summary>
private Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
{ {
{ nameof(Title), () => Book.TitleSortable() }, { nameof(Title), () => Book.TitleSortable() },
{ nameof(Series), () => Book.SeriesSortable() }, { nameof(Series), () => Book.SeriesSortable() },
@ -214,25 +176,17 @@ namespace LibationWinForms
{ nameof(Category), () => Category }, { nameof(Category), () => Category },
{ nameof(Misc), () => Misc }, { nameof(Misc), () => Misc },
{ nameof(DisplayTags), () => DisplayTags }, { nameof(DisplayTags), () => DisplayTags },
{ nameof(Liberate), () => Liberate.BookStatus } { nameof(Liberate), () => Liberate },
{ nameof(DateAdded), () => DateAdded },
}; };
// Instantiate comparers for every exposed member object type.
private static readonly Dictionary<Type, IComparer> _memberTypeComparers = new()
{
{ typeof(string), new ObjectComparer<string>() },
{ typeof(int), new ObjectComparer<int>() },
{ typeof(float), new ObjectComparer<float>() },
{ typeof(DateTime), new ObjectComparer<DateTime>() },
{ typeof(LiberatedStatus), new ObjectComparer<LiberatedStatus>() },
};
#endregion #endregion
#region Static library display functions #region Static library display functions
/// <summary> /// <summary>
/// This information should not change during <see cref="GridEntry"/> lifetime, so call only once. /// This information should not change during <see cref="LibraryBookEntry"/> lifetime, so call only once.
/// </summary> /// </summary>
private static string GetDescriptionDisplay(Book book) private static string GetDescriptionDisplay(Book book)
{ {
@ -250,7 +204,7 @@ namespace LibationWinForms
} }
/// <summary> /// <summary>
/// This information should not change during <see cref="GridEntry"/> lifetime, so call only once. /// This information should not change during <see cref="LibraryBookEntry"/> lifetime, so call only once.
/// Maximum of 5 text rows will fit in 80-pixel row height. /// Maximum of 5 text rows will fit in 80-pixel row height.
/// </summary> /// </summary>
private static string GetMiscDisplay(LibraryBook libraryBook) private static string GetMiscDisplay(LibraryBook libraryBook)
@ -280,10 +234,9 @@ namespace LibationWinForms
#endregion #endregion
~GridEntry() ~LibraryBookEntry()
{ {
UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged; UserDefinedItem.ItemChanged -= UserDefinedItem_ItemChanged;
PictureStorage.PictureCached -= PictureStorage_PictureCached;
} }
} }
} }

View File

@ -0,0 +1,64 @@
namespace LibationWinForms.GridView
{
partial class ProductsDisplay
{
/// <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 Component 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.productsGrid = new LibationWinForms.GridView.ProductsGrid();
this.SuspendLayout();
//
// productsGrid
//
this.productsGrid.AutoScroll = true;
this.productsGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.productsGrid.Location = new System.Drawing.Point(0, 0);
this.productsGrid.Name = "productsGrid";
this.productsGrid.Size = new System.Drawing.Size(1510, 380);
this.productsGrid.TabIndex = 0;
this.productsGrid.LiberateClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_LiberateClicked);
this.productsGrid.CoverClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_CoverClicked);
this.productsGrid.DetailsClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryClickedEventHandler(this.productsGrid_DetailsClicked);
this.productsGrid.DescriptionClicked += new LibationWinForms.GridView.ProductsGrid.LibraryBookEntryRectangleClickedEventHandler(this.productsGrid_DescriptionClicked);
this.productsGrid.VisibleCountChanged += new System.EventHandler<int>(this.productsGrid_VisibleCountChanged);
//
// ProductsDisplay
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.productsGrid);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsDisplay";
this.Size = new System.Drawing.Size(1510, 380);
this.ResumeLayout(false);
}
#endregion
private GridView.ProductsGrid productsGrid;
}
}

View File

@ -0,0 +1,123 @@
using ApplicationServices;
using DataLayer;
using FileLiberator;
using LibationFileManager;
using LibationWinForms.Dialogs;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LibationWinForms.GridView
{
public partial class ProductsDisplay : UserControl
{
/// <summary>Number of visible rows has changed</summary>
public event EventHandler<int> VisibleCountChanged;
public event EventHandler<LibraryBook> LiberateClicked;
public event EventHandler InitialLoaded;
private bool hasBeenDisplayed;
public ProductsDisplay()
{
InitializeComponent();
}
#region Button controls
private ImageDisplay imageDisplay;
private async void productsGrid_CoverClicked(LibraryBookEntry liveGridEntry)
{
var picDefinition = new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureLarge ?? liveGridEntry.LibraryBook.Book.PictureId, PictureSize.Native);
var picDlTask = Task.Run(() => PictureStorage.GetPictureSynchronously(picDefinition));
(_, byte[] initialImageBts) = PictureStorage.GetPicture(new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureId, PictureSize._80x80));
var windowTitle = $"{liveGridEntry.Title} - Cover";
if (imageDisplay is null || imageDisplay.IsDisposed || !imageDisplay.Visible)
{
imageDisplay = new ImageDisplay();
imageDisplay.RestoreSizeAndLocation(Configuration.Instance);
imageDisplay.FormClosed += (_, _) => imageDisplay.SaveSizeAndLocation(Configuration.Instance);
imageDisplay.Show(this);
}
imageDisplay.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(liveGridEntry.LibraryBook);
imageDisplay.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(liveGridEntry.LibraryBook, ".jpg"));
imageDisplay.Text = windowTitle;
imageDisplay.CoverPicture = initialImageBts;
imageDisplay.CoverPicture = await picDlTask;
}
private void productsGrid_DescriptionClicked(LibraryBookEntry liveGridEntry, Rectangle cellRectangle)
{
var displayWindow = new DescriptionDisplay
{
SpawnLocation = PointToScreen(cellRectangle.Location + new Size(cellRectangle.Width, 0)),
DescriptionText = liveGridEntry.LongDescription,
BorderThickness = 2,
};
void CloseWindow(object o, EventArgs e)
{
displayWindow.Close();
}
productsGrid.Scroll += CloseWindow;
displayWindow.FormClosed += (_, _) => productsGrid.Scroll -= CloseWindow;
displayWindow.Show(this);
}
private void productsGrid_DetailsClicked(LibraryBookEntry liveGridEntry)
{
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
if (bookDetailsForm.ShowDialog() == DialogResult.OK)
liveGridEntry.Commit(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
}
#endregion
#region UI display functions
public void Display()
{
// don't return early if lib size == 0. this will not update correctly if all books are removed
var lib = DbContexts.GetLibrary_Flat_NoTracking();
if (!hasBeenDisplayed)
{
// bind
productsGrid.BindToGrid(lib);
hasBeenDisplayed = true;
InitialLoaded?.Invoke(this, new());
}
else
productsGrid.UpdateGrid(lib);
}
#endregion
#region Filter
public void Filter(string searchString)
=> productsGrid.Filter(searchString);
#endregion
internal List<LibraryBook> GetVisible() => productsGrid.GetVisible().Select(v => v.LibraryBook).ToList();
private void productsGrid_VisibleCountChanged(object sender, int count)
{
VisibleCountChanged?.Invoke(this, count);
}
private void productsGrid_LiberateClicked(LibraryBookEntry liveGridEntry)
{
LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
}
}
}

View File

@ -0,0 +1,63 @@
<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="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>81</value>
</metadata>
</root>

View File

@ -1,4 +1,4 @@
namespace LibationWinForms namespace LibationWinForms.GridView
{ {
partial class ProductsGrid partial class ProductsGrid
{ {
@ -29,10 +29,9 @@
private void InitializeComponent() private void InitializeComponent()
{ {
this.components = new System.ComponentModel.Container(); this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components);
this.gridEntryDataGridView = new System.Windows.Forms.DataGridView(); this.gridEntryDataGridView = new System.Windows.Forms.DataGridView();
this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); this.liberateGVColumn = new LibationWinForms.GridView.LiberateDataGridViewImageButtonColumn();
this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn(); this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn();
this.titleGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.titleGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.authorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.authorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
@ -45,16 +44,13 @@
this.purchaseDateGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.purchaseDateGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.myRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.myRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); this.tagAndDetailsGVColumn = new LibationWinForms.GridView.EditTagsDataGridViewImageButtonColumn();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit(); this.syncBindingSource = new LibationWinForms.GridView.SyncBindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).BeginInit();
this.SuspendLayout(); this.SuspendLayout();
// //
// gridEntryBindingSource
//
this.gridEntryBindingSource.DataSource = typeof(LibationWinForms.GridEntry);
//
// gridEntryDataGridView // gridEntryDataGridView
// //
this.gridEntryDataGridView.AllowUserToAddRows = false; this.gridEntryDataGridView.AllowUserToAddRows = false;
@ -64,42 +60,40 @@
this.gridEntryDataGridView.AutoGenerateColumns = false; this.gridEntryDataGridView.AutoGenerateColumns = false;
this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.liberateGVColumn, this.liberateGVColumn,
this.coverGVColumn, this.coverGVColumn,
this.titleGVColumn, this.titleGVColumn,
this.authorsGVColumn, this.authorsGVColumn,
this.narratorsGVColumn, this.narratorsGVColumn,
this.lengthGVColumn, this.lengthGVColumn,
this.seriesGVColumn, this.seriesGVColumn,
this.descriptionGVColumn, this.descriptionGVColumn,
this.categoryGVColumn, this.categoryGVColumn,
this.productRatingGVColumn, this.productRatingGVColumn,
this.purchaseDateGVColumn, this.purchaseDateGVColumn,
this.myRatingGVColumn, this.myRatingGVColumn,
this.miscGVColumn, this.miscGVColumn,
this.tagAndDetailsGVColumn}); this.tagAndDetailsGVColumn});
this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1; this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1;
this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; this.gridEntryDataGridView.DataSource = this.syncBindingSource;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window; dataGridViewCellStyle2.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); dataGridViewCellStyle2.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText; dataGridViewCellStyle2.ForeColor = System.Drawing.SystemColors.ControlText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; dataGridViewCellStyle2.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; dataGridViewCellStyle2.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle1; this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle2;
this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill; this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
this.gridEntryDataGridView.Location = new System.Drawing.Point(0, 0); this.gridEntryDataGridView.Location = new System.Drawing.Point(0, 0);
this.gridEntryDataGridView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.gridEntryDataGridView.Name = "gridEntryDataGridView"; this.gridEntryDataGridView.Name = "gridEntryDataGridView";
this.gridEntryDataGridView.ReadOnly = true; this.gridEntryDataGridView.ReadOnly = true;
this.gridEntryDataGridView.RowHeadersVisible = false; this.gridEntryDataGridView.RowHeadersVisible = false;
this.gridEntryDataGridView.RowTemplate.Height = 82; this.gridEntryDataGridView.RowTemplate.Height = 82;
this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380);
this.gridEntryDataGridView.TabIndex = 0; this.gridEntryDataGridView.TabIndex = 0;
this.gridEntryDataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView_CellContentClick);
this.gridEntryDataGridView.CellToolTipTextNeeded += new System.Windows.Forms.DataGridViewCellToolTipTextNeededEventHandler(this.gridEntryDataGridView_CellToolTipTextNeeded); this.gridEntryDataGridView.CellToolTipTextNeeded += new System.Windows.Forms.DataGridViewCellToolTipTextNeededEventHandler(this.gridEntryDataGridView_CellToolTipTextNeeded);
this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged);
this.gridEntryDataGridView.ColumnWidthChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnWidthChanged);
// //
// liberateGVColumn // liberateGVColumn
// //
@ -218,23 +212,27 @@
this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
// //
// syncBindingSource
//
this.syncBindingSource.DataSource = typeof(LibationWinForms.GridView.GridEntry);
//
// ProductsGrid // ProductsGrid
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoScroll = true;
this.Controls.Add(this.gridEntryDataGridView); this.Controls.Add(this.gridEntryDataGridView);
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "ProductsGrid"; this.Name = "ProductsGrid";
this.Size = new System.Drawing.Size(1510, 380); this.Size = new System.Drawing.Size(1510, 380);
((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit(); this.Load += new System.EventHandler(this.ProductsGrid_Load);
((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.syncBindingSource)).EndInit();
this.ResumeLayout(false); this.ResumeLayout(false);
} }
#endregion
private LibationWinForms.SyncBindingSource gridEntryBindingSource; #endregion
private System.Windows.Forms.DataGridView gridEntryDataGridView; private System.Windows.Forms.DataGridView gridEntryDataGridView;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private LiberateDataGridViewImageButtonColumn liberateGVColumn; private LiberateDataGridViewImageButtonColumn liberateGVColumn;
@ -251,5 +249,6 @@
private System.Windows.Forms.DataGridViewTextBoxColumn myRatingGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn myRatingGVColumn;
private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn; private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn;
private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn; private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn;
private SyncBindingSource syncBindingSource;
} }
} }

View File

@ -0,0 +1,319 @@
using DataLayer;
using Dinah.Core.Windows.Forms;
using LibationFileManager;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
namespace LibationWinForms.GridView
{
public partial class ProductsGrid : UserControl
{
public delegate void LibraryBookEntryClickedEventHandler(LibraryBookEntry liveGridEntry);
public delegate void LibraryBookEntryRectangleClickedEventHandler(LibraryBookEntry liveGridEntry, Rectangle cellRectangle);
/// <summary>Number of visible rows has changed</summary>
public event EventHandler<int> VisibleCountChanged;
public event LibraryBookEntryClickedEventHandler LiberateClicked;
public event LibraryBookEntryClickedEventHandler CoverClicked;
public event LibraryBookEntryClickedEventHandler DetailsClicked;
public event LibraryBookEntryRectangleClickedEventHandler DescriptionClicked;
public new event EventHandler<ScrollEventArgs> Scroll;
private GridEntryBindingList bindingList;
internal IEnumerable<LibraryBookEntry> GetVisible()
=> bindingList
.LibraryBooks();
public ProductsGrid()
{
InitializeComponent();
EnableDoubleBuffering();
gridEntryDataGridView.Scroll += (_, s) => Scroll?.Invoke(this, s);
}
private void EnableDoubleBuffering()
{
var propertyInfo = gridEntryDataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
propertyInfo.SetValue(gridEntryDataGridView, true, null);
}
#region Button controls
private void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// handle grid button click: https://stackoverflow.com/a/13687844
if (e.RowIndex < 0)
return;
var entry = getGridEntry(e.RowIndex);
if (entry is LibraryBookEntry lbEntry)
{
if (e.ColumnIndex == liberateGVColumn.Index)
LiberateClicked?.Invoke(lbEntry);
else if (e.ColumnIndex == tagAndDetailsGVColumn.Index)
DetailsClicked?.Invoke(lbEntry);
else if (e.ColumnIndex == descriptionGVColumn.Index)
DescriptionClicked?.Invoke(lbEntry, gridEntryDataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
else if (e.ColumnIndex == coverGVColumn.Index)
CoverClicked?.Invoke(lbEntry);
}
else if (entry is SeriesEntry sEntry && e.ColumnIndex == liberateGVColumn.Index)
{
if (sEntry.Liberate.Expanded)
bindingList.CollapseItem(sEntry);
else
bindingList.ExpandItem(sEntry);
sEntry.NotifyPropertyChanged(nameof(sEntry.Liberate));
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
}
private GridEntry getGridEntry(int rowIndex) => gridEntryDataGridView.GetBoundItem<GridEntry>(rowIndex);
#endregion
#region UI display functions
internal void BindToGrid(List<LibraryBook> dbBooks)
{
var geList = dbBooks.Where(b => b.Book.ContentType is not ContentType.Episode).Select(b => new LibraryBookEntry(b)).Cast<GridEntry>().ToList();
var episodes = dbBooks.Where(b => b.Book.ContentType is ContentType.Episode).ToList();
foreach (var series in episodes.Select(lb => lb.Book.SeriesLink.First()).DistinctBy(s => s.Series))
{
var seriesEntry = new SeriesEntry(series, episodes.Where(lb => lb.Book.SeriesLink.First().Series == series.Book.SeriesLink.First().Series));
geList.Add(seriesEntry);
geList.AddRange(seriesEntry.Children);
}
bindingList = new GridEntryBindingList(geList.OrderByDescending(e => e.DateAdded));
bindingList.CollapseAll();
syncBindingSource.DataSource = bindingList;
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
internal void UpdateGrid(List<LibraryBook> dbBooks)
{
string existingFilter = syncBindingSource.Filter;
Filter(null);
//Add absent books to grid, or update current books
var allItmes = bindingList.AllItems().LibraryBooks();
foreach (var libraryBook in dbBooks)
{
var existingItem = allItmes.FindBookByAsin(libraryBook.Book.AudibleProductId);
// add new to top
if (existingItem is null)
{
if (libraryBook.Book.ContentType is ContentType.Episode)
{
LibraryBookEntry lbe;
//Find the series that libraryBook belongs to, if it exists
var series = bindingList.AllItems().FindBookSeriesEntry(libraryBook.Book.SeriesLink);
if (series is null)
{
//Series doesn't exist yet, so create and add it
var newSeries = new SeriesEntry(libraryBook.Book.SeriesLink.First(), libraryBook);
lbe = newSeries.Children[0];
newSeries.Liberate.Expanded = true;
bindingList.Insert(0, newSeries);
series = newSeries;
}
else
{
lbe = new(libraryBook) { Parent = series };
series.Children.Add(lbe);
}
//Add episode beneath the parent
int seriesIndex = bindingList.IndexOf(series);
bindingList.Insert(seriesIndex + 1, lbe);
if (series.Liberate.Expanded)
bindingList.ExpandItem(series);
else
bindingList.CollapseItem(series);
series.NotifyPropertyChanged();
}
else
//Add the new product
bindingList.Insert(0, new LibraryBookEntry(libraryBook));
}
// update existing
else
{
existingItem.UpdateLibraryBook(libraryBook);
}
}
//Re-filter after updating existing / adding new books to capture any changes
Filter(existingFilter);
// remove deleted from grid.
// note: actual deletion from db must still occur via the RemoveBook feature. deleting from audible will not trigger this
var removedBooks =
bindingList
.AllItems()
.LibraryBooks()
.ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId);
//Remove books in series from their parents' Children list
foreach (var removed in removedBooks.Where(b => b.Parent is not null))
{
removed.Parent.Children.Remove(removed);
removed.Parent.NotifyPropertyChanged();
}
//Remove series that have no children
var removedSeries =
bindingList
.AllItems()
.EmptySeries();
foreach (var removed in removedBooks.Cast<GridEntry>().Concat(removedSeries))
//no need to re-filter for removed books
bindingList.Remove(removed);
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
#endregion
#region Filter
public void Filter(string searchString)
{
int visibleCount = bindingList.Count;
if (string.IsNullOrEmpty(searchString))
syncBindingSource.RemoveFilter();
else
syncBindingSource.Filter = searchString;
if (visibleCount != bindingList.Count)
VisibleCountChanged?.Invoke(this, bindingList.LibraryBooks().Count());
}
#endregion
#region Column Customizations
private void ProductsGrid_Load(object sender, EventArgs e)
{
//https://stackoverflow.com/a/4498512/3335599
if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime) return;
gridEntryDataGridView.ColumnWidthChanged += gridEntryDataGridView_ColumnWidthChanged;
gridEntryDataGridView.ColumnDisplayIndexChanged += gridEntryDataGridView_ColumnDisplayIndexChanged;
contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns"));
contextMenuStrip1.Items.Add(new ToolStripSeparator());
//Restore Grid Display Settings
var config = Configuration.Instance;
var gridColumnsVisibilities = config.GridColumnsVisibilities;
var gridColumnsWidths = config.GridColumnsWidths;
var displayIndices = config.GridColumnsDisplayIndices;
var cmsKiller = new ContextMenuStrip();
foreach (DataGridViewColumn column in gridEntryDataGridView.Columns)
{
var itemName = column.DataPropertyName;
var visible = gridColumnsVisibilities.GetValueOrDefault(itemName, true);
var menuItem = new ToolStripMenuItem()
{
Text = column.HeaderText,
Checked = visible,
Tag = itemName
};
menuItem.Click += HideMenuItem_Click;
contextMenuStrip1.Items.Add(menuItem);
column.Width = gridColumnsWidths.GetValueOrDefault(itemName, column.Width);
column.MinimumWidth = 10;
column.HeaderCell.ContextMenuStrip = contextMenuStrip1;
column.Visible = visible;
//Setting a default ContextMenuStrip will allow the columns to handle the
//Show() event so it is not passed up to the _dataGridView.ContextMenuStrip.
//This allows the ContextMenuStrip to be shown if right-clicking in the gray
//background of _dataGridView but not shown if right-clicking inside cells.
column.ContextMenuStrip = cmsKiller;
}
//We must set DisplayIndex properties in ascending order
foreach (var itemName in displayIndices.OrderBy(i => i.Value).Select(i => i.Key))
{
var column = gridEntryDataGridView.Columns
.Cast<DataGridViewColumn>()
.Single(c => c.DataPropertyName == itemName);
column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index);
}
}
private void HideMenuItem_Click(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
var propertyName = menuItem.Tag as string;
var column = gridEntryDataGridView.Columns
.Cast<DataGridViewColumn>()
.FirstOrDefault(c => c.DataPropertyName == propertyName);
if (column != null)
{
var visible = menuItem.Checked;
menuItem.Checked = !visible;
column.Visible = !visible;
var config = Configuration.Instance;
var dictionary = config.GridColumnsVisibilities;
dictionary[propertyName] = column.Visible;
config.GridColumnsVisibilities = dictionary;
}
}
private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
{
var config = Configuration.Instance;
var dictionary = config.GridColumnsDisplayIndices;
dictionary[e.Column.DataPropertyName] = e.Column.DisplayIndex;
config.GridColumnsDisplayIndices = dictionary;
}
private void gridEntryDataGridView_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e)
{
if (e.ColumnIndex == descriptionGVColumn.Index)
e.ToolTipText = "Click to see full description";
else if (e.ColumnIndex == coverGVColumn.Index)
e.ToolTipText = "Click to see full size";
}
private void gridEntryDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
var config = Configuration.Instance;
var dictionary = config.GridColumnsWidths;
dictionary[e.Column.DataPropertyName] = e.Column.Width;
}
#endregion
}
}

View File

@ -57,13 +57,16 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="gridEntryBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>171, 17</value>
</metadata>
<metadata name="syncBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="bindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>197, 17</value> <value>326, 17</value>
</metadata> </metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="bindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>81</value> <value>326, 17</value>
</metadata> </metadata>
</root> </root>

View File

@ -0,0 +1,109 @@
using DataLayer;
using Dinah.Core;
using System;
using System.Collections.Generic;
using System.Linq;
namespace LibationWinForms.GridView
{
public class SeriesEntry : GridEntry
{
public List<LibraryBookEntry> Children { get; init; }
public override DateTime DateAdded => Children.Max(c => c.DateAdded);
public override float SeriesIndex { get; }
public override string ProductRating
{
get
{
var productAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.Rating.StoryRating));
return productAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
}
protected set => throw new NotImplementedException();
}
public override string PurchaseDate { get; protected set; }
public override string MyRating
{
get
{
var myAverageRating = new Rating(Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.OverallRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.PerformanceRating), Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.StoryRating));
return myAverageRating.ToStarString()?.DefaultIfNullOrWhiteSpace("");
}
protected set => throw new NotImplementedException();
}
public override string Series { get; protected set; }
public override string Title { get; protected set; }
public override string Length
{
get
{
int bookLenMins = Children.Sum(c => c.LibraryBook.Book.LengthInMinutes);
return bookLenMins == 0 ? "" : $"{bookLenMins / 60} hr {bookLenMins % 60} min";
}
protected set => throw new NotImplementedException();
}
public override string Authors { get; protected set; }
public override string Narrators { get; protected set; }
public override string Category { get; protected set; }
public override string Misc { get; protected set; } = string.Empty;
public override string Description { get; protected set; } = string.Empty;
public override string DisplayTags { get; } = string.Empty;
public override LiberateButtonStatus Liberate { get; }
protected override Book Book => SeriesBook.Book;
private SeriesBook SeriesBook { get; set; }
private SeriesEntry(SeriesBook seriesBook)
{
Liberate = new LiberateButtonStatus { IsSeries = true };
SeriesIndex = seriesBook.Index;
}
public SeriesEntry(SeriesBook seriesBook, IEnumerable<LibraryBook> children) : this(seriesBook)
{
Children = children.Select(c => new LibraryBookEntry(c) { Parent = this }).OrderBy(c => c.SeriesIndex).ToList();
SetSeriesBook(seriesBook);
}
public SeriesEntry(SeriesBook seriesBook, LibraryBook child) : this(seriesBook)
{
Children = new() { new LibraryBookEntry(child) { Parent = this } };
SetSeriesBook(seriesBook);
}
private void SetSeriesBook(SeriesBook seriesBook)
{
SeriesBook = seriesBook;
LoadCover();
// Immutable properties
{
Title = SeriesBook.Series.Name;
Series = SeriesBook.Series.Name;
PurchaseDate = Children.Min(c => c.LibraryBook.DateAdded).ToString("d");
Authors = Book.AuthorNames();
Narrators = Book.NarratorNames();
Category = string.Join(" > ", Book.CategoriesNames());
}
}
/// <summary>Create getters for all member object values by name</summary>
protected override Dictionary<string, Func<object>> CreateMemberValueDictionary() => new()
{
{ nameof(Title), () => Book.SeriesSortable() },
{ nameof(Series), () => Book.SeriesSortable() },
{ nameof(Length), () => Children.Sum(c => c.LibraryBook.Book.LengthInMinutes) },
{ nameof(MyRating), () => Children.Average(c => c.LibraryBook.Book.UserDefinedItem.Rating.FirstScore()) },
{ nameof(PurchaseDate), () => Children.Min(c => c.LibraryBook.DateAdded) },
{ nameof(ProductRating), () => Children.Average(c => c.LibraryBook.Book.Rating.FirstScore()) },
{ nameof(Authors), () => string.Empty },
{ nameof(Narrators), () => string.Empty },
{ nameof(Description), () => string.Empty },
{ nameof(Category), () => string.Empty },
{ nameof(Misc), () => string.Empty },
{ nameof(DisplayTags), () => string.Empty },
{ nameof(Liberate), () => Liberate },
{ nameof(DateAdded), () => DateAdded },
};
}
}

View File

@ -0,0 +1,29 @@
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
// https://stackoverflow.com/a/32886415
namespace LibationWinForms.GridView
{
public class SyncBindingSource : BindingSource
{
private SynchronizationContext syncContext { get; }
public SyncBindingSource() : base()
=> syncContext = SynchronizationContext.Current;
public SyncBindingSource(IContainer container) : base(container)
=> syncContext = SynchronizationContext.Current;
public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
=> syncContext = SynchronizationContext.Current;
public override bool SupportsFiltering => true;
protected override void OnListChanged(ListChangedEventArgs e)
{
if (syncContext is not null)
syncContext.Send(_ => base.OnListChanged(e), null);
else
base.OnListChanged(e);
}
}
}

View File

@ -19,7 +19,7 @@ namespace LibationWinForms.ProcessQueue
LogErrorString += (_, text) => Serilog.Log.Logger.Error(text); LogErrorString += (_, text) => Serilog.Log.Logger.Error(text);
LogError += (_, tuple) => Serilog.Log.Logger.Error(tuple.Item1, tuple.Item2 ?? "Automated backup: error"); LogError += (_, tuple) => Serilog.Log.Logger.Error(tuple.Item1, tuple.Item2 ?? "Automated backup: error");
} }
private static ILogForm LogForm;
public static LogMe RegisterForm<T>(T form) where T : ILogForm public static LogMe RegisterForm<T>(T form) where T : ILogForm
{ {
var logMe = new LogMe(); var logMe = new LogMe();
@ -27,19 +27,31 @@ namespace LibationWinForms.ProcessQueue
if (form is null) if (form is null)
return logMe; return logMe;
logMe.LogInfo += (_, text) => form?.WriteLine(text); LogForm = form;
logMe.LogErrorString += (_, text) => form?.WriteLine(text); logMe.LogInfo += LogMe_LogInfo;
logMe.LogErrorString += LogMe_LogErrorString;
logMe.LogError += (_, tuple) => logMe.LogError += LogMe_LogError;
{
form?.WriteLine(tuple.Item2 ?? "Automated backup: error");
form?.WriteLine("ERROR: " + tuple.Item1.Message);
};
return logMe; return logMe;
} }
private static async void LogMe_LogError(object sender, (Exception, string) tuple)
{
await Task.Run(() => LogForm?.WriteLine(tuple.Item2 ?? "Automated backup: error"));
await Task.Run(() => LogForm?.WriteLine("ERROR: " + tuple.Item1.Message));
}
private static async void LogMe_LogErrorString(object sender, string text)
{
await Task.Run(() => LogForm?.WriteLine(text));
}
private static async void LogMe_LogInfo(object sender, string text)
{
await Task.Run(() => LogForm?.WriteLine(text));
}
public void Info(string text) => LogInfo?.Invoke(this, text); public void Info(string text) => LogInfo?.Invoke(this, text);
public void Error(string text) => LogErrorString?.Invoke(this, text); public void Error(string text) => LogErrorString?.Invoke(this, text);
public void Error(Exception ex, string text = null) => LogError?.Invoke(this, (ex, text)); public void Error(Exception ex, string text = null) => LogError?.Invoke(this, (ex, text));

View File

@ -131,7 +131,6 @@ namespace LibationWinForms.ProcessQueue
{ {
ProcessBookResult.Success => ProcessBookStatus.Completed, ProcessBookResult.Success => ProcessBookStatus.Completed,
ProcessBookResult.Cancelled => ProcessBookStatus.Cancelled, ProcessBookResult.Cancelled => ProcessBookStatus.Cancelled,
ProcessBookResult.FailedRetry => ProcessBookStatus.Queued,
_ => ProcessBookStatus.Failed, _ => ProcessBookStatus.Failed,
}; };
} }

View File

@ -72,8 +72,8 @@ namespace LibationWinForms.ProcessQueue
Status = ProcessBookStatus.Cancelled; Status = ProcessBookStatus.Cancelled;
break; break;
case ProcessBookResult.FailedRetry: case ProcessBookResult.FailedRetry:
statusText = "Queued"; statusText = "Error, will retry later";
Status = ProcessBookStatus.Queued; Status = ProcessBookStatus.Failed;
break; break;
case ProcessBookResult.FailedSkip: case ProcessBookResult.FailedSkip:
statusText = "Error, Skippping"; statusText = "Error, Skippping";

View File

@ -51,9 +51,9 @@
this.logEntryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.logEntryColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.panel4 = new System.Windows.Forms.Panel(); this.panel4 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel(); this.panel2 = new System.Windows.Forms.Panel();
this.logCopyBtn = new System.Windows.Forms.Button();
this.clearLogBtn = new System.Windows.Forms.Button(); this.clearLogBtn = new System.Windows.Forms.Button();
this.counterTimer = new System.Windows.Forms.Timer(this.components); this.counterTimer = new System.Windows.Forms.Timer(this.components);
this.logCopyBtn = new System.Windows.Forms.Button();
this.statusStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout();
this.tabControl1.SuspendLayout(); this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout(); this.tabPage1.SuspendLayout();
@ -264,10 +264,21 @@
this.panel2.Size = new System.Drawing.Size(390, 25); this.panel2.Size = new System.Drawing.Size(390, 25);
this.panel2.TabIndex = 1; this.panel2.TabIndex = 1;
// //
// logCopyBtn
//
this.logCopyBtn.Dock = System.Windows.Forms.DockStyle.Left;
this.logCopyBtn.Location = new System.Drawing.Point(0, 0);
this.logCopyBtn.Name = "logCopyBtn";
this.logCopyBtn.Size = new System.Drawing.Size(57, 23);
this.logCopyBtn.TabIndex = 1;
this.logCopyBtn.Text = "Copy";
this.logCopyBtn.UseVisualStyleBackColor = true;
this.logCopyBtn.Click += new System.EventHandler(this.LogCopyBtn_Click);
//
// clearLogBtn // clearLogBtn
// //
this.clearLogBtn.Dock = System.Windows.Forms.DockStyle.Left; this.clearLogBtn.Dock = System.Windows.Forms.DockStyle.Right;
this.clearLogBtn.Location = new System.Drawing.Point(0, 0); this.clearLogBtn.Location = new System.Drawing.Point(328, 0);
this.clearLogBtn.Name = "clearLogBtn"; this.clearLogBtn.Name = "clearLogBtn";
this.clearLogBtn.Size = new System.Drawing.Size(60, 23); this.clearLogBtn.Size = new System.Drawing.Size(60, 23);
this.clearLogBtn.TabIndex = 0; this.clearLogBtn.TabIndex = 0;
@ -280,17 +291,6 @@
this.counterTimer.Interval = 950; this.counterTimer.Interval = 950;
this.counterTimer.Tick += new System.EventHandler(this.CounterTimer_Tick); this.counterTimer.Tick += new System.EventHandler(this.CounterTimer_Tick);
// //
// logCopyBtn
//
this.logCopyBtn.Dock = System.Windows.Forms.DockStyle.Right;
this.logCopyBtn.Location = new System.Drawing.Point(331, 0);
this.logCopyBtn.Name = "logCopyBtn";
this.logCopyBtn.Size = new System.Drawing.Size(57, 23);
this.logCopyBtn.TabIndex = 1;
this.logCopyBtn.Text = "Copy";
this.logCopyBtn.UseVisualStyleBackColor = true;
this.logCopyBtn.Click += new System.EventHandler(this.LogCopyBtn_Click);
//
// ProcessQueueControl // ProcessQueueControl
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);

View File

@ -46,24 +46,31 @@ namespace LibationWinForms.ProcessQueue
public ProcessQueueControl() public ProcessQueueControl()
{ {
InitializeComponent(); InitializeComponent();
Logger = LogMe.RegisterForm(this);
runningTimeLbl.Text = string.Empty;
popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text; popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
popoutBtn.Name = "popoutBtn"; popoutBtn.Name = "popoutBtn";
popoutBtn.Text = "Pop Out"; popoutBtn.Text = "Pop Out";
popoutBtn.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; popoutBtn.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
popoutBtn.Alignment = ToolStripItemAlignment.Right; popoutBtn.Alignment = ToolStripItemAlignment.Right;
popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
statusStrip1.Items.Add(popoutBtn); statusStrip1.Items.Add(popoutBtn);
Logger = LogMe.RegisterForm(this);
virtualFlowControl2.RequestData += VirtualFlowControl1_RequestData; virtualFlowControl2.RequestData += VirtualFlowControl1_RequestData;
virtualFlowControl2.ButtonClicked += VirtualFlowControl2_ButtonClicked; virtualFlowControl2.ButtonClicked += VirtualFlowControl2_ButtonClicked;
Queue.QueuededCountChanged += Queue_QueuededCountChanged; Queue.QueuededCountChanged += Queue_QueuededCountChanged;
Queue.CompletedCountChanged += Queue_CompletedCountChanged; Queue.CompletedCountChanged += Queue_CompletedCountChanged;
Load += ProcessQueueControl_Load;
}
private void ProcessQueueControl_Load(object sender, EventArgs e)
{
if (DesignMode) return;
runningTimeLbl.Text = string.Empty;
QueuedCount = 0; QueuedCount = 0;
ErrorCount = 0; ErrorCount = 0;
CompletedCount = 0; CompletedCount = 0;
@ -144,12 +151,15 @@ namespace LibationWinForms.ProcessQueue
var result = await nextBook.ProcessOneAsync(); var result = await nextBook.ProcessOneAsync();
if (result == ProcessBookResult.FailedRetry) if (result == ProcessBookResult.ValidationFail)
Queue.Enqueue(nextBook);
else if (result == ProcessBookResult.ValidationFail)
Queue.ClearCurrent(); Queue.ClearCurrent();
else if (result == ProcessBookResult.FailedAbort) else if (result == ProcessBookResult.FailedAbort)
return; Queue.ClearQueue();
else if (result == ProcessBookResult.FailedSkip)
{
nextBook.LibraryBook.Book.UserDefinedItem.BookStatus = DataLayer.LiberatedStatus.Error;
ApplicationServices.LibraryCommands.UpdateUserDefinedItem(nextBook.LibraryBook.Book);
}
} }
Queue_CompletedCountChanged(this, 0); Queue_CompletedCountChanged(this, 0);
counterTimer.Stop(); counterTimer.Stop();
@ -162,14 +172,14 @@ namespace LibationWinForms.ProcessQueue
if (IsDisposed) return; if (IsDisposed) return;
var timeStamp = DateTime.Now; var timeStamp = DateTime.Now;
logDGV.Rows.Add(timeStamp, text.Trim()); Invoke(() => logDGV.Rows.Add(timeStamp, text.Trim()));
} }
#region Control event handlers #region Control event handlers
private void Queue_CompletedCountChanged(object sender, int e) private void Queue_CompletedCountChanged(object sender, int e)
{ {
int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.ValidationFail); int errCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.FailedAbort or ProcessBookResult.FailedSkip or ProcessBookResult.FailedRetry or ProcessBookResult.ValidationFail);
int completeCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.Success); int completeCount = Queue.Completed.Count(p => p.Result is ProcessBookResult.Success);
ErrorCount = errCount; ErrorCount = errCount;

View File

@ -29,6 +29,7 @@
private void InitializeComponent() private void InitializeComponent()
{ {
this.panel1 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel();
this.vScrollBar1 = new System.Windows.Forms.VScrollBar();
this.SuspendLayout(); this.SuspendLayout();
// //
// panel1 // panel1
@ -39,12 +40,21 @@
this.panel1.BackColor = System.Drawing.SystemColors.ControlDark; this.panel1.BackColor = System.Drawing.SystemColors.ControlDark;
this.panel1.Location = new System.Drawing.Point(0, 0); this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1"; this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(377, 505); this.panel1.Size = new System.Drawing.Size(357, 505);
this.panel1.TabIndex = 0; this.panel1.TabIndex = 0;
// //
// vScrollBar1
//
this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right;
this.vScrollBar1.Location = new System.Drawing.Point(360, 0);
this.vScrollBar1.Name = "vScrollBar1";
this.vScrollBar1.Size = new System.Drawing.Size(17, 505);
this.vScrollBar1.TabIndex = 0;
//
// VirtualFlowControl // VirtualFlowControl
// //
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Controls.Add(this.vScrollBar1);
this.Controls.Add(this.panel1); this.Controls.Add(this.panel1);
this.Name = "VirtualFlowControl"; this.Name = "VirtualFlowControl";
this.Size = new System.Drawing.Size(377, 505); this.Size = new System.Drawing.Size(377, 505);
@ -55,5 +65,6 @@
#endregion #endregion
private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.VScrollBar vScrollBar1;
} }
} }

View File

@ -75,7 +75,6 @@ namespace LibationWinForms.ProcessQueue
/// </summary> /// </summary>
private readonly int TopMargin; private readonly int TopMargin;
private readonly VScrollBar vScrollBar1;
private readonly List<ProcessBookControl> BookControls = new(); private readonly List<ProcessBookControl> BookControls = new();
#endregion #endregion
@ -101,16 +100,6 @@ namespace LibationWinForms.ProcessQueue
{ {
InitializeComponent(); InitializeComponent();
vScrollBar1 = new VScrollBar
{
Minimum = 0,
Value = 0,
Dock = DockStyle.Right
};
Controls.Add(vScrollBar1);
vScrollBar1.Scroll += (_, s) => SetScrollPosition(s.NewValue);
panel1.Width -= vScrollBar1.Width + panel1.Margin.Right;
panel1.Resize += (_, _) => panel1.Resize += (_, _) =>
{ {
AdjustScrollBar(); AdjustScrollBar();
@ -125,9 +114,6 @@ namespace LibationWinForms.ProcessQueue
BookControls.Add(control); BookControls.Add(control);
panel1.Controls.Add(control); panel1.Controls.Add(control);
if (DesignMode)
return;
for (int i = 1; i < NUM_ACTUAL_CONTROLS; i++) for (int i = 1; i < NUM_ACTUAL_CONTROLS; i++)
{ {
control = InitControl(VirtualControlHeight * i); control = InitControl(VirtualControlHeight * i);
@ -135,6 +121,7 @@ namespace LibationWinForms.ProcessQueue
panel1.Controls.Add(control); panel1.Controls.Add(control);
} }
vScrollBar1.Scroll += (_, s) => SetScrollPosition(s.NewValue);
vScrollBar1.SmallChange = SmallScrollChange; vScrollBar1.SmallChange = SmallScrollChange;
panel1.Height += NUM_BLANK_SPACES_AT_BOTTOM * VirtualControlHeight; panel1.Height += NUM_BLANK_SPACES_AT_BOTTOM * VirtualControlHeight;
} }
@ -227,6 +214,8 @@ namespace LibationWinForms.ProcessQueue
/// </summary> /// </summary>
private void SetScrollPosition(int value) private void SetScrollPosition(int value)
{ {
if (!vScrollBar1.Enabled) return;
int newPos = (int)Math.Round((double)value / SmallScrollChange) * SmallScrollChange; int newPos = (int)Math.Round((double)value / SmallScrollChange) * SmallScrollChange;
if (vScrollBar1.Value != newPos) if (vScrollBar1.Value != newPos)
{ {

View File

@ -6,5 +6,5 @@
cause the file to be unrecognizable by the program. cause the file to be unrecognizable by the program.
--> -->
<GenericObjectDataSource DisplayName="GridEntry" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource"> <GenericObjectDataSource DisplayName="GridEntry" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>LibationWinForms.GridEntry, LibationWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo> <TypeInfo>LibationWinForms.GridView.GridEntry, LibationWinForms, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource> </GenericObjectDataSource>

View File

@ -229,5 +229,25 @@ namespace LibationWinForms.Properties {
return ((System.Drawing.Bitmap)(obj)); return ((System.Drawing.Bitmap)(obj));
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap minus {
get {
object obj = ResourceManager.GetObject("minus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap plus {
get {
object obj = ResourceManager.GetObject("plus", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
} }
} }

View File

@ -169,4 +169,10 @@
<data name="liberate_yellow_pdf_yes" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="liberate_yellow_pdf_yes" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\liberate_yellow_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Resources\liberate_yellow_pdf_yes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="minus" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\minus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="plus" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\plus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

View File

@ -1,30 +0,0 @@
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
// https://stackoverflow.com/a/32886415
namespace LibationWinForms
{
public class SyncBindingSource : BindingSource
{
private SynchronizationContext syncContext { get; }
public SyncBindingSource() : base()
=> syncContext = SynchronizationContext.Current;
public SyncBindingSource(IContainer container) : base(container)
=> syncContext = SynchronizationContext.Current;
public SyncBindingSource(object dataSource, string dataMember) : base(dataSource, dataMember)
=> syncContext = SynchronizationContext.Current;
public override bool SupportsFiltering => true;
protected override void OnListChanged(ListChangedEventArgs e)
{
if (syncContext is not null)
syncContext.Send(_ => base.OnListChanged(e), null);
else
base.OnListChanged(e);
}
}
}

View File

@ -1,94 +0,0 @@
using ApplicationServices;
using Dinah.Core.DataBinding;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace LibationWinForms
{
/*
* Allows filtering of the underlying SortableBindingList<GridEntry>
* by implementing IBindingListView and using SearchEngineCommands
*
* When filtering is applied, the filtered-out items are removed
* from the base list and added to the private FilterRemoved list.
* When filtering is removed, items in the FilterRemoved list are
* added back to the base list.
*
* Remove is overridden to ensure that removed items are removed from
* the base list (visible items) as well as the FilterRemoved list.
*/
internal class FilterableSortableBindingList : SortableBindingList<GridEntry>, IBindingListView
{
/// <summary>
/// Items that were removed from the base list due to filtering
/// </summary>
private readonly List<GridEntry> FilterRemoved = new();
private string FilterString;
public FilterableSortableBindingList(IEnumerable<GridEntry> enumeration) : base(enumeration) { }
public bool SupportsFiltering => true;
public string Filter { get => FilterString; set => ApplyFilter(value); }
#region Unused - Advanced Filtering
public bool SupportsAdvancedSorting => false;
//This ApplySort overload is only called if SupportsAdvancedSorting is true.
//Otherwise BindingList.ApplySort() is used
public void ApplySort(ListSortDescriptionCollection sorts) => throw new NotImplementedException();
public ListSortDescriptionCollection SortDescriptions => throw new NotImplementedException();
#endregion
public new void Remove(GridEntry entry)
{
FilterRemoved.Remove(entry);
base.Remove(entry);
}
/// <returns>All items in the list, including those filtered out.</returns>
public List<GridEntry> AllItems() => Items.Concat(FilterRemoved).ToList();
private void ApplyFilter(string filterString)
{
if (filterString != FilterString)
RemoveFilter();
FilterString = filterString;
var searchResults = SearchEngineCommands.Search(filterString);
var filteredOut = Items.ExceptBy(searchResults.Docs.Select(d => d.ProductId), ge => ge.AudibleProductId);
for (int i = Items.Count - 1; i >= 0; i--)
{
if (filteredOut.Contains(Items[i]))
{
FilterRemoved.Add(Items[i]);
Items.RemoveAt(i);
base.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, i));
}
}
}
public void RemoveFilter()
{
if (FilterString is null) return;
int visibleCount = Items.Count;
for (int i = 0; i < FilterRemoved.Count; i++)
base.InsertItem(i + visibleCount, FilterRemoved[i]);
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
FilterRemoved.Clear();
if (IsSortedCore)
Sort();
else
//No user-defined sort is applied, so do default sorting by date added, descending
((List<GridEntry>)Items).Sort((i1, i2) => i2.LibraryBook.DateAdded.CompareTo(i1.LibraryBook.DateAdded));
FilterString = null;
}
}
}

View File

@ -1,351 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using ApplicationServices;
using DataLayer;
using Dinah.Core.Windows.Forms;
using FileLiberator;
using LibationFileManager;
using LibationWinForms.Dialogs;
namespace LibationWinForms
{
#region // legacy instructions to update data_grid_view
// INSTRUCTIONS TO UPDATE DATA_GRID_VIEW
// - delete current DataGridView
// - view > other windows > data sources
// - refresh
// OR
// - Add New Data Source
// Object. Next
// LibationWinForms
// AudibleDTO
// GridEntry
// - go to Design view
// - click on Data Sources > ProductItem. dropdown: DataGridView
// - drag/drop ProductItem on design surface
//
// as of august 2021 this does not work in vs2019 with .net5 projects
// VS has improved since then with .net6+ but I haven't checked again
#endregion
public partial class ProductsGrid : UserControl
{
public event EventHandler<LibraryBook> LiberateClicked;
/// <summary>Number of visible rows has changed</summary>
public event EventHandler<int> VisibleCountChanged;
// alias
private DataGridView _dataGridView => gridEntryDataGridView;
public ProductsGrid()
{
InitializeComponent();
if (this.DesignMode)
return;
EnableDoubleBuffering();
_dataGridView.CellContentClick += DataGridView_CellContentClick;
this.Load += ProductsGrid_Load;
}
private void EnableDoubleBuffering()
{
var propertyInfo = _dataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
propertyInfo.SetValue(_dataGridView, true, null);
}
#region Button controls
private async void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
// handle grid button click: https://stackoverflow.com/a/13687844
if (e.RowIndex < 0)
return;
if (e.ColumnIndex == liberateGVColumn.Index)
Liberate_Click(getGridEntry(e.RowIndex));
else if (e.ColumnIndex == tagAndDetailsGVColumn.Index)
Details_Click(getGridEntry(e.RowIndex));
else if (e.ColumnIndex == descriptionGVColumn.Index)
Description_Click(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false));
else if (e.ColumnIndex == coverGVColumn.Index)
await Cover_Click(getGridEntry(e.RowIndex));
}
private ImageDisplay imageDisplay;
private async Task Cover_Click(GridEntry liveGridEntry)
{
var picDefinition = new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureLarge ?? liveGridEntry.LibraryBook.Book.PictureId, PictureSize.Native);
var picDlTask = Task.Run(() => PictureStorage.GetPictureSynchronously(picDefinition));
(_, byte[] initialImageBts) = PictureStorage.GetPicture(new PictureDefinition(liveGridEntry.LibraryBook.Book.PictureId, PictureSize._80x80));
var windowTitle = $"{liveGridEntry.Title} - Cover";
if (imageDisplay is null || imageDisplay.IsDisposed || !imageDisplay.Visible)
{
imageDisplay = new ImageDisplay();
imageDisplay.RestoreSizeAndLocation(Configuration.Instance);
imageDisplay.FormClosed += (_, _) => imageDisplay.SaveSizeAndLocation(Configuration.Instance);
imageDisplay.Show(this);
}
imageDisplay.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(liveGridEntry.LibraryBook);
imageDisplay.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(liveGridEntry.LibraryBook, ".jpg"));
imageDisplay.Text = windowTitle;
imageDisplay.CoverPicture = initialImageBts;
imageDisplay.CoverPicture = await picDlTask;
}
private void Description_Click(GridEntry liveGridEntry, Rectangle cellDisplay)
{
var displayWindow = new DescriptionDisplay
{
SpawnLocation = PointToScreen(cellDisplay.Location + new Size(cellDisplay.Width, 0)),
DescriptionText = liveGridEntry.LongDescription,
BorderThickness = 2,
};
void CloseWindow(object o, EventArgs e)
{
displayWindow.Close();
}
_dataGridView.Scroll += CloseWindow;
displayWindow.FormClosed += (_, _) => _dataGridView.Scroll -= CloseWindow;
displayWindow.Show(this);
}
private void Liberate_Click(GridEntry liveGridEntry)
{
LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
}
private static void Details_Click(GridEntry liveGridEntry)
{
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
if (bookDetailsForm.ShowDialog() == DialogResult.OK)
liveGridEntry.Commit(bookDetailsForm.NewTags, bookDetailsForm.BookLiberatedStatus, bookDetailsForm.PdfLiberatedStatus);
}
#endregion
#region UI display functions
private FilterableSortableBindingList bindingList;
private bool hasBeenDisplayed;
public event EventHandler InitialLoaded;
public void Display()
{
// don't return early if lib size == 0. this will not update correctly if all books are removed
var lib = DbContexts.GetLibrary_Flat_NoTracking();
if (!hasBeenDisplayed)
{
// bind
bindToGrid(lib);
hasBeenDisplayed = true;
InitialLoaded?.Invoke(this, new());
VisibleCountChanged?.Invoke(this, bindingList.Count);
}
else
updateGrid(lib);
}
private void bindToGrid(List<LibraryBook> dbBooks)
{
bindingList = new FilterableSortableBindingList(dbBooks.OrderByDescending(lb => lb.DateAdded).Select(lb => new GridEntry(lb)));
gridEntryBindingSource.DataSource = bindingList;
}
private void updateGrid(List<LibraryBook> dbBooks)
{
int visibleCount = bindingList.Count;
string existingFilter = gridEntryBindingSource.Filter;
//Add absent books to grid, or update current books
var allItmes = bindingList.AllItems();
for (var i = dbBooks.Count - 1; i >= 0; i--)
{
var libraryBook = dbBooks[i];
var existingItem = allItmes.FirstOrDefault(i => i.AudibleProductId == libraryBook.Book.AudibleProductId);
// add new to top
if (existingItem is null)
bindingList.Insert(0, new GridEntry(libraryBook));
// update existing
else
existingItem.UpdateLibraryBook(libraryBook);
}
if (bindingList.Count != visibleCount)
{
//re-filter for newly added items
Filter(null);
Filter(existingFilter);
}
// remove deleted from grid.
// note: actual deletion from db must still occur via the RemoveBook feature. deleting from audible will not trigger this
var removedBooks =
bindingList
.AllItems()
.ExceptBy(dbBooks.Select(lb => lb.Book.AudibleProductId), ge => ge.AudibleProductId)
.ToList();
foreach (var removed in removedBooks)
//no need to re-filter for removed books
bindingList.Remove(removed);
if (bindingList.Count != visibleCount)
VisibleCountChanged?.Invoke(this, bindingList.Count);
}
#endregion
#region Filter
public void Filter(string searchString)
{
int visibleCount = bindingList.Count;
if (string.IsNullOrEmpty(searchString))
gridEntryBindingSource.RemoveFilter();
else
gridEntryBindingSource.Filter = searchString;
if (visibleCount != bindingList.Count)
VisibleCountChanged?.Invoke(this, bindingList.Count);
}
#endregion
internal List<LibraryBook> GetVisible()
=> bindingList
.Select(row => row.LibraryBook)
.ToList();
private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem<GridEntry>(rowIndex);
#region Column Customizations
// to ensure this is only ever called once: Load instead of 'override OnVisibleChanged'
private void ProductsGrid_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns"));
contextMenuStrip1.Items.Add(new ToolStripSeparator());
//Restore Grid Display Settings
var config = Configuration.Instance;
var gridColumnsVisibilities = config.GridColumnsVisibilities;
var gridColumnsWidths = config.GridColumnsWidths;
var displayIndices = config.GridColumnsDisplayIndices;
var cmsKiller = new ContextMenuStrip();
foreach (DataGridViewColumn column in _dataGridView.Columns)
{
var itemName = column.DataPropertyName;
var visible = gridColumnsVisibilities.GetValueOrDefault(itemName, true);
var menuItem = new ToolStripMenuItem()
{
Text = column.HeaderText,
Checked = visible,
Tag = itemName
};
menuItem.Click += HideMenuItem_Click;
contextMenuStrip1.Items.Add(menuItem);
column.Width = gridColumnsWidths.GetValueOrDefault(itemName, column.Width);
column.MinimumWidth = 10;
column.HeaderCell.ContextMenuStrip = contextMenuStrip1;
column.Visible = visible;
//Setting a default ContextMenuStrip will allow the columns to handle the
//Show() event so it is not passed up to the _dataGridView.ContextMenuStrip.
//This allows the ContextMenuStrip to be shown if right-clicking in the gray
//background of _dataGridView but not shown if right-clicking inside cells.
column.ContextMenuStrip = cmsKiller;
}
//We must set DisplayIndex properties in ascending order
foreach (var itemName in displayIndices.OrderBy(i => i.Value).Select(i => i.Key))
{
var column = _dataGridView.Columns
.Cast<DataGridViewColumn>()
.Single(c => c.DataPropertyName == itemName);
column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index);
}
base.OnVisibleChanged(e);
}
private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e)
{
var config = Configuration.Instance;
var dictionary = config.GridColumnsDisplayIndices;
dictionary[e.Column.DataPropertyName] = e.Column.DisplayIndex;
config.GridColumnsDisplayIndices = dictionary;
}
private void gridEntryDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
var config = Configuration.Instance;
var dictionary = config.GridColumnsWidths;
dictionary[e.Column.DataPropertyName] = e.Column.Width;
config.GridColumnsWidths = dictionary;
}
private void HideMenuItem_Click(object sender, EventArgs e)
{
var menuItem = sender as ToolStripMenuItem;
var propertyName = menuItem.Tag as string;
var column = _dataGridView.Columns
.Cast<DataGridViewColumn>()
.FirstOrDefault(c => c.DataPropertyName == propertyName);
if (column != null)
{
var visible = menuItem.Checked;
menuItem.Checked = !visible;
column.Visible = !visible;
var config = Configuration.Instance;
var dictionary = config.GridColumnsVisibilities;
dictionary[propertyName] = column.Visible;
config.GridColumnsVisibilities = dictionary;
}
}
private void gridEntryDataGridView_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e)
{
if (e.ColumnIndex == descriptionGVColumn.Index)
e.ToolTipText = "Click to see full description";
else if (e.ColumnIndex == coverGVColumn.Index)
e.ToolTipText = "Click to see full size";
}
#endregion
}
}