From aecc54401d30c47d213ca4ee0f8de6961230b7e1 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 12:58:09 -0600 Subject: [PATCH 01/27] Add option for user to hide columns in ProductsGrid --- Source/AppScaffolding/LibationScaffolding.cs | 3 + Source/FileManager/PersistentDictionary.cs | 383 +++++++++--------- Source/LibationFileManager/Configuration.cs | 7 + .../grid/ProductsGrid.Designer.cs | 360 ++++++++-------- Source/LibationWinForms/grid/ProductsGrid.cs | 51 +++ .../LibationWinForms/grid/ProductsGrid.resx | 6 +- 6 files changed, 441 insertions(+), 369 deletions(-) diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index d287190f..63818d6d 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -125,6 +125,9 @@ namespace AppScaffolding if (!config.Exists(nameof(config.AutoScan))) config.AutoScan = true; + + if (!config.Exists(nameof(config.HiddenGridColumns))) + config.HiddenGridColumns = Array.Empty(); } /// Initialize logging. Run after migration diff --git a/Source/FileManager/PersistentDictionary.cs b/Source/FileManager/PersistentDictionary.cs index 53e87c9a..0073a705 100644 --- a/Source/FileManager/PersistentDictionary.cs +++ b/Source/FileManager/PersistentDictionary.cs @@ -7,236 +7,237 @@ using Newtonsoft.Json.Linq; namespace FileManager { - public class PersistentDictionary - { - public string Filepath { get; } - public bool IsReadOnly { get; } + public class PersistentDictionary + { + public string Filepath { get; } + public bool IsReadOnly { get; } - // optimize for strings. expectation is most settings will be strings and a rare exception will be something else - private Dictionary stringCache { get; } = new Dictionary(); - private Dictionary objectCache { get; } = new Dictionary(); + // optimize for strings. expectation is most settings will be strings and a rare exception will be something else + private Dictionary stringCache { get; } = new Dictionary(); + private Dictionary objectCache { get; } = new Dictionary(); - public PersistentDictionary(string filepath, bool isReadOnly = false) - { - Filepath = filepath; - IsReadOnly = isReadOnly; + public PersistentDictionary(string filepath, bool isReadOnly = false) + { + Filepath = filepath; + IsReadOnly = isReadOnly; - if (File.Exists(Filepath)) - return; + if (File.Exists(Filepath)) + return; - // will create any missing directories, incl subdirectories. if all already exist: no action - Directory.CreateDirectory(Path.GetDirectoryName(filepath)); + // will create any missing directories, incl subdirectories. if all already exist: no action + Directory.CreateDirectory(Path.GetDirectoryName(filepath)); - if (IsReadOnly) - return; + if (IsReadOnly) + return; - createNewFile(); - } + createNewFile(); + } - public string GetString(string propertyName) - { - if (!stringCache.ContainsKey(propertyName)) - { - var jObject = readFile(); - if (!jObject.ContainsKey(propertyName)) - return null; - stringCache[propertyName] = jObject[propertyName].Value(); - } + public string GetString(string propertyName) + { + if (!stringCache.ContainsKey(propertyName)) + { + var jObject = readFile(); + if (!jObject.ContainsKey(propertyName)) + return null; + stringCache[propertyName] = jObject[propertyName].Value(); + } - return stringCache[propertyName]; - } + return stringCache[propertyName]; + } - public T GetNonString(string propertyName) - { - var obj = GetObject(propertyName); - if (obj is null) return default; - if (obj is JValue jValue) return jValue.Value(); - if (obj is JObject jObject) return jObject.ToObject(); - return (T)obj; - } + public T GetNonString(string propertyName) + { + var obj = GetObject(propertyName); + if (obj is null) return default; + if (obj is JValue jValue) return jValue.Value(); + if (obj is JObject jObject) return jObject.ToObject(); + if (obj is JArray jArray && typeof(T).IsArray) return jArray.ToObject(); + return (T)obj; + } - public object GetObject(string propertyName) - { - if (!objectCache.ContainsKey(propertyName)) - { - var jObject = readFile(); - if (!jObject.ContainsKey(propertyName)) - return null; - objectCache[propertyName] = jObject[propertyName].Value(); - } + public object GetObject(string propertyName) + { + if (!objectCache.ContainsKey(propertyName)) + { + var jObject = readFile(); + if (!jObject.ContainsKey(propertyName)) + return null; + objectCache[propertyName] = jObject[propertyName].Value(); + } - return objectCache[propertyName]; - } + return objectCache[propertyName]; + } - public string GetStringFromJsonPath(string jsonPath, string propertyName) => GetStringFromJsonPath($"{jsonPath}.{propertyName}"); - public string GetStringFromJsonPath(string jsonPath) - { - if (!stringCache.ContainsKey(jsonPath)) - { - try - { - var jObject = readFile(); - var token = jObject.SelectToken(jsonPath); - if (token is null) - return null; - stringCache[jsonPath] = (string)token; - } - catch - { - return null; - } - } + public string GetStringFromJsonPath(string jsonPath, string propertyName) => GetStringFromJsonPath($"{jsonPath}.{propertyName}"); + public string GetStringFromJsonPath(string jsonPath) + { + if (!stringCache.ContainsKey(jsonPath)) + { + try + { + var jObject = readFile(); + var token = jObject.SelectToken(jsonPath); + if (token is null) + return null; + stringCache[jsonPath] = (string)token; + } + catch + { + return null; + } + } - return stringCache[jsonPath]; - } + return stringCache[jsonPath]; + } - public bool Exists(string propertyName) => readFile().ContainsKey(propertyName); + public bool Exists(string propertyName) => readFile().ContainsKey(propertyName); - private object locker { get; } = new object(); - public void SetString(string propertyName, string newValue) - { - // only do this check in string cache, NOT object cache - if (stringCache.ContainsKey(propertyName) && stringCache[propertyName] == newValue) - return; + private object locker { get; } = new object(); + public void SetString(string propertyName, string newValue) + { + // only do this check in string cache, NOT object cache + if (stringCache.ContainsKey(propertyName) && stringCache[propertyName] == newValue) + return; - // set cache - stringCache[propertyName] = newValue; + // set cache + stringCache[propertyName] = newValue; - writeFile(propertyName, newValue); - } + writeFile(propertyName, newValue); + } - public void SetNonString(string propertyName, object newValue) - { - // set cache - objectCache[propertyName] = newValue; + public void SetNonString(string propertyName, object newValue) + { + // set cache + objectCache[propertyName] = newValue; - var parsedNewValue = JToken.Parse(JsonConvert.SerializeObject(newValue)); - writeFile(propertyName, parsedNewValue); - } + var parsedNewValue = JToken.Parse(JsonConvert.SerializeObject(newValue)); + writeFile(propertyName, parsedNewValue); + } - private void writeFile(string propertyName, JToken newValue) - { - if (IsReadOnly) - return; + private void writeFile(string propertyName, JToken newValue) + { + if (IsReadOnly) + return; - // write new setting to file - lock (locker) - { - var jObject = readFile(); - var startContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); + // write new setting to file + lock (locker) + { + var jObject = readFile(); + var startContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); - jObject[propertyName] = newValue; - var endContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); + jObject[propertyName] = newValue; + var endContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); - if (startContents == endContents) - return; - - File.WriteAllText(Filepath, endContents); - } + if (startContents == endContents) + return; - try - { - var str = formatValueForLog(newValue?.ToString()); - Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { propertyName, newValue = str }); - } - catch { } - } + File.WriteAllText(Filepath, endContents); + } - /// WILL ONLY set if already present. WILL NOT create new - /// Value was changed - public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false) - { - if (IsReadOnly) - return false; + try + { + var str = formatValueForLog(newValue?.ToString()); + Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { propertyName, newValue = str }); + } + catch { } + } - var path = $"{jsonPath}.{propertyName}"; + /// WILL ONLY set if already present. WILL NOT create new + /// Value was changed + public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false) + { + if (IsReadOnly) + return false; - { - // only do this check in string cache, NOT object cache - if (stringCache.ContainsKey(path) && stringCache[path] == newValue) - return false; + var path = $"{jsonPath}.{propertyName}"; - // set cache - stringCache[path] = newValue; - } + { + // only do this check in string cache, NOT object cache + if (stringCache.ContainsKey(path) && stringCache[path] == newValue) + return false; - try - { - lock (locker) - { - var jObject = readFile(); - var token = jObject.SelectToken(jsonPath); - if (token is null || token[propertyName] is null) - return false; + // set cache + stringCache[path] = newValue; + } - var oldValue = token.Value(propertyName); - if (oldValue == newValue) - return false; + try + { + lock (locker) + { + var jObject = readFile(); + var token = jObject.SelectToken(jsonPath); + if (token is null || token[propertyName] is null) + return false; - token[propertyName] = newValue; - File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented)); - } - } - catch (Exception exDebug) - { - return false; - } + var oldValue = token.Value(propertyName); + if (oldValue == newValue) + return false; - if (!suppressLogging) - { - try - { - var str = formatValueForLog(newValue?.ToString()); - Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { jsonPath, propertyName, newValue = str }); - } - catch { } - } + token[propertyName] = newValue; + File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented)); + } + } + catch (Exception exDebug) + { + return false; + } - return true; - } + if (!suppressLogging) + { + try + { + var str = formatValueForLog(newValue?.ToString()); + Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { jsonPath, propertyName, newValue = str }); + } + catch { } + } - private static string formatValueForLog(string value) - => value is null ? "[null]" - : string.IsNullOrEmpty(value) ? "[empty]" - : string.IsNullOrWhiteSpace(value) ? $"[whitespace. Length={value.Length}]" - : value.Length > 100 ? $"[Length={value.Length}] {value[0..50]}...{value[^50..^0]}" - : value; + return true; + } - private JObject readFile() - { - if (!File.Exists(Filepath)) - { - var msg = "Unrecoverable error. Settings file cannot be found"; - var ex = new FileNotFoundException(msg, Filepath); - Serilog.Log.Logger.Error(ex, msg); - throw ex; - } + private static string formatValueForLog(string value) + => value is null ? "[null]" + : string.IsNullOrEmpty(value) ? "[empty]" + : string.IsNullOrWhiteSpace(value) ? $"[whitespace. Length={value.Length}]" + : value.Length > 100 ? $"[Length={value.Length}] {value[0..50]}...{value[^50..^0]}" + : value; - var settingsJsonContents = File.ReadAllText(Filepath); + private JObject readFile() + { + if (!File.Exists(Filepath)) + { + var msg = "Unrecoverable error. Settings file cannot be found"; + var ex = new FileNotFoundException(msg, Filepath); + Serilog.Log.Logger.Error(ex, msg); + throw ex; + } - if (string.IsNullOrWhiteSpace(settingsJsonContents)) - { - createNewFile(); - settingsJsonContents = File.ReadAllText(Filepath); - } + var settingsJsonContents = File.ReadAllText(Filepath); - var jObject = JsonConvert.DeserializeObject(settingsJsonContents); + if (string.IsNullOrWhiteSpace(settingsJsonContents)) + { + createNewFile(); + settingsJsonContents = File.ReadAllText(Filepath); + } - if (jObject is null) - { - var msg = "Unrecoverable error. Unable to read settings from Settings file"; - var ex = new NullReferenceException(msg); - Serilog.Log.Logger.Error(ex, msg); - throw ex; - } + var jObject = JsonConvert.DeserializeObject(settingsJsonContents); - return jObject; - } + if (jObject is null) + { + var msg = "Unrecoverable error. Unable to read settings from Settings file"; + var ex = new NullReferenceException(msg); + Serilog.Log.Logger.Error(ex, msg); + throw ex; + } - private void createNewFile() - { - File.WriteAllText(Filepath, "{}"); - System.Threading.Thread.Sleep(100); - } - } + return jObject; + } + + private void createNewFile() + { + File.WriteAllText(Filepath, "{}"); + System.Threading.Thread.Sleep(100); + } + } } diff --git a/Source/LibationFileManager/Configuration.cs b/Source/LibationFileManager/Configuration.cs index 89ab5f9f..0a18b770 100644 --- a/Source/LibationFileManager/Configuration.cs +++ b/Source/LibationFileManager/Configuration.cs @@ -179,6 +179,13 @@ namespace LibationFileManager get => persistentDictionary.GetNonString(nameof(LameVBRQuality)); set => persistentDictionary.SetNonString(nameof(LameVBRQuality), value); } + + [Description("A list of GridView data property names whose columns should be hidden in ProductsGrid")] + public string[] HiddenGridColumns + { + get => persistentDictionary.GetNonString(nameof(HiddenGridColumns)); + set => persistentDictionary.SetNonString(nameof(HiddenGridColumns), value); + } public enum BadBookAction { diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index 689bd848..0aec4e05 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -28,40 +28,41 @@ /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components); - this.gridEntryDataGridView = new System.Windows.Forms.DataGridView(); - this.dataGridViewImageButtonBoxColumn1 = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); - this.dataGridViewImageColumn1 = new System.Windows.Forms.DataGridViewImageColumn(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewImageButtonBoxColumn2 = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); - ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit(); - this.SuspendLayout(); - // - // gridEntryBindingSource - // - this.gridEntryBindingSource.DataSource = typeof(LibationWinForms.GridEntry); - // - // gridEntryDataGridView - // - this.gridEntryDataGridView.AllowUserToAddRows = false; - this.gridEntryDataGridView.AllowUserToDeleteRows = false; - this.gridEntryDataGridView.AllowUserToResizeRows = false; - this.gridEntryDataGridView.AutoGenerateColumns = false; - this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { + this.components = new System.ComponentModel.Container(); + System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); + this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components); + this.gridEntryDataGridView = new System.Windows.Forms.DataGridView(); + this.dataGridViewImageButtonBoxColumn1 = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); + this.dataGridViewImageColumn1 = new System.Windows.Forms.DataGridViewImageColumn(); + this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.dataGridViewImageButtonBoxColumn2 = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit(); + this.SuspendLayout(); + // + // gridEntryBindingSource + // + this.gridEntryBindingSource.DataSource = typeof(LibationWinForms.GridEntry); + // + // gridEntryDataGridView + // + this.gridEntryDataGridView.AllowUserToAddRows = false; + this.gridEntryDataGridView.AllowUserToDeleteRows = false; + this.gridEntryDataGridView.AllowUserToResizeRows = false; + this.gridEntryDataGridView.AutoGenerateColumns = false; + this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.dataGridViewImageButtonBoxColumn1, this.dataGridViewImageColumn1, this.dataGridViewTextBoxColumn1, @@ -76,147 +77,153 @@ this.dataGridViewTextBoxColumn10, this.dataGridViewTextBoxColumn11, this.dataGridViewImageButtonBoxColumn2}); - this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; - dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window; - dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText; - dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; - dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; - dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle1; - this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill; - 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.ReadOnly = true; - this.gridEntryDataGridView.RowHeadersVisible = false; - this.gridEntryDataGridView.RowTemplate.Height = 82; - this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); - this.gridEntryDataGridView.TabIndex = 0; - // - // dataGridViewImageButtonBoxColumn1 - // - this.dataGridViewImageButtonBoxColumn1.DataPropertyName = "Liberate"; - this.dataGridViewImageButtonBoxColumn1.HeaderText = "Liberate"; - this.dataGridViewImageButtonBoxColumn1.Name = "dataGridViewImageButtonBoxColumn1"; - this.dataGridViewImageButtonBoxColumn1.ReadOnly = true; - this.dataGridViewImageButtonBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageButtonBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - this.dataGridViewImageButtonBoxColumn1.Width = 75; - // - // dataGridViewImageColumn1 - // - this.dataGridViewImageColumn1.DataPropertyName = "Cover"; - this.dataGridViewImageColumn1.HeaderText = "Cover"; - this.dataGridViewImageColumn1.Name = "dataGridViewImageColumn1"; - this.dataGridViewImageColumn1.ReadOnly = true; - this.dataGridViewImageColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageColumn1.ToolTipText = "Cover Art"; - this.dataGridViewImageColumn1.Width = 80; - // - // dataGridViewTextBoxColumn1 - // - this.dataGridViewTextBoxColumn1.DataPropertyName = "Title"; - this.dataGridViewTextBoxColumn1.HeaderText = "Title"; - this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; - this.dataGridViewTextBoxColumn1.ReadOnly = true; - this.dataGridViewTextBoxColumn1.Width = 200; - // - // dataGridViewTextBoxColumn2 - // - this.dataGridViewTextBoxColumn2.DataPropertyName = "Authors"; - this.dataGridViewTextBoxColumn2.HeaderText = "Authors"; - this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; - this.dataGridViewTextBoxColumn2.ReadOnly = true; - // - // dataGridViewTextBoxColumn3 - // - this.dataGridViewTextBoxColumn3.DataPropertyName = "Narrators"; - this.dataGridViewTextBoxColumn3.HeaderText = "Narrators"; - this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; - this.dataGridViewTextBoxColumn3.ReadOnly = true; - // - // dataGridViewTextBoxColumn4 - // - this.dataGridViewTextBoxColumn4.DataPropertyName = "Length"; - this.dataGridViewTextBoxColumn4.HeaderText = "Length"; - this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; - this.dataGridViewTextBoxColumn4.ReadOnly = true; - this.dataGridViewTextBoxColumn4.ToolTipText = "Recording Length"; - // - // dataGridViewTextBoxColumn5 - // - this.dataGridViewTextBoxColumn5.DataPropertyName = "Series"; - this.dataGridViewTextBoxColumn5.HeaderText = "Series"; - this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; - this.dataGridViewTextBoxColumn5.ReadOnly = true; - // - // dataGridViewTextBoxColumn6 - // - this.dataGridViewTextBoxColumn6.DataPropertyName = "Description"; - this.dataGridViewTextBoxColumn6.HeaderText = "Description"; - this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; - this.dataGridViewTextBoxColumn6.ReadOnly = true; - // - // dataGridViewTextBoxColumn7 - // - this.dataGridViewTextBoxColumn7.DataPropertyName = "Category"; - this.dataGridViewTextBoxColumn7.HeaderText = "Category"; - this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; - this.dataGridViewTextBoxColumn7.ReadOnly = true; - // - // ProductRating - // - this.dataGridViewTextBoxColumn8.DataPropertyName = "ProductRating"; - this.dataGridViewTextBoxColumn8.HeaderText = "Product Rating"; - this.dataGridViewTextBoxColumn8.Name = "ProductRating"; - this.dataGridViewTextBoxColumn8.ReadOnly = true; - this.dataGridViewTextBoxColumn8.Width = 108; - // - // PurchaseDate - // - this.dataGridViewTextBoxColumn9.DataPropertyName = "PurchaseDate"; - this.dataGridViewTextBoxColumn9.HeaderText = "Purchase Date"; - this.dataGridViewTextBoxColumn9.Name = "PurchaseDate"; - this.dataGridViewTextBoxColumn9.ReadOnly = true; - // - // MyRating - // - this.dataGridViewTextBoxColumn10.DataPropertyName = "MyRating"; - this.dataGridViewTextBoxColumn10.HeaderText = "My Rating"; - this.dataGridViewTextBoxColumn10.Name = "MyRating"; - this.dataGridViewTextBoxColumn10.ReadOnly = true; - this.dataGridViewTextBoxColumn10.Width = 108; - // - // dataGridViewTextBoxColumn11 - // - this.dataGridViewTextBoxColumn11.DataPropertyName = "Misc"; - this.dataGridViewTextBoxColumn11.HeaderText = "Misc"; - this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11"; - this.dataGridViewTextBoxColumn11.ReadOnly = true; - this.dataGridViewTextBoxColumn11.Width = 135; - // - // dataGridViewImageButtonBoxColumn2 - // - this.dataGridViewImageButtonBoxColumn2.DataPropertyName = "DisplayTags"; - this.dataGridViewImageButtonBoxColumn2.HeaderText = "Tags and Details"; - this.dataGridViewImageButtonBoxColumn2.Name = "dataGridViewImageButtonBoxColumn2"; - this.dataGridViewImageButtonBoxColumn2.ReadOnly = true; - this.dataGridViewImageButtonBoxColumn2.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageButtonBoxColumn2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - // - // ProductsGrid - // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.gridEntryDataGridView); - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.Name = "ProductsGrid"; - this.Size = new System.Drawing.Size(1510, 380); - ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit(); - this.ResumeLayout(false); + this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1; + this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; + dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; + dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window; + dataGridViewCellStyle1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText; + dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight; + dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText; + dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True; + this.gridEntryDataGridView.DefaultCellStyle = dataGridViewCellStyle1; + this.gridEntryDataGridView.Dock = System.Windows.Forms.DockStyle.Fill; + 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.ReadOnly = true; + this.gridEntryDataGridView.RowHeadersVisible = false; + this.gridEntryDataGridView.RowTemplate.Height = 82; + this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); + this.gridEntryDataGridView.TabIndex = 0; + // + // dataGridViewImageButtonBoxColumn1 + // + this.dataGridViewImageButtonBoxColumn1.DataPropertyName = "Liberate"; + this.dataGridViewImageButtonBoxColumn1.HeaderText = "Liberate"; + this.dataGridViewImageButtonBoxColumn1.Name = "dataGridViewImageButtonBoxColumn1"; + this.dataGridViewImageButtonBoxColumn1.ReadOnly = true; + this.dataGridViewImageButtonBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewImageButtonBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.dataGridViewImageButtonBoxColumn1.Width = 75; + // + // dataGridViewImageColumn1 + // + this.dataGridViewImageColumn1.DataPropertyName = "Cover"; + this.dataGridViewImageColumn1.HeaderText = "Cover"; + this.dataGridViewImageColumn1.Name = "dataGridViewImageColumn1"; + this.dataGridViewImageColumn1.ReadOnly = true; + this.dataGridViewImageColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewImageColumn1.ToolTipText = "Cover Art"; + this.dataGridViewImageColumn1.Width = 80; + // + // dataGridViewTextBoxColumn1 + // + this.dataGridViewTextBoxColumn1.DataPropertyName = "Title"; + this.dataGridViewTextBoxColumn1.HeaderText = "Title"; + this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; + this.dataGridViewTextBoxColumn1.ReadOnly = true; + this.dataGridViewTextBoxColumn1.Width = 200; + // + // dataGridViewTextBoxColumn2 + // + this.dataGridViewTextBoxColumn2.DataPropertyName = "Authors"; + this.dataGridViewTextBoxColumn2.HeaderText = "Authors"; + this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; + this.dataGridViewTextBoxColumn2.ReadOnly = true; + // + // dataGridViewTextBoxColumn3 + // + this.dataGridViewTextBoxColumn3.DataPropertyName = "Narrators"; + this.dataGridViewTextBoxColumn3.HeaderText = "Narrators"; + this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; + this.dataGridViewTextBoxColumn3.ReadOnly = true; + // + // dataGridViewTextBoxColumn4 + // + this.dataGridViewTextBoxColumn4.DataPropertyName = "Length"; + this.dataGridViewTextBoxColumn4.HeaderText = "Length"; + this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; + this.dataGridViewTextBoxColumn4.ReadOnly = true; + this.dataGridViewTextBoxColumn4.ToolTipText = "Recording Length"; + // + // dataGridViewTextBoxColumn5 + // + this.dataGridViewTextBoxColumn5.DataPropertyName = "Series"; + this.dataGridViewTextBoxColumn5.HeaderText = "Series"; + this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; + this.dataGridViewTextBoxColumn5.ReadOnly = true; + // + // dataGridViewTextBoxColumn6 + // + this.dataGridViewTextBoxColumn6.DataPropertyName = "Description"; + this.dataGridViewTextBoxColumn6.HeaderText = "Description"; + this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; + this.dataGridViewTextBoxColumn6.ReadOnly = true; + // + // dataGridViewTextBoxColumn7 + // + this.dataGridViewTextBoxColumn7.DataPropertyName = "Category"; + this.dataGridViewTextBoxColumn7.HeaderText = "Category"; + this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; + this.dataGridViewTextBoxColumn7.ReadOnly = true; + // + // dataGridViewTextBoxColumn8 + // + this.dataGridViewTextBoxColumn8.DataPropertyName = "ProductRating"; + this.dataGridViewTextBoxColumn8.HeaderText = "Product Rating"; + this.dataGridViewTextBoxColumn8.Name = "dataGridViewTextBoxColumn8"; + this.dataGridViewTextBoxColumn8.ReadOnly = true; + this.dataGridViewTextBoxColumn8.Width = 108; + // + // dataGridViewTextBoxColumn9 + // + this.dataGridViewTextBoxColumn9.DataPropertyName = "PurchaseDate"; + this.dataGridViewTextBoxColumn9.HeaderText = "Purchase Date"; + this.dataGridViewTextBoxColumn9.Name = "dataGridViewTextBoxColumn9"; + this.dataGridViewTextBoxColumn9.ReadOnly = true; + // + // dataGridViewTextBoxColumn10 + // + this.dataGridViewTextBoxColumn10.DataPropertyName = "MyRating"; + this.dataGridViewTextBoxColumn10.HeaderText = "My Rating"; + this.dataGridViewTextBoxColumn10.Name = "dataGridViewTextBoxColumn10"; + this.dataGridViewTextBoxColumn10.ReadOnly = true; + this.dataGridViewTextBoxColumn10.Width = 108; + // + // dataGridViewTextBoxColumn11 + // + this.dataGridViewTextBoxColumn11.DataPropertyName = "Misc"; + this.dataGridViewTextBoxColumn11.HeaderText = "Misc"; + this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11"; + this.dataGridViewTextBoxColumn11.ReadOnly = true; + this.dataGridViewTextBoxColumn11.Width = 135; + // + // dataGridViewImageButtonBoxColumn2 + // + this.dataGridViewImageButtonBoxColumn2.DataPropertyName = "DisplayTags"; + this.dataGridViewImageButtonBoxColumn2.HeaderText = "Tags and Details"; + this.dataGridViewImageButtonBoxColumn2.Name = "dataGridViewImageButtonBoxColumn2"; + this.dataGridViewImageButtonBoxColumn2.ReadOnly = true; + this.dataGridViewImageButtonBoxColumn2.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.dataGridViewImageButtonBoxColumn2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(181, 26); + // + // ProductsGrid + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.gridEntryDataGridView); + this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.Name = "ProductsGrid"; + this.Size = new System.Drawing.Size(1510, 380); + ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).EndInit(); + this.ResumeLayout(false); } @@ -238,5 +245,6 @@ private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn10; private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11; private EditTagsDataGridViewImageButtonColumn dataGridViewImageButtonBoxColumn2; - } + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + } } diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index d5c0dc52..e6d71366 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -8,6 +8,7 @@ using Dinah.Core; using Dinah.Core.DataBinding; using Dinah.Core.Threading; using Dinah.Core.Windows.Forms; +using LibationFileManager; using LibationWinForms.Dialogs; namespace LibationWinForms @@ -38,12 +39,61 @@ namespace LibationWinForms { InitializeComponent(); + var hiddenGridEntries = Configuration.Instance.HiddenGridColumns; + + contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); + contextMenuStrip1.Items.Add(new ToolStripSeparator()); + + foreach (DataGridViewColumn column in _dataGridView.Columns) + { + var visible = !hiddenGridEntries.Contains(column.DataPropertyName); + + var itemName = column.DataPropertyName; + + var menuItem = new ToolStripMenuItem() + { + Text = itemName, + Checked = visible, + Tag = itemName + }; + menuItem.Click += HideMenuItem_Click; + contextMenuStrip1.Items.Add(menuItem); + + column.Visible = visible; + } + // sorting breaks filters. must reapply filters after sorting _dataGridView.Sorted += Filter; _dataGridView.CellContentClick += DataGridView_CellContentClick; EnableDoubleBuffering(); } + + private void HideMenuItem_Click(object sender, EventArgs e) + { + var menuItem = sender as ToolStripMenuItem; + var propertyName = menuItem.Tag as string; + + var column = _dataGridView.Columns.Cast().FirstOrDefault(c => c.DataPropertyName == propertyName); + + if (column != null) + { + var visible = menuItem.Checked; + menuItem.Checked = !visible; + column.Visible = !visible; + + var config = Configuration.Instance; + + var hiddenColumns = new List(config.HiddenGridColumns); + + if (column.Visible && hiddenColumns.Contains(propertyName)) + hiddenColumns.Remove(propertyName); + else if (!hiddenColumns.Contains(propertyName)) + hiddenColumns.Add(propertyName); + + config.HiddenGridColumns = hiddenColumns.ToArray(); + } + } private void EnableDoubleBuffering() { var propertyInfo = _dataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); @@ -225,5 +275,6 @@ namespace LibationWinForms #region DataGridView Macro private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex); #endregion + } } diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/grid/ProductsGrid.resx index 6ee0745a..cc951239 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.resx +++ b/Source/LibationWinForms/grid/ProductsGrid.resx @@ -1,5 +1,4 @@ - - + @@ -61,4 +60,7 @@ 17, 17 + + 197, 17 + \ No newline at end of file From 9fe95bbddcf5ac157c28dbb598e219f8202501ea Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 13:21:10 -0600 Subject: [PATCH 02/27] Add option to reorder ProductsGrid columns --- Source/AppScaffolding/LibationScaffolding.cs | 6 +++ Source/LibationFileManager/Configuration.cs | 7 ++++ .../grid/ProductsGrid.Designer.cs | 4 +- Source/LibationWinForms/grid/ProductsGrid.cs | 37 ++++++++++++------- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index 63818d6d..493b5964 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -128,6 +128,12 @@ namespace AppScaffolding if (!config.Exists(nameof(config.HiddenGridColumns))) config.HiddenGridColumns = Array.Empty(); + + if (!config.Exists(nameof(config.GridColumnsDisplayIndices))) + { + int startIndex = 0; + config.GridColumnsDisplayIndices = new int[30].Select(_ => startIndex++).ToArray(); + } } /// Initialize logging. Run after migration diff --git a/Source/LibationFileManager/Configuration.cs b/Source/LibationFileManager/Configuration.cs index 0a18b770..c9610fb1 100644 --- a/Source/LibationFileManager/Configuration.cs +++ b/Source/LibationFileManager/Configuration.cs @@ -187,6 +187,13 @@ namespace LibationFileManager set => persistentDictionary.SetNonString(nameof(HiddenGridColumns), value); } + [Description("A DisplayIndex list of columns in ProductsGrid")] + public int[] GridColumnsDisplayIndices + { + get => persistentDictionary.GetNonString(nameof(GridColumnsDisplayIndices)); + set => persistentDictionary.SetNonString(nameof(GridColumnsDisplayIndices), value); + } + public enum BadBookAction { [Description("Ask each time what action to take.")] diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index 0aec4e05..fa993918 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -59,6 +59,7 @@ // this.gridEntryDataGridView.AllowUserToAddRows = false; this.gridEntryDataGridView.AllowUserToDeleteRows = false; + this.gridEntryDataGridView.AllowUserToOrderColumns = true; this.gridEntryDataGridView.AllowUserToResizeRows = false; this.gridEntryDataGridView.AutoGenerateColumns = false; this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; @@ -96,6 +97,7 @@ this.gridEntryDataGridView.RowTemplate.Height = 82; this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); this.gridEntryDataGridView.TabIndex = 0; + this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged); // // dataGridViewImageButtonBoxColumn1 // @@ -211,7 +213,7 @@ // contextMenuStrip1 // this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(181, 26); + this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); // // ProductsGrid // diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index e6d71366..aa12f2b8 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -39,15 +39,17 @@ namespace LibationWinForms { InitializeComponent(); - var hiddenGridEntries = Configuration.Instance.HiddenGridColumns; + //Restore Grid Display Settings + var config = Configuration.Instance; + var displayIndices = config.GridColumnsDisplayIndices; contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); contextMenuStrip1.Items.Add(new ToolStripSeparator()); + var columnIndex = 0; foreach (DataGridViewColumn column in _dataGridView.Columns) { - var visible = !hiddenGridEntries.Contains(column.DataPropertyName); - + var visible = !config.HiddenGridColumns.Contains(column.DataPropertyName); var itemName = column.DataPropertyName; var menuItem = new ToolStripMenuItem() @@ -60,6 +62,7 @@ namespace LibationWinForms contextMenuStrip1.Items.Add(menuItem); column.Visible = visible; + column.DisplayIndex = displayIndices[columnIndex++]; } // sorting breaks filters. must reapply filters after sorting @@ -74,7 +77,9 @@ namespace LibationWinForms var menuItem = sender as ToolStripMenuItem; var propertyName = menuItem.Tag as string; - var column = _dataGridView.Columns.Cast().FirstOrDefault(c => c.DataPropertyName == propertyName); + var column = _dataGridView.Columns + .Cast() + .FirstOrDefault(c => c.DataPropertyName == propertyName); if (column != null) { @@ -82,16 +87,12 @@ namespace LibationWinForms menuItem.Checked = !visible; column.Visible = !visible; - var config = Configuration.Instance; - - var hiddenColumns = new List(config.HiddenGridColumns); - - if (column.Visible && hiddenColumns.Contains(propertyName)) - hiddenColumns.Remove(propertyName); - else if (!hiddenColumns.Contains(propertyName)) - hiddenColumns.Add(propertyName); - - config.HiddenGridColumns = hiddenColumns.ToArray(); + Configuration.Instance.HiddenGridColumns = + _dataGridView.Columns + .Cast() + .Where(c=>!c.Visible) + .Select(c => c.DataPropertyName) + .ToArray(); } } private void EnableDoubleBuffering() @@ -276,5 +277,13 @@ namespace LibationWinForms private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex); #endregion + private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e) + { + Configuration.Instance.GridColumnsDisplayIndices + = _dataGridView.Columns + .Cast() + .Select(c => c.DisplayIndex) + .ToArray(); + } } } From 19262bceac296f9589306e9947a4180815cb9f64 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 14:16:14 -0600 Subject: [PATCH 03/27] Fix display issue if all columns are hidden on startup --- .../grid/ProductsGrid.Designer.cs | 1 - Source/LibationWinForms/grid/ProductsGrid.cs | 36 ++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index fa993918..b6659e37 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -78,7 +78,6 @@ this.dataGridViewTextBoxColumn10, this.dataGridViewTextBoxColumn11, this.dataGridViewImageButtonBoxColumn2}); - this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1; this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window; diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index aa12f2b8..341b650f 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -35,21 +35,20 @@ namespace LibationWinForms // alias private DataGridView _dataGridView => gridEntryDataGridView; - public ProductsGrid() + protected override void OnVisibleChanged(EventArgs e) { - InitializeComponent(); + contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); + contextMenuStrip1.Items.Add(new ToolStripSeparator()); //Restore Grid Display Settings var config = Configuration.Instance; var displayIndices = config.GridColumnsDisplayIndices; + var hiddenGridColumns = config.HiddenGridColumns; - contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); - contextMenuStrip1.Items.Add(new ToolStripSeparator()); - - var columnIndex = 0; + int columnIndex = 0, numVisible = 0; foreach (DataGridViewColumn column in _dataGridView.Columns) - { - var visible = !config.HiddenGridColumns.Contains(column.DataPropertyName); + { + var visible = !hiddenGridColumns.Contains(column.DataPropertyName); var itemName = column.DataPropertyName; var menuItem = new ToolStripMenuItem() @@ -63,8 +62,23 @@ namespace LibationWinForms column.Visible = visible; column.DisplayIndex = displayIndices[columnIndex++]; + column.HeaderCell.ContextMenuStrip = contextMenuStrip1; + + if (visible) numVisible++; } + if (numVisible == 0) + { + _dataGridView.ContextMenuStrip = contextMenuStrip1; + } + + base.OnVisibleChanged(e); + } + + public ProductsGrid() + { + InitializeComponent(); + // sorting breaks filters. must reapply filters after sorting _dataGridView.Sorted += Filter; _dataGridView.CellContentClick += DataGridView_CellContentClick; @@ -93,6 +107,12 @@ namespace LibationWinForms .Where(c=>!c.Visible) .Select(c => c.DataPropertyName) .ToArray(); + + _dataGridView.ContextMenuStrip = + _dataGridView.Columns + .Cast() + .Where(c => c.Visible).Any() ? + default(ContextMenuStrip) : contextMenuStrip1; } } private void EnableDoubleBuffering() From 725979afb087836d7650cfdf9e988f3144f05b7a Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 14:38:14 -0600 Subject: [PATCH 04/27] Improve Context Menu performance. --- .../grid/ProductsGrid.Designer.cs | 1 + Source/LibationWinForms/grid/ProductsGrid.cs | 151 ++++++++++-------- 2 files changed, 81 insertions(+), 71 deletions(-) diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index b6659e37..fa993918 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -78,6 +78,7 @@ this.dataGridViewTextBoxColumn10, this.dataGridViewTextBoxColumn11, this.dataGridViewImageButtonBoxColumn2}); + this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1; this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window; diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index 341b650f..a828ed81 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; @@ -33,51 +34,11 @@ namespace LibationWinForms public event EventHandler VisibleCountChanged; // alias - private DataGridView _dataGridView => gridEntryDataGridView; - - protected override void OnVisibleChanged(EventArgs e) - { - contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); - contextMenuStrip1.Items.Add(new ToolStripSeparator()); - - //Restore Grid Display Settings - var config = Configuration.Instance; - var displayIndices = config.GridColumnsDisplayIndices; - var hiddenGridColumns = config.HiddenGridColumns; - - int columnIndex = 0, numVisible = 0; - foreach (DataGridViewColumn column in _dataGridView.Columns) - { - var visible = !hiddenGridColumns.Contains(column.DataPropertyName); - var itemName = column.DataPropertyName; - - var menuItem = new ToolStripMenuItem() - { - Text = itemName, - Checked = visible, - Tag = itemName - }; - menuItem.Click += HideMenuItem_Click; - contextMenuStrip1.Items.Add(menuItem); - - column.Visible = visible; - column.DisplayIndex = displayIndices[columnIndex++]; - column.HeaderCell.ContextMenuStrip = contextMenuStrip1; - - if (visible) numVisible++; - } - - if (numVisible == 0) - { - _dataGridView.ContextMenuStrip = contextMenuStrip1; - } - - base.OnVisibleChanged(e); - } + private DataGridView _dataGridView => gridEntryDataGridView; public ProductsGrid() { - InitializeComponent(); + InitializeComponent(); // sorting breaks filters. must reapply filters after sorting _dataGridView.Sorted += Filter; @@ -86,35 +47,6 @@ namespace LibationWinForms EnableDoubleBuffering(); } - private void HideMenuItem_Click(object sender, EventArgs e) - { - var menuItem = sender as ToolStripMenuItem; - var propertyName = menuItem.Tag as string; - - var column = _dataGridView.Columns - .Cast() - .FirstOrDefault(c => c.DataPropertyName == propertyName); - - if (column != null) - { - var visible = menuItem.Checked; - menuItem.Checked = !visible; - column.Visible = !visible; - - Configuration.Instance.HiddenGridColumns = - _dataGridView.Columns - .Cast() - .Where(c=>!c.Visible) - .Select(c => c.DataPropertyName) - .ToArray(); - - _dataGridView.ContextMenuStrip = - _dataGridView.Columns - .Cast() - .Where(c => c.Visible).Any() ? - default(ContextMenuStrip) : contextMenuStrip1; - } - } private void EnableDoubleBuffering() { var propertyInfo = _dataGridView.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); @@ -297,6 +229,73 @@ namespace LibationWinForms private GridEntry getGridEntry(int rowIndex) => _dataGridView.GetBoundItem(rowIndex); #endregion + #region Column Customizations + + protected override void OnVisibleChanged(EventArgs e) + { + contextMenuStrip1.Items.Add(new ToolStripLabel("Show / Hide Columns")); + contextMenuStrip1.Items.Add(new ToolStripSeparator()); + + //Restore Grid Display Settings + var config = Configuration.Instance; + var displayIndices = config.GridColumnsDisplayIndices; + var hiddenGridColumns = config.HiddenGridColumns; + + var cmsKiller = new ContextMenuStrip(); + + int columnIndex = 0; + foreach (DataGridViewColumn column in _dataGridView.Columns) + { + var visible = !hiddenGridColumns.Contains(column.DataPropertyName); + var itemName = column.DataPropertyName; + + var menuItem = new ToolStripMenuItem() + { + Text = itemName, + Checked = visible, + Tag = itemName + }; + menuItem.Click += HideMenuItem_Click; + contextMenuStrip1.Items.Add(menuItem); + + column.Visible = visible; + column.DisplayIndex = displayIndices[columnIndex++]; + column.HeaderCell.ContextMenuStrip = contextMenuStrip1; + + //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; + } + + base.OnVisibleChanged(e); + } + + private void HideMenuItem_Click(object sender, EventArgs e) + { + var menuItem = sender as ToolStripMenuItem; + var propertyName = menuItem.Tag as string; + + var column = _dataGridView.Columns + .Cast() + .FirstOrDefault(c => c.DataPropertyName == propertyName); + + if (column != null) + { + var visible = menuItem.Checked; + menuItem.Checked = !visible; + column.Visible = !visible; + + Configuration.Instance.HiddenGridColumns = + _dataGridView.Columns + .Cast() + .Where(c => !c.Visible) + .Select(c => c.DataPropertyName) + .ToArray(); + } + } + private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e) { Configuration.Instance.GridColumnsDisplayIndices @@ -305,5 +304,15 @@ namespace LibationWinForms .Select(c => c.DisplayIndex) .ToArray(); } + + #endregion + } + + class ContextMenuStripEx : ContextMenuStrip + { + protected override ToolStripItem CreateDefaultItem(string text, Image image, EventHandler onClick) + { + return base.CreateDefaultItem(text, image, onClick); + } } } From 30feb42ed8081364b572fcc99228ac6cdab6451a Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 15:30:18 -0600 Subject: [PATCH 05/27] Add setting to persist ProductsGrid column widths --- Source/AppScaffolding/LibationScaffolding.cs | 10 +- Source/FileManager/PersistentDictionary.cs | 383 +++++++++--------- Source/LibationFileManager/Configuration.cs | 19 +- .../grid/ProductsGrid.Designer.cs | 1 + Source/LibationWinForms/grid/ProductsGrid.cs | 58 +-- 5 files changed, 240 insertions(+), 231 deletions(-) diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index 493b5964..21daf970 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -127,13 +127,13 @@ namespace AppScaffolding config.AutoScan = true; if (!config.Exists(nameof(config.HiddenGridColumns))) - config.HiddenGridColumns = Array.Empty(); + config.HiddenGridColumns = new Dictionary(); if (!config.Exists(nameof(config.GridColumnsDisplayIndices))) - { - int startIndex = 0; - config.GridColumnsDisplayIndices = new int[30].Select(_ => startIndex++).ToArray(); - } + config.GridColumnsDisplayIndices = new Dictionary(); + + if (!config.Exists(nameof(config.GridColumnsWidths))) + config.GridColumnsWidths = new Dictionary(); } /// Initialize logging. Run after migration diff --git a/Source/FileManager/PersistentDictionary.cs b/Source/FileManager/PersistentDictionary.cs index 0073a705..53e87c9a 100644 --- a/Source/FileManager/PersistentDictionary.cs +++ b/Source/FileManager/PersistentDictionary.cs @@ -7,237 +7,236 @@ using Newtonsoft.Json.Linq; namespace FileManager { - public class PersistentDictionary - { - public string Filepath { get; } - public bool IsReadOnly { get; } + public class PersistentDictionary + { + public string Filepath { get; } + public bool IsReadOnly { get; } - // optimize for strings. expectation is most settings will be strings and a rare exception will be something else - private Dictionary stringCache { get; } = new Dictionary(); - private Dictionary objectCache { get; } = new Dictionary(); + // optimize for strings. expectation is most settings will be strings and a rare exception will be something else + private Dictionary stringCache { get; } = new Dictionary(); + private Dictionary objectCache { get; } = new Dictionary(); - public PersistentDictionary(string filepath, bool isReadOnly = false) - { - Filepath = filepath; - IsReadOnly = isReadOnly; + public PersistentDictionary(string filepath, bool isReadOnly = false) + { + Filepath = filepath; + IsReadOnly = isReadOnly; - if (File.Exists(Filepath)) - return; + if (File.Exists(Filepath)) + return; - // will create any missing directories, incl subdirectories. if all already exist: no action - Directory.CreateDirectory(Path.GetDirectoryName(filepath)); + // will create any missing directories, incl subdirectories. if all already exist: no action + Directory.CreateDirectory(Path.GetDirectoryName(filepath)); - if (IsReadOnly) - return; + if (IsReadOnly) + return; - createNewFile(); - } + createNewFile(); + } - public string GetString(string propertyName) - { - if (!stringCache.ContainsKey(propertyName)) - { - var jObject = readFile(); - if (!jObject.ContainsKey(propertyName)) - return null; - stringCache[propertyName] = jObject[propertyName].Value(); - } + public string GetString(string propertyName) + { + if (!stringCache.ContainsKey(propertyName)) + { + var jObject = readFile(); + if (!jObject.ContainsKey(propertyName)) + return null; + stringCache[propertyName] = jObject[propertyName].Value(); + } - return stringCache[propertyName]; - } + return stringCache[propertyName]; + } - public T GetNonString(string propertyName) - { - var obj = GetObject(propertyName); - if (obj is null) return default; - if (obj is JValue jValue) return jValue.Value(); - if (obj is JObject jObject) return jObject.ToObject(); - if (obj is JArray jArray && typeof(T).IsArray) return jArray.ToObject(); - return (T)obj; - } + public T GetNonString(string propertyName) + { + var obj = GetObject(propertyName); + if (obj is null) return default; + if (obj is JValue jValue) return jValue.Value(); + if (obj is JObject jObject) return jObject.ToObject(); + return (T)obj; + } - public object GetObject(string propertyName) - { - if (!objectCache.ContainsKey(propertyName)) - { - var jObject = readFile(); - if (!jObject.ContainsKey(propertyName)) - return null; - objectCache[propertyName] = jObject[propertyName].Value(); - } + public object GetObject(string propertyName) + { + if (!objectCache.ContainsKey(propertyName)) + { + var jObject = readFile(); + if (!jObject.ContainsKey(propertyName)) + return null; + objectCache[propertyName] = jObject[propertyName].Value(); + } - return objectCache[propertyName]; - } + return objectCache[propertyName]; + } - public string GetStringFromJsonPath(string jsonPath, string propertyName) => GetStringFromJsonPath($"{jsonPath}.{propertyName}"); - public string GetStringFromJsonPath(string jsonPath) - { - if (!stringCache.ContainsKey(jsonPath)) - { - try - { - var jObject = readFile(); - var token = jObject.SelectToken(jsonPath); - if (token is null) - return null; - stringCache[jsonPath] = (string)token; - } - catch - { - return null; - } - } + public string GetStringFromJsonPath(string jsonPath, string propertyName) => GetStringFromJsonPath($"{jsonPath}.{propertyName}"); + public string GetStringFromJsonPath(string jsonPath) + { + if (!stringCache.ContainsKey(jsonPath)) + { + try + { + var jObject = readFile(); + var token = jObject.SelectToken(jsonPath); + if (token is null) + return null; + stringCache[jsonPath] = (string)token; + } + catch + { + return null; + } + } - return stringCache[jsonPath]; - } + return stringCache[jsonPath]; + } - public bool Exists(string propertyName) => readFile().ContainsKey(propertyName); + public bool Exists(string propertyName) => readFile().ContainsKey(propertyName); - private object locker { get; } = new object(); - public void SetString(string propertyName, string newValue) - { - // only do this check in string cache, NOT object cache - if (stringCache.ContainsKey(propertyName) && stringCache[propertyName] == newValue) - return; + private object locker { get; } = new object(); + public void SetString(string propertyName, string newValue) + { + // only do this check in string cache, NOT object cache + if (stringCache.ContainsKey(propertyName) && stringCache[propertyName] == newValue) + return; - // set cache - stringCache[propertyName] = newValue; + // set cache + stringCache[propertyName] = newValue; - writeFile(propertyName, newValue); - } + writeFile(propertyName, newValue); + } - public void SetNonString(string propertyName, object newValue) - { - // set cache - objectCache[propertyName] = newValue; + public void SetNonString(string propertyName, object newValue) + { + // set cache + objectCache[propertyName] = newValue; - var parsedNewValue = JToken.Parse(JsonConvert.SerializeObject(newValue)); - writeFile(propertyName, parsedNewValue); - } + var parsedNewValue = JToken.Parse(JsonConvert.SerializeObject(newValue)); + writeFile(propertyName, parsedNewValue); + } - private void writeFile(string propertyName, JToken newValue) - { - if (IsReadOnly) - return; + private void writeFile(string propertyName, JToken newValue) + { + if (IsReadOnly) + return; - // write new setting to file - lock (locker) - { - var jObject = readFile(); - var startContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); + // write new setting to file + lock (locker) + { + var jObject = readFile(); + var startContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); - jObject[propertyName] = newValue; - var endContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); + jObject[propertyName] = newValue; + var endContents = JsonConvert.SerializeObject(jObject, Formatting.Indented); - if (startContents == endContents) - return; + if (startContents == endContents) + return; + + File.WriteAllText(Filepath, endContents); + } - File.WriteAllText(Filepath, endContents); - } + try + { + var str = formatValueForLog(newValue?.ToString()); + Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { propertyName, newValue = str }); + } + catch { } + } - try - { - var str = formatValueForLog(newValue?.ToString()); - Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { propertyName, newValue = str }); - } - catch { } - } + /// WILL ONLY set if already present. WILL NOT create new + /// Value was changed + public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false) + { + if (IsReadOnly) + return false; - /// WILL ONLY set if already present. WILL NOT create new - /// Value was changed - public bool SetWithJsonPath(string jsonPath, string propertyName, string newValue, bool suppressLogging = false) - { - if (IsReadOnly) - return false; + var path = $"{jsonPath}.{propertyName}"; - var path = $"{jsonPath}.{propertyName}"; + { + // only do this check in string cache, NOT object cache + if (stringCache.ContainsKey(path) && stringCache[path] == newValue) + return false; - { - // only do this check in string cache, NOT object cache - if (stringCache.ContainsKey(path) && stringCache[path] == newValue) - return false; + // set cache + stringCache[path] = newValue; + } - // set cache - stringCache[path] = newValue; - } + try + { + lock (locker) + { + var jObject = readFile(); + var token = jObject.SelectToken(jsonPath); + if (token is null || token[propertyName] is null) + return false; - try - { - lock (locker) - { - var jObject = readFile(); - var token = jObject.SelectToken(jsonPath); - if (token is null || token[propertyName] is null) - return false; + var oldValue = token.Value(propertyName); + if (oldValue == newValue) + return false; - var oldValue = token.Value(propertyName); - if (oldValue == newValue) - return false; + token[propertyName] = newValue; + File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented)); + } + } + catch (Exception exDebug) + { + return false; + } - token[propertyName] = newValue; - File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented)); - } - } - catch (Exception exDebug) - { - return false; - } + if (!suppressLogging) + { + try + { + var str = formatValueForLog(newValue?.ToString()); + Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { jsonPath, propertyName, newValue = str }); + } + catch { } + } - if (!suppressLogging) - { - try - { - var str = formatValueForLog(newValue?.ToString()); - Serilog.Log.Logger.Information("Config changed. {@DebugInfo}", new { jsonPath, propertyName, newValue = str }); - } - catch { } - } + return true; + } - return true; - } + private static string formatValueForLog(string value) + => value is null ? "[null]" + : string.IsNullOrEmpty(value) ? "[empty]" + : string.IsNullOrWhiteSpace(value) ? $"[whitespace. Length={value.Length}]" + : value.Length > 100 ? $"[Length={value.Length}] {value[0..50]}...{value[^50..^0]}" + : value; - private static string formatValueForLog(string value) - => value is null ? "[null]" - : string.IsNullOrEmpty(value) ? "[empty]" - : string.IsNullOrWhiteSpace(value) ? $"[whitespace. Length={value.Length}]" - : value.Length > 100 ? $"[Length={value.Length}] {value[0..50]}...{value[^50..^0]}" - : value; + private JObject readFile() + { + if (!File.Exists(Filepath)) + { + var msg = "Unrecoverable error. Settings file cannot be found"; + var ex = new FileNotFoundException(msg, Filepath); + Serilog.Log.Logger.Error(ex, msg); + throw ex; + } - private JObject readFile() - { - if (!File.Exists(Filepath)) - { - var msg = "Unrecoverable error. Settings file cannot be found"; - var ex = new FileNotFoundException(msg, Filepath); - Serilog.Log.Logger.Error(ex, msg); - throw ex; - } + var settingsJsonContents = File.ReadAllText(Filepath); - var settingsJsonContents = File.ReadAllText(Filepath); + if (string.IsNullOrWhiteSpace(settingsJsonContents)) + { + createNewFile(); + settingsJsonContents = File.ReadAllText(Filepath); + } - if (string.IsNullOrWhiteSpace(settingsJsonContents)) - { - createNewFile(); - settingsJsonContents = File.ReadAllText(Filepath); - } + var jObject = JsonConvert.DeserializeObject(settingsJsonContents); - var jObject = JsonConvert.DeserializeObject(settingsJsonContents); + if (jObject is null) + { + var msg = "Unrecoverable error. Unable to read settings from Settings file"; + var ex = new NullReferenceException(msg); + Serilog.Log.Logger.Error(ex, msg); + throw ex; + } - if (jObject is null) - { - var msg = "Unrecoverable error. Unable to read settings from Settings file"; - var ex = new NullReferenceException(msg); - Serilog.Log.Logger.Error(ex, msg); - throw ex; - } + return jObject; + } - return jObject; - } - - private void createNewFile() - { - File.WriteAllText(Filepath, "{}"); - System.Threading.Thread.Sleep(100); - } - } + private void createNewFile() + { + File.WriteAllText(Filepath, "{}"); + System.Threading.Thread.Sleep(100); + } + } } diff --git a/Source/LibationFileManager/Configuration.cs b/Source/LibationFileManager/Configuration.cs index c9610fb1..874f49ab 100644 --- a/Source/LibationFileManager/Configuration.cs +++ b/Source/LibationFileManager/Configuration.cs @@ -180,20 +180,27 @@ namespace LibationFileManager set => persistentDictionary.SetNonString(nameof(LameVBRQuality), value); } - [Description("A list of GridView data property names whose columns should be hidden in ProductsGrid")] - public string[] HiddenGridColumns + [Description("A Dictionary of GridView data property names and bool indicating its column's visibility in ProductsGrid")] + public Dictionary HiddenGridColumns { - get => persistentDictionary.GetNonString(nameof(HiddenGridColumns)); + get => persistentDictionary.GetNonString>(nameof(HiddenGridColumns)); set => persistentDictionary.SetNonString(nameof(HiddenGridColumns), value); } - [Description("A DisplayIndex list of columns in ProductsGrid")] - public int[] GridColumnsDisplayIndices + [Description("A Dictionary of GridView data property names and int indicating its column's display index in ProductsGrid")] + public Dictionary GridColumnsDisplayIndices { - get => persistentDictionary.GetNonString(nameof(GridColumnsDisplayIndices)); + get => persistentDictionary.GetNonString>(nameof(GridColumnsDisplayIndices)); set => persistentDictionary.SetNonString(nameof(GridColumnsDisplayIndices), value); } + [Description("A Dictionary of GridView data property names and int indicating its column's width in ProductsGrid")] + public Dictionary GridColumnsWidths + { + get => persistentDictionary.GetNonString>(nameof(GridColumnsWidths)); + set => persistentDictionary.SetNonString(nameof(GridColumnsWidths), value); + } + public enum BadBookAction { [Description("Ask each time what action to take.")] diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index fa993918..202fc078 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -98,6 +98,7 @@ this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); this.gridEntryDataGridView.TabIndex = 0; this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged); + this.gridEntryDataGridView.ColumnWidthChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnWidthChanged); // // dataGridViewImageButtonBoxColumn1 // diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index a828ed81..f28d0449 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -34,7 +34,7 @@ namespace LibationWinForms public event EventHandler VisibleCountChanged; // alias - private DataGridView _dataGridView => gridEntryDataGridView; + private DataGridView _dataGridView => gridEntryDataGridView; public ProductsGrid() { @@ -238,16 +238,16 @@ namespace LibationWinForms //Restore Grid Display Settings var config = Configuration.Instance; - var displayIndices = config.GridColumnsDisplayIndices; var hiddenGridColumns = config.HiddenGridColumns; + var displayIndices = config.GridColumnsDisplayIndices; + var gridColumnsWidths = config.GridColumnsWidths; var cmsKiller = new ContextMenuStrip(); - int columnIndex = 0; foreach (DataGridViewColumn column in _dataGridView.Columns) { - var visible = !hiddenGridColumns.Contains(column.DataPropertyName); var itemName = column.DataPropertyName; + var visible = !hiddenGridColumns.GetValueOrDefault(itemName, false); var menuItem = new ToolStripMenuItem() { @@ -259,7 +259,9 @@ namespace LibationWinForms contextMenuStrip1.Items.Add(menuItem); column.Visible = visible; - column.DisplayIndex = displayIndices[columnIndex++]; + column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index); + column.Width = gridColumnsWidths.GetValueOrDefault(itemName, column.Width); + column.MinimumWidth = 10; column.HeaderCell.ContextMenuStrip = contextMenuStrip1; //Setting a default ContextMenuStrip will allow the columns to handle the @@ -272,6 +274,24 @@ namespace LibationWinForms 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; @@ -287,32 +307,14 @@ namespace LibationWinForms menuItem.Checked = !visible; column.Visible = !visible; - Configuration.Instance.HiddenGridColumns = - _dataGridView.Columns - .Cast() - .Where(c => !c.Visible) - .Select(c => c.DataPropertyName) - .ToArray(); - } - } + var config = Configuration.Instance; - private void gridEntryDataGridView_ColumnDisplayIndexChanged(object sender, DataGridViewColumnEventArgs e) - { - Configuration.Instance.GridColumnsDisplayIndices - = _dataGridView.Columns - .Cast() - .Select(c => c.DisplayIndex) - .ToArray(); + var dictionary = config.HiddenGridColumns; + dictionary[propertyName] = visible; + config.HiddenGridColumns = dictionary; + } } #endregion } - - class ContextMenuStripEx : ContextMenuStrip - { - protected override ToolStripItem CreateDefaultItem(string text, Image image, EventHandler onClick) - { - return base.CreateDefaultItem(text, image, onClick); - } - } } From 1c9ea0a7109c059bcc55678105678c02ab8f202a Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 15:44:37 -0600 Subject: [PATCH 06/27] No text trimming since columns are enlargeable --- Source/LibationWinForms/grid/GridEntry.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index 04283952..b1c7f088 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -263,11 +263,7 @@ namespace LibationWinForms { var doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(book?.Description ?? ""); - var noHtml = doc.DocumentNode.InnerText; - return - noHtml.Length < 63 ? - noHtml : - noHtml.Substring(0, 60) + "..."; + return doc.DocumentNode.InnerText; } /// From 201ecebda91004746340ab06fedcba732df54956 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 16:44:44 -0600 Subject: [PATCH 07/27] Show full book description when Description cell is clicked. --- .../grid/DescriptionDisplay.Designer.cs | 63 ++++ .../grid/DescriptionDisplay.cs | 42 +++ .../grid/DescriptionDisplay.resx | 60 ++++ Source/LibationWinForms/grid/GridEntry.cs | 13 +- .../grid/ProductsGrid.Designer.cs | 307 +++++++++--------- Source/LibationWinForms/grid/ProductsGrid.cs | 31 +- .../LibationWinForms/grid/ProductsGrid.resx | 3 + 7 files changed, 353 insertions(+), 166 deletions(-) create mode 100644 Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs create mode 100644 Source/LibationWinForms/grid/DescriptionDisplay.cs create mode 100644 Source/LibationWinForms/grid/DescriptionDisplay.resx diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs new file mode 100644 index 00000000..061695bf --- /dev/null +++ b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs @@ -0,0 +1,63 @@ +namespace LibationWinForms +{ + partial class DescriptionDisplay + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill; + this.textBox1.Location = new System.Drawing.Point(0, 0); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(413, 162); + this.textBox1.TabIndex = 0; + // + // DescriptionDisplay + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(413, 162); + this.Controls.Add(this.textBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.Name = "DescriptionDisplay"; + this.Text = "DescriptionDisplay"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + public System.Windows.Forms.TextBox textBox1; + } +} \ No newline at end of file diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/grid/DescriptionDisplay.cs new file mode 100644 index 00000000..0bca3fc7 --- /dev/null +++ b/Source/LibationWinForms/grid/DescriptionDisplay.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace LibationWinForms +{ + public partial class DescriptionDisplay : Form + { + public DescriptionDisplay() + { + InitializeComponent(); + textBox1.LostFocus += (_, _) => Close(); + this.Shown += DescriptionDisplay_Shown; + + var textHeight = TextRenderer.MeasureText("\n", textBox1.Font).Height; + } + + [DllImport("user32.dll")] + static extern bool HideCaret(IntPtr hWnd); + + private void DescriptionDisplay_Shown(object sender, EventArgs e) + { + textBox1.DeselectAll(); + HideCaret(textBox1.Handle); + } + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + int lineCount = textBox1.GetLineFromCharIndex(int.MaxValue) + 2; + Height = Height - textBox1.Height + lineCount * TextRenderer.MeasureText(textBox1.Text, textBox1.Font).Height; + + } + } +} diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.resx b/Source/LibationWinForms/grid/DescriptionDisplay.resx new file mode 100644 index 00000000..f298a7be --- /dev/null +++ b/Source/LibationWinForms/grid/DescriptionDisplay.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index b1c7f088..bd6d341d 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -26,6 +26,8 @@ namespace LibationWinForms public string AudibleProductId => Book.AudibleProductId; [Browsable(false)] public LibraryBook LibraryBook { get; private set; } + [Browsable(false)] + public string LongDescription { get; private set; } #endregion #region Model properties exposed to the view @@ -131,7 +133,8 @@ namespace LibationWinForms Narrators = Book.NarratorNames; Category = string.Join(" > ", Book.CategoriesNames); Misc = GetMiscDisplay(libraryBook); - Description = GetDescriptionDisplay(Book); + LongDescription = GetDescriptionDisplay(Book); + Description = TrimTextToWord(LongDescription, 62); } UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged; @@ -266,6 +269,14 @@ namespace LibationWinForms return doc.DocumentNode.InnerText; } + private static string TrimTextToWord(string text, int maxLength) + { + return + text.Length <= maxLength ? + text : + text.Substring(0, maxLength - 3) + "..."; + } + /// /// This information should not change during lifetime, so call only once. /// Maximum of 5 text rows will fit in 80-pixel row height. diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index 202fc078..89f53316 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -32,21 +32,21 @@ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components); this.gridEntryDataGridView = new System.Windows.Forms.DataGridView(); - this.dataGridViewImageButtonBoxColumn1 = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); - this.dataGridViewImageColumn1 = new System.Windows.Forms.DataGridViewImageColumn(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn7 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn8 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn9 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn10 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn11 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewImageButtonBoxColumn2 = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); + this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn(); + this.titleGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.authorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.narratorsGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.lengthGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.seriesGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.descriptionGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.categoryGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.productRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.purchaseDateGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.myRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); + this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit(); this.SuspendLayout(); @@ -64,20 +64,20 @@ this.gridEntryDataGridView.AutoGenerateColumns = false; this.gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewImageButtonBoxColumn1, - this.dataGridViewImageColumn1, - this.dataGridViewTextBoxColumn1, - this.dataGridViewTextBoxColumn2, - this.dataGridViewTextBoxColumn3, - this.dataGridViewTextBoxColumn4, - this.dataGridViewTextBoxColumn5, - this.dataGridViewTextBoxColumn6, - this.dataGridViewTextBoxColumn7, - this.dataGridViewTextBoxColumn8, - this.dataGridViewTextBoxColumn9, - this.dataGridViewTextBoxColumn10, - this.dataGridViewTextBoxColumn11, - this.dataGridViewImageButtonBoxColumn2}); + this.liberateGVColumn, + this.coverGVColumn, + this.titleGVColumn, + this.authorsGVColumn, + this.narratorsGVColumn, + this.lengthGVColumn, + this.seriesGVColumn, + this.descriptionGVColumn, + this.categoryGVColumn, + this.productRatingGVColumn, + this.purchaseDateGVColumn, + this.myRatingGVColumn, + this.miscGVColumn, + this.tagAndDetailsGVColumn}); this.gridEntryDataGridView.ContextMenuStrip = this.contextMenuStrip1; this.gridEntryDataGridView.DataSource = this.gridEntryBindingSource; dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; @@ -100,122 +100,123 @@ this.gridEntryDataGridView.ColumnDisplayIndexChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnDisplayIndexChanged); this.gridEntryDataGridView.ColumnWidthChanged += new System.Windows.Forms.DataGridViewColumnEventHandler(this.gridEntryDataGridView_ColumnWidthChanged); // - // dataGridViewImageButtonBoxColumn1 - // - this.dataGridViewImageButtonBoxColumn1.DataPropertyName = "Liberate"; - this.dataGridViewImageButtonBoxColumn1.HeaderText = "Liberate"; - this.dataGridViewImageButtonBoxColumn1.Name = "dataGridViewImageButtonBoxColumn1"; - this.dataGridViewImageButtonBoxColumn1.ReadOnly = true; - this.dataGridViewImageButtonBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageButtonBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - this.dataGridViewImageButtonBoxColumn1.Width = 75; - // - // dataGridViewImageColumn1 - // - this.dataGridViewImageColumn1.DataPropertyName = "Cover"; - this.dataGridViewImageColumn1.HeaderText = "Cover"; - this.dataGridViewImageColumn1.Name = "dataGridViewImageColumn1"; - this.dataGridViewImageColumn1.ReadOnly = true; - this.dataGridViewImageColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageColumn1.ToolTipText = "Cover Art"; - this.dataGridViewImageColumn1.Width = 80; - // - // dataGridViewTextBoxColumn1 - // - this.dataGridViewTextBoxColumn1.DataPropertyName = "Title"; - this.dataGridViewTextBoxColumn1.HeaderText = "Title"; - this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; - this.dataGridViewTextBoxColumn1.ReadOnly = true; - this.dataGridViewTextBoxColumn1.Width = 200; - // - // dataGridViewTextBoxColumn2 - // - this.dataGridViewTextBoxColumn2.DataPropertyName = "Authors"; - this.dataGridViewTextBoxColumn2.HeaderText = "Authors"; - this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; - this.dataGridViewTextBoxColumn2.ReadOnly = true; - // - // dataGridViewTextBoxColumn3 - // - this.dataGridViewTextBoxColumn3.DataPropertyName = "Narrators"; - this.dataGridViewTextBoxColumn3.HeaderText = "Narrators"; - this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; - this.dataGridViewTextBoxColumn3.ReadOnly = true; - // - // dataGridViewTextBoxColumn4 - // - this.dataGridViewTextBoxColumn4.DataPropertyName = "Length"; - this.dataGridViewTextBoxColumn4.HeaderText = "Length"; - this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; - this.dataGridViewTextBoxColumn4.ReadOnly = true; - this.dataGridViewTextBoxColumn4.ToolTipText = "Recording Length"; - // - // dataGridViewTextBoxColumn5 - // - this.dataGridViewTextBoxColumn5.DataPropertyName = "Series"; - this.dataGridViewTextBoxColumn5.HeaderText = "Series"; - this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; - this.dataGridViewTextBoxColumn5.ReadOnly = true; - // - // dataGridViewTextBoxColumn6 - // - this.dataGridViewTextBoxColumn6.DataPropertyName = "Description"; - this.dataGridViewTextBoxColumn6.HeaderText = "Description"; - this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; - this.dataGridViewTextBoxColumn6.ReadOnly = true; - // - // dataGridViewTextBoxColumn7 - // - this.dataGridViewTextBoxColumn7.DataPropertyName = "Category"; - this.dataGridViewTextBoxColumn7.HeaderText = "Category"; - this.dataGridViewTextBoxColumn7.Name = "dataGridViewTextBoxColumn7"; - this.dataGridViewTextBoxColumn7.ReadOnly = true; - // - // dataGridViewTextBoxColumn8 - // - this.dataGridViewTextBoxColumn8.DataPropertyName = "ProductRating"; - this.dataGridViewTextBoxColumn8.HeaderText = "Product Rating"; - this.dataGridViewTextBoxColumn8.Name = "dataGridViewTextBoxColumn8"; - this.dataGridViewTextBoxColumn8.ReadOnly = true; - this.dataGridViewTextBoxColumn8.Width = 108; - // - // dataGridViewTextBoxColumn9 - // - this.dataGridViewTextBoxColumn9.DataPropertyName = "PurchaseDate"; - this.dataGridViewTextBoxColumn9.HeaderText = "Purchase Date"; - this.dataGridViewTextBoxColumn9.Name = "dataGridViewTextBoxColumn9"; - this.dataGridViewTextBoxColumn9.ReadOnly = true; - // - // dataGridViewTextBoxColumn10 - // - this.dataGridViewTextBoxColumn10.DataPropertyName = "MyRating"; - this.dataGridViewTextBoxColumn10.HeaderText = "My Rating"; - this.dataGridViewTextBoxColumn10.Name = "dataGridViewTextBoxColumn10"; - this.dataGridViewTextBoxColumn10.ReadOnly = true; - this.dataGridViewTextBoxColumn10.Width = 108; - // - // dataGridViewTextBoxColumn11 - // - this.dataGridViewTextBoxColumn11.DataPropertyName = "Misc"; - this.dataGridViewTextBoxColumn11.HeaderText = "Misc"; - this.dataGridViewTextBoxColumn11.Name = "dataGridViewTextBoxColumn11"; - this.dataGridViewTextBoxColumn11.ReadOnly = true; - this.dataGridViewTextBoxColumn11.Width = 135; - // - // dataGridViewImageButtonBoxColumn2 - // - this.dataGridViewImageButtonBoxColumn2.DataPropertyName = "DisplayTags"; - this.dataGridViewImageButtonBoxColumn2.HeaderText = "Tags and Details"; - this.dataGridViewImageButtonBoxColumn2.Name = "dataGridViewImageButtonBoxColumn2"; - this.dataGridViewImageButtonBoxColumn2.ReadOnly = true; - this.dataGridViewImageButtonBoxColumn2.Resizable = System.Windows.Forms.DataGridViewTriState.False; - this.dataGridViewImageButtonBoxColumn2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; - // // contextMenuStrip1 // this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); // + // liberateGVColumn + // + this.liberateGVColumn.DataPropertyName = "Liberate"; + this.liberateGVColumn.HeaderText = "Liberate"; + this.liberateGVColumn.Name = "liberateGVColumn"; + this.liberateGVColumn.ReadOnly = true; + this.liberateGVColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.liberateGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + this.liberateGVColumn.Width = 75; + // + // coverGVColumn + // + this.coverGVColumn.DataPropertyName = "Cover"; + this.coverGVColumn.HeaderText = "Cover"; + this.coverGVColumn.Name = "coverGVColumn"; + this.coverGVColumn.ReadOnly = true; + this.coverGVColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.coverGVColumn.ToolTipText = "Cover Art"; + this.coverGVColumn.Width = 80; + // + // titleGVColumn + // + this.titleGVColumn.DataPropertyName = "Title"; + this.titleGVColumn.HeaderText = "Title"; + this.titleGVColumn.Name = "titleGVColumn"; + this.titleGVColumn.ReadOnly = true; + this.titleGVColumn.Width = 200; + // + // authorsGVColumn + // + this.authorsGVColumn.DataPropertyName = "Authors"; + this.authorsGVColumn.HeaderText = "Authors"; + this.authorsGVColumn.Name = "authorsGVColumn"; + this.authorsGVColumn.ReadOnly = true; + // + // narratorsGVColumn + // + this.narratorsGVColumn.DataPropertyName = "Narrators"; + this.narratorsGVColumn.HeaderText = "Narrators"; + this.narratorsGVColumn.Name = "narratorsGVColumn"; + this.narratorsGVColumn.ReadOnly = true; + // + // lengthGVColumn + // + this.lengthGVColumn.DataPropertyName = "Length"; + this.lengthGVColumn.HeaderText = "Length"; + this.lengthGVColumn.Name = "lengthGVColumn"; + this.lengthGVColumn.ReadOnly = true; + this.lengthGVColumn.ToolTipText = "Recording Length"; + // + // seriesGVColumn + // + this.seriesGVColumn.DataPropertyName = "Series"; + this.seriesGVColumn.HeaderText = "Series"; + this.seriesGVColumn.Name = "seriesGVColumn"; + this.seriesGVColumn.ReadOnly = true; + // + // descriptionGVColumn + // + this.descriptionGVColumn.DataPropertyName = "Description"; + this.descriptionGVColumn.HeaderText = "Description"; + this.descriptionGVColumn.Name = "descriptionGVColumn"; + this.descriptionGVColumn.ReadOnly = true; + this.descriptionGVColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; + // + // categoryGVColumn + // + this.categoryGVColumn.DataPropertyName = "Category"; + this.categoryGVColumn.HeaderText = "Category"; + this.categoryGVColumn.Name = "categoryGVColumn"; + this.categoryGVColumn.ReadOnly = true; + // + // productRatingGVColumn + // + this.productRatingGVColumn.DataPropertyName = "ProductRating"; + this.productRatingGVColumn.HeaderText = "Product Rating"; + this.productRatingGVColumn.Name = "productRatingGVColumn"; + this.productRatingGVColumn.ReadOnly = true; + this.productRatingGVColumn.Width = 108; + // + // purchaseDateGVColumn + // + this.purchaseDateGVColumn.DataPropertyName = "PurchaseDate"; + this.purchaseDateGVColumn.HeaderText = "Purchase Date"; + this.purchaseDateGVColumn.Name = "purchaseDateGVColumn"; + this.purchaseDateGVColumn.ReadOnly = true; + // + // myRatingGVColumn + // + this.myRatingGVColumn.DataPropertyName = "MyRating"; + this.myRatingGVColumn.HeaderText = "My Rating"; + this.myRatingGVColumn.Name = "myRatingGVColumn"; + this.myRatingGVColumn.ReadOnly = true; + this.myRatingGVColumn.Width = 108; + // + // miscGVColumn + // + this.miscGVColumn.DataPropertyName = "Misc"; + this.miscGVColumn.HeaderText = "Misc"; + this.miscGVColumn.Name = "miscGVColumn"; + this.miscGVColumn.ReadOnly = true; + this.miscGVColumn.Width = 135; + // + // tagAndDetailsGVColumn + // + this.tagAndDetailsGVColumn.DataPropertyName = "DisplayTags"; + this.tagAndDetailsGVColumn.HeaderText = "Tags and Details"; + this.tagAndDetailsGVColumn.Name = "tagAndDetailsGVColumn"; + this.tagAndDetailsGVColumn.ReadOnly = true; + this.tagAndDetailsGVColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; + this.tagAndDetailsGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + // // ProductsGrid // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -234,20 +235,20 @@ private LibationWinForms.SyncBindingSource gridEntryBindingSource; private System.Windows.Forms.DataGridView gridEntryDataGridView; - private LiberateDataGridViewImageButtonColumn dataGridViewImageButtonBoxColumn1; - private System.Windows.Forms.DataGridViewImageColumn dataGridViewImageColumn1; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn7; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn8; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn9; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn10; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn11; - private EditTagsDataGridViewImageButtonColumn dataGridViewImageButtonBoxColumn2; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private LiberateDataGridViewImageButtonColumn liberateGVColumn; + private System.Windows.Forms.DataGridViewImageColumn coverGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn titleGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn authorsGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn narratorsGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn lengthGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn seriesGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn descriptionGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn categoryGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn productRatingGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn purchaseDateGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn myRatingGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn miscGVColumn; + private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn; } } diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index f28d0449..dfac3312 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -59,20 +59,27 @@ namespace LibationWinForms private async void DataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e) { // handle grid button click: https://stackoverflow.com/a/13687844 - if (e.RowIndex < 0 || _dataGridView.Columns[e.ColumnIndex] is not DataGridViewButtonColumn) + if (e.RowIndex < 0) return; - var liveGridEntry = getGridEntry(e.RowIndex); + var propertyName = _dataGridView.Columns[e.ColumnIndex].DataPropertyName; - switch (_dataGridView.Columns[e.ColumnIndex].DataPropertyName) - { - case nameof(liveGridEntry.Liberate): - await Liberate_Click(liveGridEntry); - break; - case nameof(liveGridEntry.DisplayTags): - Details_Click(liveGridEntry); - break; - } + if (propertyName == liberateGVColumn.DataPropertyName) + await Liberate_Click(getGridEntry(e.RowIndex)); + else if (propertyName == tagAndDetailsGVColumn.DataPropertyName) + Details_Click(getGridEntry(e.RowIndex)); + else if (propertyName == descriptionGVColumn.DataPropertyName) + DescriptionClick(getGridEntry(e.RowIndex)); + } + + private void DescriptionClick(GridEntry liveGridEntry) + { + var displayWindow = new DescriptionDisplay(); + displayWindow.Text = $"{liveGridEntry.Title} description"; + displayWindow.Load += (_, _) => displayWindow.RestoreSizeAndLocation(Configuration.Instance); + displayWindow.FormClosing += (_, _) => displayWindow.SaveSizeAndLocation(Configuration.Instance); + displayWindow.textBox1.Text = liveGridEntry.LongDescription; + displayWindow.Show(this); } private static async Task Liberate_Click(GridEntry liveGridEntry) @@ -82,7 +89,7 @@ namespace LibationWinForms // liberated: open explorer to file if (libraryBook.Book.Audio_Exists) { - var filePath = LibationFileManager.AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId); + var filePath = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId); if (!Go.To.File(filePath)) { var suffix = string.IsNullOrWhiteSpace(filePath) ? "" : $":\r\n{filePath}"; diff --git a/Source/LibationWinForms/grid/ProductsGrid.resx b/Source/LibationWinForms/grid/ProductsGrid.resx index cc951239..8a560af5 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.resx +++ b/Source/LibationWinForms/grid/ProductsGrid.resx @@ -63,4 +63,7 @@ 197, 17 + + 81 + \ No newline at end of file From 8763d63a937b58df6fecef827fa71450a4550e04 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 17:15:16 -0600 Subject: [PATCH 08/27] Better windows positioning --- Source/AppScaffolding/LibationScaffolding.cs | 4 +-- Source/LibationFileManager/Configuration.cs | 6 ++--- .../grid/DescriptionDisplay.Designer.cs | 2 +- .../grid/DescriptionDisplay.cs | 13 +++++++--- Source/LibationWinForms/grid/ProductsGrid.cs | 25 ++++++++++--------- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Source/AppScaffolding/LibationScaffolding.cs b/Source/AppScaffolding/LibationScaffolding.cs index 21daf970..6bde3030 100644 --- a/Source/AppScaffolding/LibationScaffolding.cs +++ b/Source/AppScaffolding/LibationScaffolding.cs @@ -126,8 +126,8 @@ namespace AppScaffolding if (!config.Exists(nameof(config.AutoScan))) config.AutoScan = true; - if (!config.Exists(nameof(config.HiddenGridColumns))) - config.HiddenGridColumns = new Dictionary(); + if (!config.Exists(nameof(config.GridColumnsVisibilities))) + config.GridColumnsVisibilities = new Dictionary(); if (!config.Exists(nameof(config.GridColumnsDisplayIndices))) config.GridColumnsDisplayIndices = new Dictionary(); diff --git a/Source/LibationFileManager/Configuration.cs b/Source/LibationFileManager/Configuration.cs index 874f49ab..698a5a05 100644 --- a/Source/LibationFileManager/Configuration.cs +++ b/Source/LibationFileManager/Configuration.cs @@ -181,10 +181,10 @@ namespace LibationFileManager } [Description("A Dictionary of GridView data property names and bool indicating its column's visibility in ProductsGrid")] - public Dictionary HiddenGridColumns + public Dictionary GridColumnsVisibilities { - get => persistentDictionary.GetNonString>(nameof(HiddenGridColumns)); - set => persistentDictionary.SetNonString(nameof(HiddenGridColumns), value); + get => persistentDictionary.GetNonString>(nameof(GridColumnsVisibilities)); + set => persistentDictionary.SetNonString(nameof(GridColumnsVisibilities), value); } [Description("A Dictionary of GridView data property names and int indicating its column's display index in ProductsGrid")] diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs index 061695bf..89b553bf 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs @@ -58,6 +58,6 @@ #endregion - public System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox textBox1; } } \ No newline at end of file diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/grid/DescriptionDisplay.cs index 0bca3fc7..9f616421 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.cs @@ -13,18 +13,17 @@ namespace LibationWinForms { public partial class DescriptionDisplay : Form { + public Point SpawnLocation { get; init; } + public string DescriptionText { get => textBox1.Text; set => textBox1.Text = value; } public DescriptionDisplay() { InitializeComponent(); textBox1.LostFocus += (_, _) => Close(); - this.Shown += DescriptionDisplay_Shown; + Shown += DescriptionDisplay_Shown; var textHeight = TextRenderer.MeasureText("\n", textBox1.Font).Height; } - [DllImport("user32.dll")] - static extern bool HideCaret(IntPtr hWnd); - private void DescriptionDisplay_Shown(object sender, EventArgs e) { textBox1.DeselectAll(); @@ -37,6 +36,12 @@ namespace LibationWinForms int lineCount = textBox1.GetLineFromCharIndex(int.MaxValue) + 2; Height = Height - textBox1.Height + lineCount * TextRenderer.MeasureText(textBox1.Text, textBox1.Font).Height; + int screenHeight = Screen.PrimaryScreen.WorkingArea.Height; + + Location = new Point(SpawnLocation.X + 10, Math.Min(SpawnLocation.Y, screenHeight - Height)); } + + [DllImport("user32.dll")] + static extern bool HideCaret(IntPtr hWnd); } } diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index dfac3312..91452ecc 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -69,16 +69,17 @@ namespace LibationWinForms else if (propertyName == tagAndDetailsGVColumn.DataPropertyName) Details_Click(getGridEntry(e.RowIndex)); else if (propertyName == descriptionGVColumn.DataPropertyName) - DescriptionClick(getGridEntry(e.RowIndex)); + DescriptionClick(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex,false)); } - private void DescriptionClick(GridEntry liveGridEntry) + private void DescriptionClick(GridEntry liveGridEntry, Rectangle cell) { - var displayWindow = new DescriptionDisplay(); - displayWindow.Text = $"{liveGridEntry.Title} description"; - displayWindow.Load += (_, _) => displayWindow.RestoreSizeAndLocation(Configuration.Instance); - displayWindow.FormClosing += (_, _) => displayWindow.SaveSizeAndLocation(Configuration.Instance); - displayWindow.textBox1.Text = liveGridEntry.LongDescription; + var displayWindow = new DescriptionDisplay + { + Text = $"{liveGridEntry.Title} description", + SpawnLocation = cell.Location + cell.Size, + DescriptionText = liveGridEntry.LongDescription + }; displayWindow.Show(this); } @@ -245,7 +246,7 @@ namespace LibationWinForms //Restore Grid Display Settings var config = Configuration.Instance; - var hiddenGridColumns = config.HiddenGridColumns; + var gridColumnsVisibilities = config.GridColumnsVisibilities; var displayIndices = config.GridColumnsDisplayIndices; var gridColumnsWidths = config.GridColumnsWidths; @@ -254,7 +255,7 @@ namespace LibationWinForms foreach (DataGridViewColumn column in _dataGridView.Columns) { var itemName = column.DataPropertyName; - var visible = !hiddenGridColumns.GetValueOrDefault(itemName, false); + var visible = gridColumnsVisibilities.GetValueOrDefault(itemName, true); var menuItem = new ToolStripMenuItem() { @@ -316,9 +317,9 @@ namespace LibationWinForms var config = Configuration.Instance; - var dictionary = config.HiddenGridColumns; - dictionary[propertyName] = visible; - config.HiddenGridColumns = dictionary; + var dictionary = config.GridColumnsVisibilities; + dictionary[propertyName] = column.Visible; + config.GridColumnsVisibilities = dictionary; } } From 6474ef98f585cbea5a7c5c29b1734400d4d41e71 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 17:50:47 -0600 Subject: [PATCH 09/27] Fix description form location --- Source/LibationWinForms/grid/DescriptionDisplay.cs | 12 +++++++----- Source/LibationWinForms/grid/GridEntry.cs | 2 +- Source/LibationWinForms/grid/ProductsGrid.cs | 6 ++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/grid/DescriptionDisplay.cs index 9f616421..7905e0a5 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.cs @@ -13,15 +13,13 @@ namespace LibationWinForms { public partial class DescriptionDisplay : Form { - public Point SpawnLocation { get; init; } public string DescriptionText { get => textBox1.Text; set => textBox1.Text = value; } + public Point SpawnLocation { get; set; } public DescriptionDisplay() { InitializeComponent(); textBox1.LostFocus += (_, _) => Close(); Shown += DescriptionDisplay_Shown; - - var textHeight = TextRenderer.MeasureText("\n", textBox1.Font).Height; } private void DescriptionDisplay_Shown(object sender, EventArgs e) @@ -34,11 +32,15 @@ namespace LibationWinForms { base.OnLoad(e); int lineCount = textBox1.GetLineFromCharIndex(int.MaxValue) + 2; - Height = Height - textBox1.Height + lineCount * TextRenderer.MeasureText(textBox1.Text, textBox1.Font).Height; + Height = Height - textBox1.Height + lineCount * TextRenderer.MeasureText("X", textBox1.Font).Height; int screenHeight = Screen.PrimaryScreen.WorkingArea.Height; - Location = new Point(SpawnLocation.X + 10, Math.Min(SpawnLocation.Y, screenHeight - Height)); + + var tboxLocation = PointToScreen(textBox1.Location); + var tboxOffset = new Size(tboxLocation.X - Location.X, tboxLocation.Y - Location.Y); + + Location = new Point(SpawnLocation.X - tboxOffset.Width, Math.Min(SpawnLocation.Y - tboxOffset.Height, screenHeight - Height)); } [DllImport("user32.dll")] diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index bd6d341d..8b93dd12 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -265,7 +265,7 @@ namespace LibationWinForms private static string GetDescriptionDisplay(Book book) { var doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(book?.Description ?? ""); + doc.LoadHtml(book?.Description?.Replace("

", "\r\n\r\n

") ?? ""); return doc.DocumentNode.InnerText; } diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index 91452ecc..2df9be7f 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -69,7 +69,7 @@ namespace LibationWinForms else if (propertyName == tagAndDetailsGVColumn.DataPropertyName) Details_Click(getGridEntry(e.RowIndex)); else if (propertyName == descriptionGVColumn.DataPropertyName) - DescriptionClick(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex,false)); + DescriptionClick(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false)); } private void DescriptionClick(GridEntry liveGridEntry, Rectangle cell) @@ -77,10 +77,12 @@ namespace LibationWinForms var displayWindow = new DescriptionDisplay { Text = $"{liveGridEntry.Title} description", - SpawnLocation = cell.Location + cell.Size, + SpawnLocation = PointToScreen(cell.Location + new Size(cell.Width, 0)), DescriptionText = liveGridEntry.LongDescription }; + displayWindow.RestoreSizeAndLocation(Configuration.Instance); displayWindow.Show(this); + displayWindow.FormClosing += (_, _) => displayWindow.SaveSizeAndLocation(Configuration.Instance); } private static async Task Liberate_Click(GridEntry liveGridEntry) From b1968caa0fd0150402b76dd6cdfd76a3cf7f8920 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 20:29:08 -0600 Subject: [PATCH 10/27] Improve display and fix display indices --- .../grid/DescriptionDisplay.Designer.cs | 15 ++++--- .../grid/DescriptionDisplay.cs | 24 ++++++----- Source/LibationWinForms/grid/GridEntry.cs | 2 +- Source/LibationWinForms/grid/ProductsGrid.cs | 43 +++++++++++++------ 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs index 89b553bf..8a1f7cd2 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs @@ -33,22 +33,27 @@ // // textBox1 // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.textBox1.BackColor = System.Drawing.SystemColors.ControlLightLight; - this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.textBox1.Location = new System.Drawing.Point(0, 0); + this.textBox1.Location = new System.Drawing.Point(3, 3); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(413, 162); + this.textBox1.Size = new System.Drawing.Size(544, 144); this.textBox1.TabIndex = 0; // // DescriptionDisplay // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(413, 162); + this.BackColor = System.Drawing.SystemColors.Highlight; + this.ClientSize = new System.Drawing.Size(550, 150); this.Controls.Add(this.textBox1); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "DescriptionDisplay"; this.Text = "DescriptionDisplay"; this.ResumeLayout(false); diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/grid/DescriptionDisplay.cs index 7905e0a5..43c22a9d 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.cs @@ -1,18 +1,26 @@ using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace LibationWinForms { public partial class DescriptionDisplay : Form { + private int borderThickness = 0; + + public int BorderThickness + { + get => borderThickness; + set + { + borderThickness = value; + textBox1.Location = new Point(borderThickness, borderThickness); + textBox1.Size = new Size(Width - 2 * borderThickness, Height - 2 * borderThickness); + } + } public string DescriptionText { get => textBox1.Text; set => textBox1.Text = value; } public Point SpawnLocation { get; set; } public DescriptionDisplay() @@ -34,13 +42,7 @@ namespace LibationWinForms int lineCount = textBox1.GetLineFromCharIndex(int.MaxValue) + 2; Height = Height - textBox1.Height + lineCount * TextRenderer.MeasureText("X", textBox1.Font).Height; - int screenHeight = Screen.PrimaryScreen.WorkingArea.Height; - - - var tboxLocation = PointToScreen(textBox1.Location); - var tboxOffset = new Size(tboxLocation.X - Location.X, tboxLocation.Y - Location.Y); - - Location = new Point(SpawnLocation.X - tboxOffset.Width, Math.Min(SpawnLocation.Y - tboxOffset.Height, screenHeight - Height)); + Location = new Point(SpawnLocation.X, Math.Min(SpawnLocation.Y, Screen.PrimaryScreen.WorkingArea.Height - Height)); } [DllImport("user32.dll")] diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index 8b93dd12..0a6ab244 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -266,7 +266,7 @@ namespace LibationWinForms { var doc = new HtmlAgilityPack.HtmlDocument(); doc.LoadHtml(book?.Description?.Replace("

", "\r\n\r\n

") ?? ""); - return doc.DocumentNode.InnerText; + return doc.DocumentNode.InnerText.Trim(); } private static string TrimTextToWord(string text, int maxLength) diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index 2df9be7f..48bd2e49 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -62,27 +62,33 @@ namespace LibationWinForms if (e.RowIndex < 0) return; - var propertyName = _dataGridView.Columns[e.ColumnIndex].DataPropertyName; + var clickedColumn = _dataGridView.Columns[e.ColumnIndex]; - if (propertyName == liberateGVColumn.DataPropertyName) + if (clickedColumn == liberateGVColumn) await Liberate_Click(getGridEntry(e.RowIndex)); - else if (propertyName == tagAndDetailsGVColumn.DataPropertyName) + else if (clickedColumn == tagAndDetailsGVColumn) Details_Click(getGridEntry(e.RowIndex)); - else if (propertyName == descriptionGVColumn.DataPropertyName) + else if (clickedColumn == descriptionGVColumn) DescriptionClick(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false)); } - private void DescriptionClick(GridEntry liveGridEntry, Rectangle cell) + private void DescriptionClick(GridEntry liveGridEntry, Rectangle cellDisplay) { var displayWindow = new DescriptionDisplay { - Text = $"{liveGridEntry.Title} description", - SpawnLocation = PointToScreen(cell.Location + new Size(cell.Width, 0)), - DescriptionText = liveGridEntry.LongDescription + SpawnLocation = PointToScreen(cellDisplay.Location + new Size(cellDisplay.Width, 0)), + DescriptionText = liveGridEntry.LongDescription, + BorderThickness = 2, }; - displayWindow.RestoreSizeAndLocation(Configuration.Instance); + + void CloseWindow (object o, EventArgs e) + { + displayWindow.Close(); + } + + _dataGridView.Scroll += CloseWindow; + displayWindow.FormClosed += (_,_) => _dataGridView.Scroll -= CloseWindow; displayWindow.Show(this); - displayWindow.FormClosing += (_, _) => displayWindow.SaveSizeAndLocation(Configuration.Instance); } private static async Task Liberate_Click(GridEntry liveGridEntry) @@ -249,8 +255,8 @@ namespace LibationWinForms //Restore Grid Display Settings var config = Configuration.Instance; var gridColumnsVisibilities = config.GridColumnsVisibilities; - var displayIndices = config.GridColumnsDisplayIndices; var gridColumnsWidths = config.GridColumnsWidths; + var displayIndices = config.GridColumnsDisplayIndices; var cmsKiller = new ContextMenuStrip(); @@ -261,18 +267,17 @@ namespace LibationWinForms var menuItem = new ToolStripMenuItem() { - Text = itemName, + Text = column.HeaderText, Checked = visible, Tag = itemName }; menuItem.Click += HideMenuItem_Click; contextMenuStrip1.Items.Add(menuItem); - column.Visible = visible; - column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index); 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. @@ -281,6 +286,16 @@ namespace LibationWinForms 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() + .Single(c => c.DataPropertyName == itemName); + + column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index); + } + base.OnVisibleChanged(e); } From e2a05761a648da8da69e4b953667a12ec97cedca Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 20:36:48 -0600 Subject: [PATCH 11/27] Unnecessary. Cleanup of unfinished decrypts is performed by Caller --- Source/AaxDecrypter/AudiobookDownloadBase.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/AaxDecrypter/AudiobookDownloadBase.cs b/Source/AaxDecrypter/AudiobookDownloadBase.cs index ef16f7d5..04e901ed 100644 --- a/Source/AaxDecrypter/AudiobookDownloadBase.cs +++ b/Source/AaxDecrypter/AudiobookDownloadBase.cs @@ -140,11 +140,6 @@ namespace AaxDecrypter else FileUtility.SaferDelete(TempFilePath); } - else - { - FileUtility.SaferDelete(OutputFileName); - } - return success; } From 803eef382520c9d7030bbebfb36bcc1f951ac1e3 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 20:37:05 -0600 Subject: [PATCH 12/27] Settings are not mutually exclusive --- Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs b/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs index 6b45db4e..68cf9d6f 100644 --- a/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs +++ b/Source/LibationWinForms/Dialogs/SettingsDialog.AudioSettings.cs @@ -17,7 +17,6 @@ namespace LibationWinForms.Dialogs private void LameMatchSourceBRCbox_CheckedChanged(object sender, EventArgs e) { lameBitrateTb.Enabled = !LameMatchSourceBRCbox.Checked; - lameConstantBitrateCbox.Enabled = !LameMatchSourceBRCbox.Checked; } private void convertFormatRb_CheckedChanged(object sender, EventArgs e) From 04665fea36a467dc3814490efea9ecf842189229 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 20:37:41 -0600 Subject: [PATCH 13/27] Change default border width --- Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs | 4 ++-- Source/LibationWinForms/grid/DescriptionDisplay.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs index 8a1f7cd2..bd599dfe 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs @@ -37,11 +37,11 @@ | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.textBox1.BackColor = System.Drawing.SystemColors.ControlLightLight; - this.textBox1.Location = new System.Drawing.Point(3, 3); + this.textBox1.Location = new System.Drawing.Point(5, 5); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.ReadOnly = true; - this.textBox1.Size = new System.Drawing.Size(544, 144); + this.textBox1.Size = new System.Drawing.Size(540, 140); this.textBox1.TabIndex = 0; // // DescriptionDisplay diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.cs b/Source/LibationWinForms/grid/DescriptionDisplay.cs index 43c22a9d..3f95a92e 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.cs @@ -9,7 +9,7 @@ namespace LibationWinForms { public partial class DescriptionDisplay : Form { - private int borderThickness = 0; + private int borderThickness = 5; public int BorderThickness { From 81c152ddcb0daec56364854bdfca3b2ddd952c48 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 21:09:59 -0600 Subject: [PATCH 14/27] Add libation icon to forms --- .../BookLiberation/BaseForms/LiberationBaseForm.cs | 1 + Source/LibationWinForms/Dialogs/AccountsDialog.cs | 1 + .../Dialogs/BookDetailsDialog.Designer.cs | 1 - .../LibationWinForms/Dialogs/BookDetailsDialog.cs | 1 + Source/LibationWinForms/Dialogs/EditQuickFilters.cs | 1 + .../Dialogs/EditTemplateDialog.Designer.cs | 4 +++- .../LibationWinForms/Dialogs/EditTemplateDialog.cs | 6 +++++- .../Dialogs/RemoveBooksDialog.Designer.cs | 2 +- .../LibationWinForms/Dialogs/RemoveBooksDialog.cs | 1 + .../LibationWinForms/Dialogs/ScanAccountsDialog.cs | 1 + .../Dialogs/SearchSyntaxDialog.Designer.cs | 1 - .../LibationWinForms/Dialogs/SearchSyntaxDialog.cs | 1 + .../Dialogs/SettingsDialog.Designer.cs | 4 +++- Source/LibationWinForms/Dialogs/SettingsDialog.cs | 6 +++++- Source/LibationWinForms/FormSaveExtension.cs | 13 +++++++++++++ 15 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs b/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs index 691db3c9..03f5ba05 100644 --- a/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs +++ b/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs @@ -19,6 +19,7 @@ namespace LibationWinForms.BookLiberation.BaseForms //If this is the first form created, it will not exist until after execution //reaches inside the constructor (after base class has been initialized). Invoker = new SynchronizeInvoker(); + this.SetLibationIcon(); } public void RegisterFileLiberator(Streamable streamable, LogMe logMe = null) diff --git a/Source/LibationWinForms/Dialogs/AccountsDialog.cs b/Source/LibationWinForms/Dialogs/AccountsDialog.cs index 3da3cdbd..14c67523 100644 --- a/Source/LibationWinForms/Dialogs/AccountsDialog.cs +++ b/Source/LibationWinForms/Dialogs/AccountsDialog.cs @@ -28,6 +28,7 @@ namespace LibationWinForms.Dialogs populateDropDown(); populateGridValues(); + this.SetLibationIcon(); } private void populateDropDown() diff --git a/Source/LibationWinForms/Dialogs/BookDetailsDialog.Designer.cs b/Source/LibationWinForms/Dialogs/BookDetailsDialog.Designer.cs index 9f57e610..2e51bc1a 100644 --- a/Source/LibationWinForms/Dialogs/BookDetailsDialog.Designer.cs +++ b/Source/LibationWinForms/Dialogs/BookDetailsDialog.Designer.cs @@ -205,7 +205,6 @@ this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "BookDetailsDialog"; - this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Book Details"; diff --git a/Source/LibationWinForms/Dialogs/BookDetailsDialog.cs b/Source/LibationWinForms/Dialogs/BookDetailsDialog.cs index 3e20b74b..89184b00 100644 --- a/Source/LibationWinForms/Dialogs/BookDetailsDialog.cs +++ b/Source/LibationWinForms/Dialogs/BookDetailsDialog.cs @@ -27,6 +27,7 @@ namespace LibationWinForms.Dialogs public BookDetailsDialog() { InitializeComponent(); + this.SetLibationIcon(); } public BookDetailsDialog(LibraryBook libraryBook) : this() { diff --git a/Source/LibationWinForms/Dialogs/EditQuickFilters.cs b/Source/LibationWinForms/Dialogs/EditQuickFilters.cs index 7d8f20ca..3d6eab63 100644 --- a/Source/LibationWinForms/Dialogs/EditQuickFilters.cs +++ b/Source/LibationWinForms/Dialogs/EditQuickFilters.cs @@ -26,6 +26,7 @@ namespace LibationWinForms.Dialogs dataGridView1.Columns[COL_Filter].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; populateGridValues(); + this.SetLibationIcon(); } private void populateGridValues() diff --git a/Source/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs b/Source/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs index deea82d3..592c285d 100644 --- a/Source/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs +++ b/Source/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs @@ -170,8 +170,10 @@ this.Controls.Add(this.templateTb); this.Controls.Add(this.cancelBtn); this.Controls.Add(this.saveBtn); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "EditTemplateDialog"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Template"; diff --git a/Source/LibationWinForms/Dialogs/EditTemplateDialog.cs b/Source/LibationWinForms/Dialogs/EditTemplateDialog.cs index a14066ba..734a49d4 100644 --- a/Source/LibationWinForms/Dialogs/EditTemplateDialog.cs +++ b/Source/LibationWinForms/Dialogs/EditTemplateDialog.cs @@ -28,7 +28,11 @@ namespace LibationWinForms.Dialogs private Templates template { get; } private string inputTemplateText { get; } - public EditTemplateDialog() => InitializeComponent(); + public EditTemplateDialog() + { + InitializeComponent(); + this.SetLibationIcon(); + } public EditTemplateDialog(Templates template, string inputTemplateText) : this() { this.template = ArgumentValidator.EnsureNotNull(template, nameof(template)); diff --git a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs index ea2551ce..61974264 100644 --- a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs +++ b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.Designer.cs @@ -164,7 +164,7 @@ namespace LibationWinForms.Dialogs this.Controls.Add(this.btnRemoveBooks); this.Controls.Add(this._dataGridView); this.Name = "RemoveBooksDialog"; - this.Text = "RemoveBooksDialog"; + this.Text = "Remove Books from Libation's Database"; this.Shown += new System.EventHandler(this.RemoveBooksDialog_Shown); ((System.ComponentModel.ISupportInitialize)(this._dataGridView)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).EndInit(); diff --git a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs index 9680e246..1f7e18d9 100644 --- a/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs +++ b/Source/LibationWinForms/Dialogs/RemoveBooksDialog.cs @@ -48,6 +48,7 @@ namespace LibationWinForms.Dialogs gridEntryBindingSource.DataSource = _removableGridEntries; _dataGridView.Enabled = false; + this.SetLibationIcon(); } private void _dataGridView_BindingContextChanged(object sender, EventArgs e) diff --git a/Source/LibationWinForms/Dialogs/ScanAccountsDialog.cs b/Source/LibationWinForms/Dialogs/ScanAccountsDialog.cs index 5ad47361..0ebd283d 100644 --- a/Source/LibationWinForms/Dialogs/ScanAccountsDialog.cs +++ b/Source/LibationWinForms/Dialogs/ScanAccountsDialog.cs @@ -17,6 +17,7 @@ namespace LibationWinForms.Dialogs _parent = parent; InitializeComponent(); + this.SetLibationIcon(); } private class listItem diff --git a/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.Designer.cs b/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.Designer.cs index 7a7f27d9..7600c226 100644 --- a/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.Designer.cs +++ b/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.Designer.cs @@ -113,7 +113,6 @@ this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "SearchSyntaxDialog"; - this.ShowIcon = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Filter options"; this.ResumeLayout(false); diff --git a/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.cs b/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.cs index ed897b11..d809f33f 100644 --- a/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.cs +++ b/Source/LibationWinForms/Dialogs/SearchSyntaxDialog.cs @@ -14,6 +14,7 @@ namespace LibationWinForms.Dialogs label3.Text += "\r\n\r\n" + string.Join("\r\n", LibationSearchEngine.SearchEngine.GetSearchNumberFields()); label4.Text += "\r\n\r\n" + string.Join("\r\n", LibationSearchEngine.SearchEngine.GetSearchBoolFields()); label5.Text += "\r\n\r\n" + string.Join("\r\n", LibationSearchEngine.SearchEngine.GetSearchIdFields()); + this.SetLibationIcon(); } private void CloseBtn_Click(object sender, EventArgs e) => this.Close(); diff --git a/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs b/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs index 48cd06d2..2df343c7 100644 --- a/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs +++ b/Source/LibationWinForms/Dialogs/SettingsDialog.Designer.cs @@ -944,8 +944,10 @@ this.Controls.Add(this.tabControl); this.Controls.Add(this.cancelBtn); this.Controls.Add(this.saveBtn); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.MaximizeBox = false; + this.MinimizeBox = false; this.Name = "SettingsDialog"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Edit Settings"; diff --git a/Source/LibationWinForms/Dialogs/SettingsDialog.cs b/Source/LibationWinForms/Dialogs/SettingsDialog.cs index a0333608..6d106411 100644 --- a/Source/LibationWinForms/Dialogs/SettingsDialog.cs +++ b/Source/LibationWinForms/Dialogs/SettingsDialog.cs @@ -13,7 +13,11 @@ namespace LibationWinForms.Dialogs private Configuration config { get; } = Configuration.Instance; private Func desc { get; } = Configuration.GetDescription; - public SettingsDialog() => InitializeComponent(); + public SettingsDialog() + { + InitializeComponent(); + this.SetLibationIcon(); + } private void SettingsDialog_Load(object sender, EventArgs e) { diff --git a/Source/LibationWinForms/FormSaveExtension.cs b/Source/LibationWinForms/FormSaveExtension.cs index cca421b7..22be5c73 100644 --- a/Source/LibationWinForms/FormSaveExtension.cs +++ b/Source/LibationWinForms/FormSaveExtension.cs @@ -7,6 +7,18 @@ namespace LibationWinForms { public static class FormSaveExtension { + static readonly Icon libationIcon; + static FormSaveExtension() + { + var resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + libationIcon = (Icon)resources.GetObject("$this.Icon"); + } + + public static void SetLibationIcon(this Form form) + { + form.Icon = libationIcon; + } + public static void RestoreSizeAndLocation(this Form form, Configuration config) { FormSizeAndPosition savedState = config.GetNonString(form.Name); @@ -77,6 +89,7 @@ namespace LibationWinForms config.SetObject(form.Name, saveState); } + } class FormSizeAndPosition { From 138f94594f1c314784201105154c7d200d42a4c2 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 21:31:21 -0600 Subject: [PATCH 15/27] Fixed cross-thread access error. --- Source/LibationWinForms/Form1.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/LibationWinForms/Form1.cs b/Source/LibationWinForms/Form1.cs index dac6d01a..b0d26cf1 100644 --- a/Source/LibationWinForms/Form1.cs +++ b/Source/LibationWinForms/Form1.cs @@ -262,8 +262,8 @@ namespace LibationWinForms .Where(a => a.LibraryScan) .ToArray(); - // in autoScan, new books SHALL NOT show dialog - await LibraryCommands.ImportAccountAsync(Login.WinformLoginChoiceEager.ApiExtendedFunc, accounts); + // in autoScan, new books SHALL NOT show dialog + await Invoke(async () => await LibraryCommands.ImportAccountAsync(Login.WinformLoginChoiceEager.ApiExtendedFunc, accounts)); }; // load init state to menu checkbox From 7723de7284b4c7aaa403f84da474b355a51e8b5c Mon Sep 17 00:00:00 2001 From: Mbucari <37587114+Mbucari@users.noreply.github.com> Date: Mon, 9 May 2022 21:49:56 -0600 Subject: [PATCH 16/27] Update ProductsGrid.cs --- Source/LibationWinForms/grid/ProductsGrid.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index 48bd2e49..7f8deb4d 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -69,10 +69,10 @@ namespace LibationWinForms else if (clickedColumn == tagAndDetailsGVColumn) Details_Click(getGridEntry(e.RowIndex)); else if (clickedColumn == descriptionGVColumn) - DescriptionClick(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false)); + Description_Click(getGridEntry(e.RowIndex), _dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false)); } - private void DescriptionClick(GridEntry liveGridEntry, Rectangle cellDisplay) + private void Description_Click(GridEntry liveGridEntry, Rectangle cellDisplay) { var displayWindow = new DescriptionDisplay { From 23460e0137f4d11169005790955aee3550d5922e Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 22:09:47 -0600 Subject: [PATCH 17/27] Don't show description form in task bar --- Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs index bd599dfe..96012e50 100644 --- a/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs +++ b/Source/LibationWinForms/grid/DescriptionDisplay.Designer.cs @@ -55,6 +55,7 @@ this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "DescriptionDisplay"; + this.ShowInTaskbar = false; this.Text = "DescriptionDisplay"; this.ResumeLayout(false); this.PerformLayout(); From b3202769260a35dffa54955babb1e642ad02f3f6 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 23:21:52 -0600 Subject: [PATCH 18/27] Add PictureID_1215 to Book and migrate DB --- Source/DataLayer/EfClasses/Book.cs | 1 + Source/DataLayer/LibationContext.db | Bin 122880 -> 122880 bytes ...20510051435_Add PictureId_1215.Designer.cs | 394 ++++++++++++++++++ .../20220510051435_Add PictureId_1215.cs | 25 ++ .../LibationContextModelSnapshot.cs | 10 +- Source/DtoImporterService/BookImporter.cs | 4 + Source/LibationFileManager/PictureStorage.cs | 2 +- 7 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.Designer.cs create mode 100644 Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs diff --git a/Source/DataLayer/EfClasses/Book.cs b/Source/DataLayer/EfClasses/Book.cs index 2dba71d5..59ae4395 100644 --- a/Source/DataLayer/EfClasses/Book.cs +++ b/Source/DataLayer/EfClasses/Book.cs @@ -34,6 +34,7 @@ namespace DataLayer // mutable public string PictureId { get; set; } + public string PictureId_1215 { get; set; } // book details public bool IsAbridged { get; private set; } diff --git a/Source/DataLayer/LibationContext.db b/Source/DataLayer/LibationContext.db index 7591b152123b6c207b22cdda7921ce3849e3f975..9d9b5859305d4878404815196e67cee066031ba8 100644 GIT binary patch delta 360 zcmZoTz}|3xeS)+g4+8^(91u$bF%u9QOw=)EfXw8Q(xOz)lz2lU zLsK(713iVF@K;t?X_+RiJIl7P2<|U zPA~YOI?$;COe-1q8~NVw#q;jv4dA)Olh3r0`xp0g&J7&-Z1dPMS^u&20^Qlj#MPQ8 z#V#%`&e*NEy-{FMO1n{D7T(`T;Sb#h!>GYLy+exe#&msg#_a875{yDj+Y_W2MHm^mHZvx0 MDQxF0( z4|UmRF$gfJGH`$8PT>5_8Oia6ql{gjC7tUvR|lUY&kd$&9FFYQfC_+sF?HiaD@J|} z5SxvMiBVizo3Y(^`YuUE<;hVWx~KPwG8S&1C&qY@k*n2Jid|e>oUto&`(`0VGp5N4 znM5b=<0_t>FT8 +using System; +using DataLayer; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DataLayer.Migrations +{ + [DbContext(typeof(LibationContext))] + [Migration("20220510051435_Add PictureId_1215")] + partial class AddPictureId_1215 + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.4"); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.Property("BookId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleProductId") + .HasColumnType("TEXT"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("DatePublished") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IsAbridged") + .HasColumnType("INTEGER"); + + b.Property("LengthInMinutes") + .HasColumnType("INTEGER"); + + b.Property("Locale") + .HasColumnType("TEXT"); + + b.Property("PictureId") + .HasColumnType("TEXT"); + + b.Property("PictureId_1215") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("BookId"); + + b.HasIndex("AudibleProductId"); + + b.HasIndex("CategoryId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("DataLayer.BookContributor", b => + { + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("ContributorId") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.HasKey("BookId", "ContributorId", "Role"); + + b.HasIndex("BookId"); + + b.HasIndex("ContributorId"); + + b.ToTable("BookContributor"); + }); + + modelBuilder.Entity("DataLayer.Category", b => + { + b.Property("CategoryId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleCategoryId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("ParentCategoryCategoryId") + .HasColumnType("INTEGER"); + + b.HasKey("CategoryId"); + + b.HasIndex("AudibleCategoryId"); + + b.HasIndex("ParentCategoryCategoryId"); + + b.ToTable("Categories"); + + b.HasData( + new + { + CategoryId = -1, + AudibleCategoryId = "", + Name = "" + }); + }); + + modelBuilder.Entity("DataLayer.Contributor", b => + { + b.Property("ContributorId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleContributorId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("ContributorId"); + + b.HasIndex("Name"); + + b.ToTable("Contributors"); + + b.HasData( + new + { + ContributorId = -1, + Name = "" + }); + }); + + modelBuilder.Entity("DataLayer.LibraryBook", b => + { + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("Account") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.HasKey("BookId"); + + b.ToTable("LibraryBooks"); + }); + + modelBuilder.Entity("DataLayer.Series", b => + { + b.Property("SeriesId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AudibleSeriesId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("SeriesId"); + + b.HasIndex("AudibleSeriesId"); + + b.ToTable("Series"); + }); + + modelBuilder.Entity("DataLayer.SeriesBook", b => + { + b.Property("SeriesId") + .HasColumnType("INTEGER"); + + b.Property("BookId") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("TEXT"); + + b.HasKey("SeriesId", "BookId"); + + b.HasIndex("BookId"); + + b.HasIndex("SeriesId"); + + b.ToTable("SeriesBook"); + }); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.HasOne("DataLayer.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("DataLayer.Rating", "Rating", b1 => + { + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("OverallRating") + .HasColumnType("REAL"); + + b1.Property("PerformanceRating") + .HasColumnType("REAL"); + + b1.Property("StoryRating") + .HasColumnType("REAL"); + + b1.HasKey("BookId"); + + b1.ToTable("Books"); + + b1.WithOwner() + .HasForeignKey("BookId"); + }); + + b.OwnsMany("DataLayer.Supplement", "Supplements", b1 => + { + b1.Property("SupplementId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("Url") + .HasColumnType("TEXT"); + + b1.HasKey("SupplementId"); + + b1.HasIndex("BookId"); + + b1.ToTable("Supplement"); + + b1.WithOwner("Book") + .HasForeignKey("BookId"); + + b1.Navigation("Book"); + }); + + b.OwnsOne("DataLayer.UserDefinedItem", "UserDefinedItem", b1 => + { + b1.Property("BookId") + .HasColumnType("INTEGER"); + + b1.Property("BookStatus") + .HasColumnType("INTEGER"); + + b1.Property("PdfStatus") + .HasColumnType("INTEGER"); + + b1.Property("Tags") + .HasColumnType("TEXT"); + + b1.HasKey("BookId"); + + b1.ToTable("UserDefinedItem", (string)null); + + b1.WithOwner("Book") + .HasForeignKey("BookId"); + + b1.OwnsOne("DataLayer.Rating", "Rating", b2 => + { + b2.Property("UserDefinedItemBookId") + .HasColumnType("INTEGER"); + + b2.Property("OverallRating") + .HasColumnType("REAL"); + + b2.Property("PerformanceRating") + .HasColumnType("REAL"); + + b2.Property("StoryRating") + .HasColumnType("REAL"); + + b2.HasKey("UserDefinedItemBookId"); + + b2.ToTable("UserDefinedItem"); + + b2.WithOwner() + .HasForeignKey("UserDefinedItemBookId"); + }); + + b1.Navigation("Book"); + + b1.Navigation("Rating"); + }); + + b.Navigation("Category"); + + b.Navigation("Rating"); + + b.Navigation("Supplements"); + + b.Navigation("UserDefinedItem"); + }); + + modelBuilder.Entity("DataLayer.BookContributor", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithMany("ContributorsLink") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DataLayer.Contributor", "Contributor") + .WithMany("BooksLink") + .HasForeignKey("ContributorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Contributor"); + }); + + modelBuilder.Entity("DataLayer.Category", b => + { + b.HasOne("DataLayer.Category", "ParentCategory") + .WithMany() + .HasForeignKey("ParentCategoryCategoryId"); + + b.Navigation("ParentCategory"); + }); + + modelBuilder.Entity("DataLayer.LibraryBook", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithOne() + .HasForeignKey("DataLayer.LibraryBook", "BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + }); + + modelBuilder.Entity("DataLayer.SeriesBook", b => + { + b.HasOne("DataLayer.Book", "Book") + .WithMany("SeriesLink") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DataLayer.Series", "Series") + .WithMany("BooksLink") + .HasForeignKey("SeriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("DataLayer.Book", b => + { + b.Navigation("ContributorsLink"); + + b.Navigation("SeriesLink"); + }); + + modelBuilder.Entity("DataLayer.Contributor", b => + { + b.Navigation("BooksLink"); + }); + + modelBuilder.Entity("DataLayer.Series", b => + { + b.Navigation("BooksLink"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs b/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs new file mode 100644 index 00000000..e4f6abed --- /dev/null +++ b/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DataLayer.Migrations +{ + public partial class AddPictureId_1215 : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "PictureId_1215", + table: "Books", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "PictureId_1215", + table: "Books"); + } + } +} diff --git a/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs b/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs index 5453c4a9..f2e133fb 100644 --- a/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs +++ b/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +#nullable disable + namespace DataLayer.Migrations { [DbContext(typeof(LibationContext))] @@ -13,8 +15,7 @@ namespace DataLayer.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.10"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.4"); modelBuilder.Entity("DataLayer.Book", b => { @@ -49,6 +50,9 @@ namespace DataLayer.Migrations b.Property("PictureId") .HasColumnType("TEXT"); + b.Property("PictureId_1215") + .HasColumnType("TEXT"); + b.Property("Title") .HasColumnType("TEXT"); @@ -267,7 +271,7 @@ namespace DataLayer.Migrations b1.HasKey("BookId"); - b1.ToTable("UserDefinedItem"); + b1.ToTable("UserDefinedItem", (string)null); b1.WithOwner("Book") .HasForeignKey("BookId"); diff --git a/Source/DtoImporterService/BookImporter.cs b/Source/DtoImporterService/BookImporter.cs index cbb56d3b..4c3cd74d 100644 --- a/Source/DtoImporterService/BookImporter.cs +++ b/Source/DtoImporterService/BookImporter.cs @@ -164,6 +164,10 @@ namespace DtoImporterService // set/update book-specific info which may have changed if (item.PictureId is not null) book.PictureId = item.PictureId; + + // set/update book-specific info which may have changed + if (item.PictureId_1215 is not null) + book.PictureId_1215 = item.PictureId_1215; book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars); diff --git a/Source/LibationFileManager/PictureStorage.cs b/Source/LibationFileManager/PictureStorage.cs index 868e4e33..4b6556ab 100644 --- a/Source/LibationFileManager/PictureStorage.cs +++ b/Source/LibationFileManager/PictureStorage.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace LibationFileManager { - public enum PictureSize { _80x80 = 80, _300x300 = 300, _500x500 = 500 } + public enum PictureSize { _80x80 = 80, _300x300 = 300, _500x500 = 500 , _1215x1215 = 1215 } public class PictureCachedEventArgs : EventArgs { public PictureDefinition Definition { get; internal set; } From 82b5daa809f97dd2e5890c0d5859d32572677d24 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 23:22:21 -0600 Subject: [PATCH 19/27] Download large cover art after successfilly downloading an audiobook. --- .../ProcessorAutomationController.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index 064b012e..a9f751aa 100644 --- a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -201,7 +201,23 @@ namespace LibationWinForms.BookLiberation var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate); if (statusHandler.IsSuccess) + { + var destinationDir = AudibleFileStorage.Audio.GetDestinationDirectory(libraryBook); + var coverPath = FileManager.FileUtility.GetValidFilename(System.IO.Path.Combine(destinationDir, "Cover.jpg"), "", true); + + try + { + var picBytes = PictureStorage.GetPictureSynchronously(new PictureDefinition(libraryBook.Book.PictureId_1215, PictureSize._1215x1215)); + System.IO.File.WriteAllBytes(coverPath, picBytes); + } + catch(Exception ex) + { + LogMe.Error(ex.Message); + } + //Failure to download cover art should not be + //considered a failure to download the book return true; + } foreach (var errorMessage in statusHandler.Errors) LogMe.Error(errorMessage); From 48ffc40abb9c8cf1b01d573447381caf037faf12 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Mon, 9 May 2022 23:53:10 -0600 Subject: [PATCH 20/27] Move cover download to processable --- Source/FileLiberator/Processable.cs | 30 +++++++++++++++++++ .../ProcessorAutomationController.cs | 18 +---------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Source/FileLiberator/Processable.cs b/Source/FileLiberator/Processable.cs index 0c7743e7..66e36d1c 100644 --- a/Source/FileLiberator/Processable.cs +++ b/Source/FileLiberator/Processable.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using DataLayer; using Dinah.Core; using Dinah.Core.ErrorHandling; +using LibationFileManager; namespace FileLiberator { @@ -47,9 +48,38 @@ namespace FileLiberator = (await ProcessAsync(libraryBook)) ?? new StatusHandler { "Processable should never return a null status" }; + if (status.IsSuccess) + DownloadCoverArt(libraryBook); + return status; } + private void DownloadCoverArt(LibraryBook libraryBook) + { + var destinationDir = AudibleFileStorage.Audio.GetDestinationDirectory(libraryBook); + var coverPath = FileManager.FileUtility.GetValidFilename(System.IO.Path.Combine(destinationDir, "Cover.jpg"), "", true); + + if (System.IO.File.Exists(coverPath)) return; + + try + { + (string picId, PictureSize size) = libraryBook.Book.PictureId_1215 is null ? + (libraryBook.Book.PictureId, PictureSize._500x500) : + (libraryBook.Book.PictureId_1215, PictureSize._1215x1215); + + var picBytes = PictureStorage.GetPictureSynchronously(new PictureDefinition(picId, size)); + + if (picBytes.Length > 0) + System.IO.File.WriteAllBytes(coverPath, picBytes); + } + catch (Exception ex) + { + //Failure to download cover art should not be + //considered a failure to download the book + Serilog.Log.Logger.Error(ex.Message); + } + } + public async Task TryProcessAsync(LibraryBook libraryBook) => Validate(libraryBook) ? await ProcessAsync(libraryBook) diff --git a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs index a9f751aa..dca83b84 100644 --- a/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs +++ b/Source/LibationWinForms/BookLiberation/ProcessorAutomationController.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using System.Windows.Forms; using DataLayer; @@ -201,23 +201,7 @@ namespace LibationWinForms.BookLiberation var statusHandler = await Processable.ProcessSingleAsync(libraryBook, validate); if (statusHandler.IsSuccess) - { - var destinationDir = AudibleFileStorage.Audio.GetDestinationDirectory(libraryBook); - var coverPath = FileManager.FileUtility.GetValidFilename(System.IO.Path.Combine(destinationDir, "Cover.jpg"), "", true); - - try - { - var picBytes = PictureStorage.GetPictureSynchronously(new PictureDefinition(libraryBook.Book.PictureId_1215, PictureSize._1215x1215)); - System.IO.File.WriteAllBytes(coverPath, picBytes); - } - catch(Exception ex) - { - LogMe.Error(ex.Message); - } - //Failure to download cover art should not be - //considered a failure to download the book return true; - } foreach (var errorMessage in statusHandler.Errors) LogMe.Error(errorMessage); From d848c1a499af995dd14bfb68aab79a8eaf05e5f6 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 May 2022 00:04:55 -0600 Subject: [PATCH 21/27] Cache book and pdf statuses for faster sorting. --- Source/LibationWinForms/grid/GridEntry.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index 0a6ab244..55499f66 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -32,6 +32,8 @@ namespace LibationWinForms #region Model properties exposed to the view private Image _cover; + private LiberatedStatus _bookStatus; + private LiberatedStatus? _pdfStatus; public Image Cover { get => _cover; @@ -63,10 +65,12 @@ namespace LibationWinForms // 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 { - get => (LibraryCommands.Liberated_Status(LibraryBook.Book), LibraryCommands.Pdf_Status(LibraryBook.Book)); + get => (_bookStatus, _pdfStatus); set { + _bookStatus = value.BookStatus; + _pdfStatus = value.PdfStatus; LibraryBook.Book.UserDefinedItem.BookStatus = value.BookStatus; LibraryBook.Book.UserDefinedItem.PdfStatus = value.PdfStatus; } @@ -110,6 +114,10 @@ namespace LibationWinForms LibraryBook = libraryBook; _memberValues = CreateMemberValueDictionary(); + //Cache these statuses for faster sorting. + _bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book); + _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book); + // Get cover art. If it's default, subscribe to PictureCached { (bool isDefault, byte[] picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80)); From 9559109aa861a41eb99ce4fb5c8e10118fe92fd8 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 May 2022 00:19:45 -0600 Subject: [PATCH 22/27] Fix liberated status cache --- Source/LibationWinForms/grid/GridEntry.cs | 26 ++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Source/LibationWinForms/grid/GridEntry.cs b/Source/LibationWinForms/grid/GridEntry.cs index 55499f66..ce9d552d 100644 --- a/Source/LibationWinForms/grid/GridEntry.cs +++ b/Source/LibationWinForms/grid/GridEntry.cs @@ -32,6 +32,8 @@ namespace LibationWinForms #region Model properties exposed to the view private Image _cover; + + private DateTime lastStatusUpdate = default; private LiberatedStatus _bookStatus; private LiberatedStatus? _pdfStatus; public Image Cover @@ -65,7 +67,16 @@ namespace LibationWinForms // 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 { - get => (_bookStatus, _pdfStatus); + get + { + //Cache these statuses for faster sorting. + if ((DateTime.Now - lastStatusUpdate).TotalSeconds > 2) + { + UpdateLiberatedStatus(notify: false); + lastStatusUpdate = DateTime.Now; + } + return (_bookStatus, _pdfStatus); + } set { @@ -93,6 +104,7 @@ namespace LibationWinForms { DownloadInProgress = true; await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(LibraryBook); + UpdateLiberatedStatus(); } finally { @@ -114,10 +126,6 @@ namespace LibationWinForms LibraryBook = libraryBook; _memberValues = CreateMemberValueDictionary(); - //Cache these statuses for faster sorting. - _bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book); - _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book); - // Get cover art. If it's default, subscribe to PictureCached { (bool isDefault, byte[] picture) = PictureStorage.GetPicture(new PictureDefinition(Book.PictureId, PictureSize._80x80)); @@ -223,6 +231,14 @@ namespace LibationWinForms Committed?.Invoke(this, null); } + private void UpdateLiberatedStatus(bool notify = true) + { + _bookStatus = LibraryCommands.Liberated_Status(LibraryBook.Book); + _pdfStatus = LibraryCommands.Pdf_Status(LibraryBook.Book); + if (notify) + NotifyPropertyChanged(nameof(Liberate)); + } + #endregion #region Data Sorting From df4739cbf4817e280345123af2d31705ed317ade Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 May 2022 08:40:42 -0600 Subject: [PATCH 23/27] Set description cell tooltip text --- .../LibationWinForms/grid/ProductsGrid.Designer.cs | 13 +++++++------ Source/LibationWinForms/grid/ProductsGrid.cs | 6 ++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs index 89f53316..b3eaecd5 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.Designer.cs @@ -32,7 +32,6 @@ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); this.gridEntryBindingSource = new LibationWinForms.SyncBindingSource(this.components); this.gridEntryDataGridView = new System.Windows.Forms.DataGridView(); - this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.liberateGVColumn = new LibationWinForms.LiberateDataGridViewImageButtonColumn(); this.coverGVColumn = new System.Windows.Forms.DataGridViewImageColumn(); this.titleGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); @@ -47,6 +46,7 @@ this.myRatingGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.miscGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); this.tagAndDetailsGVColumn = new LibationWinForms.EditTagsDataGridViewImageButtonColumn(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); ((System.ComponentModel.ISupportInitialize)(this.gridEntryBindingSource)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.gridEntryDataGridView)).BeginInit(); this.SuspendLayout(); @@ -97,14 +97,10 @@ this.gridEntryDataGridView.RowTemplate.Height = 82; this.gridEntryDataGridView.Size = new System.Drawing.Size(1510, 380); this.gridEntryDataGridView.TabIndex = 0; + 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); // - // contextMenuStrip1 - // - this.contextMenuStrip1.Name = "contextMenuStrip1"; - this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); - // // liberateGVColumn // this.liberateGVColumn.DataPropertyName = "Liberate"; @@ -217,6 +213,11 @@ this.tagAndDetailsGVColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False; this.tagAndDetailsGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; // + // contextMenuStrip1 + // + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); + // // ProductsGrid // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); diff --git a/Source/LibationWinForms/grid/ProductsGrid.cs b/Source/LibationWinForms/grid/ProductsGrid.cs index 7f8deb4d..239288b6 100644 --- a/Source/LibationWinForms/grid/ProductsGrid.cs +++ b/Source/LibationWinForms/grid/ProductsGrid.cs @@ -340,6 +340,12 @@ namespace LibationWinForms } } + private void gridEntryDataGridView_CellToolTipTextNeeded(object sender, DataGridViewCellToolTipTextNeededEventArgs e) + { + if (e.ColumnIndex == descriptionGVColumn.Index) + e.ToolTipText = "Click to see full description"; + } + #endregion } } From a5ff890ea14c6da02983d451ae03d17048a91ce0 Mon Sep 17 00:00:00 2001 From: Mbucari <37587114+Mbucari@users.noreply.github.com> Date: Tue, 10 May 2022 11:42:24 -0600 Subject: [PATCH 24/27] Delete LibationContext.db --- Source/DataLayer/LibationContext.db | Bin 122880 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Source/DataLayer/LibationContext.db diff --git a/Source/DataLayer/LibationContext.db b/Source/DataLayer/LibationContext.db deleted file mode 100644 index 9d9b5859305d4878404815196e67cee066031ba8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122880 zcmeI5&u<&Y700=vL{dK}I*F5w<2YHdRU=kvN=lYx9paXzRt{l`q)95VVFV0CuH{82 z(%xML(IE&V|A>pC=l0ZlfTrlFw;uW@q(FkAr=sYg1$wDZK~uz?*`Kq&BsrmvL*>P`pQmA6P6+;A|oS_9}7Yx5}6|JSIGM`d5@5Hmb^#F z+j?=ML68+0<84pHDuV%q4ymTS)ATy%K$K^zYnfsV@(Zfvm?N zu)mg!^D{Ht-MZG=>Pq#&ty^7bN9t+L(R86E<{P5W$X_gpLfXkl3v!6k21ZGdC6&sn+ecF#jCKZtQBOO_ z+QVoRdmZV6G%+Aw($NR-pblW_W*sn>Hgbpt3x?(7C=(!qGPPwq5vGS$YSeG4;rFF& zh})Y+GIb|YAjqLhQ!)P13>T3pQ1y0~^m@(KKA0JYC--nl76GP)gW6H8-J#x%a8!6}X4F=j%!$9vxij4jkIB<}Q|6rZF+xxq zd}BPuUzrbUgI+yzo`i{eBk?%T^W0C`cKqpGvYPP68rA8L0ms`8X?5f>*4u#tSborv z$;et&`kg^rqtv{kRk|T-G#q{DYm(YlR_uYt2dpVg^cT#`~u0}?kl^rf-o7imL~VMo0az^ zrPb{kXZ~?2Z5FFaihhgPYfFa}t&_fFH>?obRLPj7yR2!dO9p7`P}kgjFTmL331q`q zay1=AT*ZQ7c<(|i&YwEP?Z3_37#KrF+#QDY&}7|Hh29K!Bhk9@sG(?-4-AKLYljU) z(u?oCI~M0>XSq93-2kTDs_b#hZ48^`G%Y4IC|107F~yJ4&^)?Z(P_3nMwrWTVq$eP zM#rgZx`F0cuS&NE5(z)g>6pt*Pv%^Y&|4r^X70>IjoZP~1~fZnoY)(6NwNaT2rDxJ znBelYD<3PnilcW)tbAYJ6GF4vQpm%Bb*1&`@}|=>c$%MCnrV3SFkGU$MTVC92JN#Z zlIM|Pp+V#ODi`NhR=E9&?y6=}T;Gtl71CYxd+M9AO1qc9#1Xdx1Isv}Z_9LoFXZVc zL=e-st;jZql(!^BWkv{7EHSM(664=l2^&8H>uKf!lcUBX<%#JeIhdGkL{fiA{WkR= z^>%7u`s?XGPJcT65lO@g1V8`;KmY_l00ck)1V8`;KmY^|Ads1eR`|v2;$n6=mnHAB zOUq5Nh#}b1md)H^Zu#8n+1Jl5j7RIINYPw&b&;fUZN&k?KH;=7=KMvy1v{VNn%t$!fnN>7^E8 z(M_Y&c~X*SwX{M6?)2Z6HajvER_eF)i33`CIWuNezp}WJJD)w9Jx`S-b(1+zP3n*p zS8br`MSnONy>19Tw@5iGFP}FB=UX4N*QBis>ev#^?)>CJu|2_T1^sh-GULXJhAOHd&00JNY0w4eaAOHd& z@Lwh{8?A7MP8m$R7Om4#hs_p@o6-)RCrAiU(UcZEMG&8hZW;v+nH`AP^&K=ZFg72( zZiqX4PGHoo`jF{>==Y*msL(@Z0!H}g@_5iB0A2s*QvZyQAG|;S1V8`;KmY_l00ck) z1V8`;KmY`Wg}~S&>opchCL{FuKbrc2JpZTuOg``e0T2KI5C8!X009sH0T2KI5C8!X zcp3;in~-ia6VWK2(Ek`BH4>doFkh9SCb{TL!ujF`WBvbOB=zuVFb+C`00@8p2!H?x zfB*=900@8p2!H?x9F4%Jwf_HTl&t>K=YR60|9F7_2!H?xfB*=900@8p2!H?xfB*;# zF#-Dhe|Y{MVh6)C5C8!X009sH0T2KI5C8!X009sn1hD>(FaQA%009sH0T2KI5C8!X z009sHf#D~B_5b1bF)RcD5C8!X009sH0T2KI5C8!X00FH3BL+YK1V8`;KmY_l00ck) z1V8`;Kw$U@VEupieGCgh00ck)1V8`;KmY_l00ck)1V8}K|A+w)009sH0T2KI5C8!X z009sH0T38|0@(jQ{62<-AOHd&00JNY0w4eaAOHd&00JO@=YPZi2!H?xfB*=900@8p z2!H?xfB*;#KY`@v^~iYiWMujesZW!yO?^K3a55KLn0OdHY5e1!i~PW*kk}b}#Lv%j z_ja|`R#)0oC1p*zA@`(CQImE&r>R0s%r``#k-u0Hg|sI(EzBh+1oBE>?DyX*cG5zz z+z>B`HKAN-2<6RENhnmx^+qjE(uH*Oa?>ZES}ShkYuAL!;ygVAze{AlH#}CgOOE-At=nHZKW1$r)13PSQ+b= zn~sbo)l=1fQ)|{MHL-Z9OkF|*nl@wz>2n-y9^AUsm3E|_R=1C)JwCQG7$4hd zL4Ni|w<9_&ux`n3HY&w3scl0nH!SBL795*O_ux37KD5<)B0eM-6Fb~z6yyEv|FfoI zbQWw(lkUZc2};)O047?Fd%L)MArYq?;{&5(q^t`4o~FoK1Ff%kPRHFX#FOhZ6Pgj! zK&)72YB;D^t>2aWV~8ch>>9m8Oh89NBEhFB+aB$Hiv)vPHIkq!5z=RRq&|^G7hn%* z>E4dTRPSN3No;{55;+}#L-|0wX&@yfp%)1Wa#eBQnAM`XUgWQS)b2Y_3 z5l@otb7?BZUz*_}G9BsF+g(|cnk~}M^mC@WYUZ4-E1CL|`;HEmKQi3o#`TTy7=L9x zjH|b?iAg<*T}*M(oY`(Q&^nLq zR?{_&W`xnYSreB*ey5qb;c%FLa)sD4X$|Fi*( z^d8%Ndh1`Xk49aR(oP10%P72iBv!WIBapI?F!F647Pb(Y)s{l;Y)x%x2rcIsXc!Q47FLRo9b;-Dc~mSG8Z^GIa&dlTh1;*_u4*>L^$mGjA&-Fl zp8BS&l3SJCz{C-^0|U!AzO-dJ!58x28X|}Zf6GNxrQaE}wYMZiCCXYcZHgtP6-Q$H zJ1b#bS71HOTwrpPJkuxWb3Ok4-=5vT0SJHq2!H?xfB*=900@8p2!H?x3@rh=|Nq3u zCy~_N^gpJX$=@ZbQ-7N3k9;!uugRZ}|0dCo{W2zxeLeQGp#=cLo(=-{S}(W?rA$c&6%d7r>@D&kV!i8GG7JD0VZ=gwJx;?aD zzuls1r@jf}s@&EFiWF$$#_p|v z^&)fsN@8GVhfc$Hn{v(|WwPa3XCGw_S$HSwyD4lbUi3$f;g7kUwC8O-(D7?v!6OmR-WPka$*%9etfXz(N<^1}yc% z+6cB*nOnMSl!xRfPV`S=`q-fp46^@JDoH79-R9h=>R>OB0Zz|EtcQNe@YNx8Z8a-3h{xxF!~W2RW`(TEH|`uR!U2;ePd z^vHTDZJq2urJj!SKO$9}aaUn3CEGVR`n8FWioAtA)%mhB@+t3t^S=pU-nh% z3cA|rP&dVR^}0w&b;?L zF>sa{QJHNDYLl+Pvk5Qys%3Na;zo^ZGObr%%+Kt-dNR&mBjfiK%ZJSEO4#zcQ-t@| z?%eH!U2f`Q7o^&Rmd)%$y0>FV(Oz|`eBNMDbdN*44E=!q| zE~Z+T*%_?=KOK+1&=Led00ck)1V8`;KmY_l00ck)1ilRcJpX?idbkz@KmY_l00ck) z1V8`;KmY_l00f>60?haSpClUV-wE(^Xbvqw00ck)1V8`;KmY_l00ck)1V8`;j!J;8 z|8uFYBIE}z5C8!X009sH0T2KI5C8!X009sHf#D-C8clMK@cch~j)g@a00JNY0w4ea zAOHd&00JNY0wBN;7>!2o{Lk>fAqao~2!H?xfB*=900@8p2!H?x3?l)1{XcSI7|nxC zAOHd&00JNY0w4eaAOHd&00JNY0u}*$|Gz~7pCAANAOHd&00JNY0w4eaAOHd&F!TgC zV&O~VP5(Q9siC(P27&+xfB*=900@8p2!H?xfB*=9z%e6$_5Wk$aF`1MAOHd&00JNY z0w4eaAOHd&a4ZSX1%Leg|FLvEj0OP^009sH0T2KI5C8!X009s Date: Tue, 10 May 2022 12:01:23 -0600 Subject: [PATCH 25/27] Use new PictureIDLarge and PictureSize.Native --- Source/DtoImporterService/BookImporter.cs | 5 ++--- Source/FileLiberator/Processable.cs | 6 +++--- Source/LibationFileManager/PictureStorage.cs | 13 +++++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Source/DtoImporterService/BookImporter.cs b/Source/DtoImporterService/BookImporter.cs index 4c3cd74d..bc69f382 100644 --- a/Source/DtoImporterService/BookImporter.cs +++ b/Source/DtoImporterService/BookImporter.cs @@ -165,9 +165,8 @@ namespace DtoImporterService if (item.PictureId is not null) book.PictureId = item.PictureId; - // set/update book-specific info which may have changed - if (item.PictureId_1215 is not null) - book.PictureId_1215 = item.PictureId_1215; + if (item.PictureLarge is not null) + book.PictureLarge = item.PictureLarge; book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars); diff --git a/Source/FileLiberator/Processable.cs b/Source/FileLiberator/Processable.cs index 66e36d1c..56ca47a5 100644 --- a/Source/FileLiberator/Processable.cs +++ b/Source/FileLiberator/Processable.cs @@ -63,9 +63,9 @@ namespace FileLiberator try { - (string picId, PictureSize size) = libraryBook.Book.PictureId_1215 is null ? - (libraryBook.Book.PictureId, PictureSize._500x500) : - (libraryBook.Book.PictureId_1215, PictureSize._1215x1215); + (string picId, PictureSize size) = libraryBook.Book.PictureLarge is null ? + (libraryBook.Book.PictureId, PictureSize.Native) : + (libraryBook.Book.PictureLarge, PictureSize.Native); var picBytes = PictureStorage.GetPictureSynchronously(new PictureDefinition(picId, size)); diff --git a/Source/LibationFileManager/PictureStorage.cs b/Source/LibationFileManager/PictureStorage.cs index 4b6556ab..ba5cea1a 100644 --- a/Source/LibationFileManager/PictureStorage.cs +++ b/Source/LibationFileManager/PictureStorage.cs @@ -8,13 +8,13 @@ using System.Threading.Tasks; namespace LibationFileManager { - public enum PictureSize { _80x80 = 80, _300x300 = 300, _500x500 = 500 , _1215x1215 = 1215 } + public enum PictureSize { Native, _80x80 = 80, _300x300 = 300, _500x500 = 500 } public class PictureCachedEventArgs : EventArgs { public PictureDefinition Definition { get; internal set; } public byte[] Picture { get; internal set; } } - public struct PictureDefinition + public struct PictureDefinition : IEquatable { public string PictureId { get; } public PictureSize Size { get; } @@ -24,6 +24,11 @@ namespace LibationFileManager PictureId = pictureId; Size = pictureSize; } + + public bool Equals(PictureDefinition other) + { + return PictureId == other.PictureId && Size == other.Size; + } } public static class PictureStorage { @@ -113,8 +118,8 @@ namespace LibationFileManager try { - var sz = (int)def.Size; - var bytes = imageDownloadClient.GetByteArrayAsync("ht" + $"tps://images-na.ssl-images-amazon.com/images/I/{def.PictureId}._SL{sz}_.jpg").Result; + var sizeStr = def.Size == PictureSize.Native ? "" : $"._SL{(int)def.Size}_"; + var bytes = imageDownloadClient.GetByteArrayAsync("ht" + $"tps://images-na.ssl-images-amazon.com/images/I/{def.PictureId}{sizeStr}.jpg").Result; // save image file. make sure to not save default image var path = getPath(def); From 0091245734663e3d9381d3440c4adaf00e993602 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 May 2022 12:03:47 -0600 Subject: [PATCH 26/27] Revert PictureID_1215 migration and add PictureIDLarge migration --- Source/DataLayer/EfClasses/Book.cs | 2 +- ...> 20220510175257_AddPictureIDLargeMigration.Designer.cs} | 6 +++--- ...1215.cs => 20220510175257_AddPictureIDLargeMigration.cs} | 6 +++--- Source/DataLayer/Migrations/LibationContextModelSnapshot.cs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename Source/DataLayer/Migrations/{20220510051435_Add PictureId_1215.Designer.cs => 20220510175257_AddPictureIDLargeMigration.Designer.cs} (98%) rename Source/DataLayer/Migrations/{20220510051435_Add PictureId_1215.cs => 20220510175257_AddPictureIDLargeMigration.cs} (78%) diff --git a/Source/DataLayer/EfClasses/Book.cs b/Source/DataLayer/EfClasses/Book.cs index 59ae4395..63d3e7c3 100644 --- a/Source/DataLayer/EfClasses/Book.cs +++ b/Source/DataLayer/EfClasses/Book.cs @@ -34,7 +34,7 @@ namespace DataLayer // mutable public string PictureId { get; set; } - public string PictureId_1215 { get; set; } + public string PictureLarge { get; set; } // book details public bool IsAbridged { get; private set; } diff --git a/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.Designer.cs b/Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.Designer.cs similarity index 98% rename from Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.Designer.cs rename to Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.Designer.cs index 7c9f3f96..dae19073 100644 --- a/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.Designer.cs +++ b/Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.Designer.cs @@ -11,8 +11,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace DataLayer.Migrations { [DbContext(typeof(LibationContext))] - [Migration("20220510051435_Add PictureId_1215")] - partial class AddPictureId_1215 + [Migration("20220510175257_AddPictureIDLargeMigration")] + partial class AddPictureIDLargeMigration { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -52,7 +52,7 @@ namespace DataLayer.Migrations b.Property("PictureId") .HasColumnType("TEXT"); - b.Property("PictureId_1215") + b.Property("PictureLarge") .HasColumnType("TEXT"); b.Property("Title") diff --git a/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs b/Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.cs similarity index 78% rename from Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs rename to Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.cs index e4f6abed..10363132 100644 --- a/Source/DataLayer/Migrations/20220510051435_Add PictureId_1215.cs +++ b/Source/DataLayer/Migrations/20220510175257_AddPictureIDLargeMigration.cs @@ -4,12 +4,12 @@ namespace DataLayer.Migrations { - public partial class AddPictureId_1215 : Migration + public partial class AddPictureIDLargeMigration : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.AddColumn( - name: "PictureId_1215", + name: "PictureLarge", table: "Books", type: "TEXT", nullable: true); @@ -18,7 +18,7 @@ namespace DataLayer.Migrations protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropColumn( - name: "PictureId_1215", + name: "PictureLarge", table: "Books"); } } diff --git a/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs b/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs index f2e133fb..c198e3c0 100644 --- a/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs +++ b/Source/DataLayer/Migrations/LibationContextModelSnapshot.cs @@ -50,7 +50,7 @@ namespace DataLayer.Migrations b.Property("PictureId") .HasColumnType("TEXT"); - b.Property("PictureId_1215") + b.Property("PictureLarge") .HasColumnType("TEXT"); b.Property("Title") From 22e5c8746c2fe66710fee4748736e75619787131 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Tue, 10 May 2022 12:36:46 -0600 Subject: [PATCH 27/27] Updated Api --- Source/AudibleUtilities/AudibleUtilities.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/AudibleUtilities/AudibleUtilities.csproj b/Source/AudibleUtilities/AudibleUtilities.csproj index e345a1ee..1b933a47 100644 --- a/Source/AudibleUtilities/AudibleUtilities.csproj +++ b/Source/AudibleUtilities/AudibleUtilities.csproj @@ -5,7 +5,7 @@ - +