Merge pull request #997 from cbordeman/Friendly-name-filters-995

Implemented Name on Quick Filters.
This commit is contained in:
rmcrackan 2024-10-15 13:09:38 -04:00 committed by GitHub
commit 8a87462cf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 326 additions and 170 deletions

View File

@ -2,7 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Version>11.4.1.1</Version> <Version>11.5</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Octokit" Version="11.0.1" /> <PackageReference Include="Octokit" Version="11.0.1" />

View File

@ -1,21 +1,22 @@
using System; using ApplicationServices;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using ApplicationServices;
using AudibleUtilities; using AudibleUtilities;
using Dinah.Core;
using Dinah.Core.IO; using Dinah.Core.IO;
using Dinah.Core.Logging; using Dinah.Core.Logging;
using LibationFileManager; using LibationFileManager;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Serilog; using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace AppScaffolding namespace AppScaffolding
{ {
public enum ReleaseIdentifier public enum ReleaseIdentifier
{ {
None, None,
WindowsClassic = OS.Windows | Variety.Classic | Architecture.X64, WindowsClassic = OS.Windows | Variety.Classic | Architecture.X64,
@ -87,7 +88,8 @@ namespace AppScaffolding
// //
Migrations.migrate_to_v6_6_9(config); Migrations.migrate_to_v6_6_9(config);
} Migrations.migrate_to_v11_5_0(config);
}
/// <summary>Initialize logging. Wire-up events. Run after migration</summary> /// <summary>Initialize logging. Wire-up events. Run after migration</summary>
public static void RunPostMigrationScaffolding(Variety variety, Configuration config) public static void RunPostMigrationScaffolding(Variety variety, Configuration config)
@ -404,5 +406,55 @@ namespace AppScaffolding
UNSAFE_MigrationHelper.Settings_AddUniqueToArray("Serilog.Enrich", "WithExceptionDetails"); UNSAFE_MigrationHelper.Settings_AddUniqueToArray("Serilog.Enrich", "WithExceptionDetails");
} }
} }
}
class FilterState_6_6_9
{
public bool UseDefault { get; set; }
public List<string> Filters { get; set; } = new();
}
public static void migrate_to_v11_5_0(Configuration config)
{
// Read file, but convert old format to new (with Name field) as necessary.
if (!File.Exists(QuickFilters.JsonFile))
{
QuickFilters.InMemoryState = new();
return;
}
try
{
if (JsonConvert.DeserializeObject<QuickFilters.FilterState>(File.ReadAllText(QuickFilters.JsonFile))
is QuickFilters.FilterState inMemState)
{
QuickFilters.InMemoryState = inMemState;
return;
}
}
catch
{
// Eat
}
try
{
if (JsonConvert.DeserializeObject<FilterState_6_6_9>(File.ReadAllText(QuickFilters.JsonFile))
is FilterState_6_6_9 inMemState)
{
// Copy old structure to new.
QuickFilters.InMemoryState = new();
QuickFilters.InMemoryState.UseDefault = inMemState.UseDefault;
foreach (var oldFilter in inMemState.Filters)
QuickFilters.InMemoryState.Filters.Add(new QuickFilters.NamedFilter(oldFilter, null));
return;
}
Debug.Assert(false, "Should not get here, QuickFilters.json deserialization issue");
}
catch
{
// Eat
}
}
}
} }

View File

@ -2,11 +2,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350" mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="350"
Width="800" Height="450" Width="800" Height="450"
x:Class="LibationAvalonia.Dialogs.EditQuickFilters" x:Class="LibationAvalonia.Dialogs.EditQuickFilters"
Title="Audible Accounts" Title="Audible Accounts"
Icon="/Assets/libation.ico"> Icon="/Assets/libation.ico"
x:DataType="dialogs:EditQuickFilters">
<Grid RowDefinitions="*,Auto"> <Grid RowDefinitions="*,Auto">
<Grid.Styles> <Grid.Styles>
@ -43,7 +45,14 @@
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTextColumn
Width="*"
IsReadOnly="False"
Binding="{Binding Name, Mode=TwoWay}"
Header="Name"/>
<DataGridTextColumn <DataGridTextColumn
Width="*" Width="*"
IsReadOnly="False" IsReadOnly="False"

View File

@ -12,8 +12,18 @@ namespace LibationAvalonia.Dialogs
public ObservableCollection<Filter> Filters { get; } = new(); public ObservableCollection<Filter> Filters { get; } = new();
public class Filter : ViewModels.ViewModelBase public class Filter : ViewModels.ViewModelBase
{ {
private string _filterString; private string _name;
public string Name
{
get => _name;
set
{
this.RaiseAndSetIfChanged(ref _name, value);
}
}
private string _filterString;
public string FilterString public string FilterString
{ {
get => _filterString; get => _filterString;
@ -25,6 +35,9 @@ namespace LibationAvalonia.Dialogs
} }
} }
public bool IsDefault { get; private set; } = true; public bool IsDefault { get; private set; } = true;
public QuickFilters.NamedFilter AsNamedFilter() => new(FilterString, Name);
} }
public EditQuickFilters() public EditQuickFilters()
{ {
@ -40,7 +53,7 @@ namespace LibationAvalonia.Dialogs
ControlToFocusOnShow = this.FindControl<Button>(nameof(saveBtn)); ControlToFocusOnShow = this.FindControl<Button>(nameof(saveBtn));
var allFilters = QuickFilters.Filters.Select(f => new Filter { FilterString = f }).ToList(); var allFilters = QuickFilters.Filters.Select(f => new Filter { FilterString = f.Filter, Name = f.Name }).ToList();
allFilters.Add(new Filter()); allFilters.Add(new Filter());
foreach (var f in allFilters) foreach (var f in allFilters)
@ -61,7 +74,7 @@ namespace LibationAvalonia.Dialogs
protected override void SaveAndClose() protected override void SaveAndClose()
{ {
QuickFilters.ReplaceAll(Filters.Where(f => !f.IsDefault).Select(f => f.FilterString)); QuickFilters.ReplaceAll(Filters.Where(f => !f.IsDefault).Select(x => x.AsNamedFilter()));
base.SaveAndClose(); base.SaveAndClose();
} }

View File

@ -13,12 +13,12 @@ namespace LibationAvalonia.ViewModels
{ {
partial class MainVM partial class MainVM
{ {
private string lastGoodFilter = ""; private QuickFilters.NamedFilter lastGoodFilter = new(string.Empty, null);
private string _filterString; private QuickFilters.NamedFilter _selectedNamedFilter;
private bool _firstFilterIsDefault = true; private bool _firstFilterIsDefault = true;
/// <summary> Library filterting query </summary> /// <summary> Library filterting query </summary>
public string FilterString { get => _filterString; set => this.RaiseAndSetIfChanged(ref _filterString, value); } public QuickFilters.NamedFilter SelectedNamedFilter { get => _selectedNamedFilter; set => this.RaiseAndSetIfChanged(ref _selectedNamedFilter, value); }
public AvaloniaList<Control> QuickFilterMenuItems { get; } = new(); public AvaloniaList<Control> QuickFilterMenuItems { get; } = new();
/// <summary> Indicates if the first quick filter is the default filter </summary> /// <summary> Indicates if the first quick filter is the default filter </summary>
public bool FirstFilterIsDefault { get => _firstFilterIsDefault; set => QuickFilters.UseDefault = this.RaiseAndSetIfChanged(ref _firstFilterIsDefault, value); } public bool FirstFilterIsDefault { get => _firstFilterIsDefault; set => QuickFilters.UseDefault = this.RaiseAndSetIfChanged(ref _firstFilterIsDefault, value); }
@ -50,19 +50,19 @@ namespace LibationAvalonia.ViewModels
QuickFilterMenuItems.Add(new Separator()); QuickFilterMenuItems.Add(new Separator());
} }
public void AddQuickFilterBtn() => QuickFilters.Add(FilterString); public void AddQuickFilterBtn() => QuickFilters.Add(SelectedNamedFilter);
public async Task FilterBtn() => await PerformFilter(FilterString); public async Task FilterBtn() => await PerformFilter(SelectedNamedFilter);
public async Task FilterHelpBtn() => await new LibationAvalonia.Dialogs.SearchSyntaxDialog().ShowDialog(MainWindow); public async Task FilterHelpBtn() => await new LibationAvalonia.Dialogs.SearchSyntaxDialog().ShowDialog(MainWindow);
public void ToggleFirstFilterIsDefault() => FirstFilterIsDefault = !FirstFilterIsDefault; public void ToggleFirstFilterIsDefault() => FirstFilterIsDefault = !FirstFilterIsDefault;
public async Task EditQuickFiltersAsync() => await new LibationAvalonia.Dialogs.EditQuickFilters().ShowDialog(MainWindow); public async Task EditQuickFiltersAsync() => await new LibationAvalonia.Dialogs.EditQuickFilters().ShowDialog(MainWindow);
public async Task PerformFilter(string filterString) public async Task PerformFilter(QuickFilters.NamedFilter namedFilter)
{ {
FilterString = filterString; SelectedNamedFilter = namedFilter;
try try
{ {
await ProductsDisplay.Filter(filterString); await ProductsDisplay.Filter(namedFilter.Filter);
lastGoodFilter = filterString; lastGoodFilter = namedFilter;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -99,8 +99,8 @@ namespace LibationAvalonia.ViewModels
{ {
var command = ReactiveCommand.Create(async () => await PerformFilter(filter)); var command = ReactiveCommand.Create(async () => await PerformFilter(filter));
var menuItem = new MenuItem { Header = $"{++index}: {filter}", Command = command }; var menuItem = new MenuItem { Header = $"{++index}: {(string.IsNullOrWhiteSpace(filter.Name) ? filter.Filter : filter.Name)}", Command = command };
var nativeMenuItem = new NativeMenuItem { Header = $"{index}: {filter}", Command = command }; var nativeMenuItem = new NativeMenuItem { Header = $"{index}: {(string.IsNullOrWhiteSpace(filter.Name) ? filter.Filter : filter.Name)}", Command = command };
if (Configuration.IsMacOs && index <= 10) if (Configuration.IsMacOs && index <= 10)
{ {

View File

@ -191,7 +191,7 @@
<Button IsVisible="{CompiledBinding RemoveButtonsVisible}" Command="{CompiledBinding DoneRemovingBtn}" Content="Done Removing Books"/> <Button IsVisible="{CompiledBinding RemoveButtonsVisible}" Command="{CompiledBinding DoneRemovingBtn}" Content="Done Removing Books"/>
</StackPanel> </StackPanel>
<TextBox Grid.Column="1" Margin="10,0,0,0" Name="filterSearchTb" IsVisible="{CompiledBinding !RemoveButtonsVisible}" Text="{CompiledBinding FilterString, Mode=TwoWay}" KeyDown="filterSearchTb_KeyPress" /> <TextBox Grid.Column="1" Margin="10,0,0,0" Name="filterSearchTb" IsVisible="{CompiledBinding !RemoveButtonsVisible}" Text="{CompiledBinding SelectedNamedFilter, Mode=TwoWay}" KeyDown="filterSearchTb_KeyPress" />
<StackPanel Grid.Column="2" Height="30" Orientation="Horizontal"> <StackPanel Grid.Column="2" Height="30" Orientation="Horizontal">
<Button Name="filterBtn" Command="{CompiledBinding FilterBtn}" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="Filter"/> <Button Name="filterBtn" Command="{CompiledBinding FilterBtn}" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="Filter"/>

View File

@ -79,7 +79,7 @@ namespace LibationAvalonia.Views
{ {
if (e.Key == Key.Return) if (e.Key == Key.Return)
{ {
await ViewModel.PerformFilter(ViewModel.FilterString); await ViewModel.PerformFilter(ViewModel.SelectedNamedFilter);
// silence the 'ding' // silence the 'ding'
e.Handled = true; e.Handled = true;

View File

@ -1,9 +1,9 @@
using System; using Dinah.Core.Collections.Generic;
using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Dinah.Core.Collections.Generic;
using Newtonsoft.Json;
#nullable enable #nullable enable
namespace LibationFileManager namespace LibationFileManager
@ -14,24 +14,21 @@ namespace LibationFileManager
public static event EventHandler? UseDefaultChanged; public static event EventHandler? UseDefaultChanged;
internal class FilterState public class FilterState
{ {
public bool UseDefault { get; set; } public bool UseDefault { get; set; }
public List<string> Filters { get; set; } = new List<string>(); public List<NamedFilter> Filters { get; set; } = new();
} }
public static string JsonFile => Path.Combine(Configuration.Instance.LibationFiles, "QuickFilters.json"); public static string JsonFile => Path.Combine(Configuration.Instance.LibationFiles, "QuickFilters.json");
// load json into memory. if file doesn't exist, nothing to do. save() will create if needed // load json into memory. if file doesn't exist, nothing to do. save() will create if needed
static FilterState inMemoryState { get; } public static FilterState InMemoryState { get; set; } = null!;
= File.Exists(JsonFile) && JsonConvert.DeserializeObject<FilterState>(File.ReadAllText(JsonFile)) is FilterState inMemState
? inMemState
: new FilterState();
public static bool UseDefault public static bool UseDefault
{ {
get => inMemoryState.UseDefault; get => InMemoryState.UseDefault;
set set
{ {
if (UseDefault == value) if (UseDefault == value)
@ -39,7 +36,7 @@ namespace LibationFileManager
lock (locker) lock (locker)
{ {
inMemoryState.UseDefault = value; InMemoryState.UseDefault = value;
save(false); save(false);
} }
@ -47,68 +44,81 @@ namespace LibationFileManager
} }
} }
public static IEnumerable<string> Filters => inMemoryState.Filters.AsReadOnly(); // Note that records overload equality automagically, so should be able to
// compare these the same way as comparing simple strings.
public static void Add(string filter) public record NamedFilter(string Filter, string Name)
{ {
if (string.IsNullOrWhiteSpace(filter)) public string Filter { get; set; } = Filter;
public string? Name { get; set; } = Name;
}
public static IEnumerable<NamedFilter> Filters => InMemoryState.Filters.AsReadOnly();
public static void Add(NamedFilter namedFilter)
{
if (namedFilter == null)
throw new ArgumentNullException(nameof(namedFilter));
if (string.IsNullOrWhiteSpace(namedFilter.Filter))
return; return;
filter = filter.Trim(); namedFilter.Filter = namedFilter.Filter?.Trim() ?? string.Empty;
namedFilter.Name = namedFilter.Name?.Trim() ?? null;
lock (locker) lock (locker)
{ {
// check for duplicate // check for duplicates
if (inMemoryState.Filters.ContainsInsensative(filter)) if (InMemoryState.Filters.Select(x => x.Filter).ContainsInsensative(namedFilter.Filter))
return; return;
inMemoryState.Filters.Add(filter); InMemoryState.Filters.Add(namedFilter);
save(); save();
} }
} }
public static void Remove(string filter) public static void Remove(NamedFilter filter)
{ {
lock (locker) lock (locker)
{ {
inMemoryState.Filters.Remove(filter); InMemoryState.Filters.Remove(filter);
save(); save();
} }
} }
public static void Edit(string oldFilter, string newFilter) public static void Edit(NamedFilter oldFilter, NamedFilter newFilter)
{ {
lock (locker) lock (locker)
{ {
var index = inMemoryState.Filters.IndexOf(oldFilter); var index = InMemoryState.Filters.IndexOf(oldFilter);
if (index < 0) if (index < 0)
return; return;
inMemoryState.Filters = inMemoryState.Filters.Select(f => f == oldFilter ? newFilter : f).ToList(); InMemoryState.Filters = InMemoryState.Filters.Select(f => f == oldFilter ? newFilter : f).ToList();
save(); save();
} }
} }
public static void ReplaceAll(IEnumerable<string> filters) public static void ReplaceAll(IEnumerable<NamedFilter> filters)
{ {
filters = filters filters = filters
.Where(f => !string.IsNullOrWhiteSpace(f)) .Where(f => !string.IsNullOrWhiteSpace(f.Filter))
.Distinct() .Distinct();
.Select(f => f.Trim()); foreach (var filter in filters)
filter.Filter = filter.Filter.Trim();
lock (locker) lock (locker)
{ {
inMemoryState.Filters = new List<string>(filters); InMemoryState.Filters = new List<NamedFilter>(filters);
save(); save();
} }
} }
private static object locker { get; } = new object(); private static object locker { get; } = new();
// ONLY call this within lock() // ONLY call this within lock()
private static void save(bool invokeUpdatedEvent = true) private static void save(bool invokeUpdatedEvent = true)
{ {
// create json if not exists // create json if not exists
void resave() => File.WriteAllText(JsonFile, JsonConvert.SerializeObject(inMemoryState, Formatting.Indented)); void resave() => File.WriteAllText(JsonFile, JsonConvert.SerializeObject(InMemoryState, Formatting.Indented));
try { resave(); } try { resave(); }
catch (IOException) catch (IOException)
{ {

View File

@ -28,116 +28,127 @@
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
this.cancelBtn = new System.Windows.Forms.Button(); cancelBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button(); saveBtn = new System.Windows.Forms.Button();
this.dataGridView1 = new System.Windows.Forms.DataGridView(); dataGridView1 = new System.Windows.Forms.DataGridView();
this.Original = new System.Windows.Forms.DataGridViewTextBoxColumn(); Original = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Delete = new DisableButtonColumn(); Delete = new DisableButtonColumn();
this.Filter = new System.Windows.Forms.DataGridViewTextBoxColumn(); FilterName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.MoveUp = new DisableButtonColumn(); Filter = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.MoveDown = new DisableButtonColumn(); MoveUp = new DisableButtonColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); MoveDown = new DisableButtonColumn();
this.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
SuspendLayout();
// //
// cancelBtn // cancelBtn
// //
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); cancelBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel; cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(713, 415); cancelBtn.Location = new System.Drawing.Point(1248, 726);
this.cancelBtn.Name = "cancelBtn"; cancelBtn.Margin = new System.Windows.Forms.Padding(5);
this.cancelBtn.Size = new System.Drawing.Size(75, 23); cancelBtn.Name = "cancelBtn";
this.cancelBtn.TabIndex = 2; cancelBtn.Size = new System.Drawing.Size(131, 40);
this.cancelBtn.Text = "Cancel"; cancelBtn.TabIndex = 2;
this.cancelBtn.UseVisualStyleBackColor = true; cancelBtn.Text = "Cancel";
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click); cancelBtn.UseVisualStyleBackColor = true;
cancelBtn.Click += cancelBtn_Click;
// //
// saveBtn // saveBtn
// //
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); saveBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
this.saveBtn.Location = new System.Drawing.Point(612, 415); saveBtn.Location = new System.Drawing.Point(1071, 726);
this.saveBtn.Name = "saveBtn"; saveBtn.Margin = new System.Windows.Forms.Padding(5);
this.saveBtn.Size = new System.Drawing.Size(75, 23); saveBtn.Name = "saveBtn";
this.saveBtn.TabIndex = 1; saveBtn.Size = new System.Drawing.Size(131, 40);
this.saveBtn.Text = "Save"; saveBtn.TabIndex = 1;
this.saveBtn.UseVisualStyleBackColor = true; saveBtn.Text = "Save";
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click); saveBtn.UseVisualStyleBackColor = true;
saveBtn.Click += saveBtn_Click;
// //
// dataGridView1 // dataGridView1
// //
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) dataGridView1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
| System.Windows.Forms.AnchorStyles.Left) dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
| System.Windows.Forms.AnchorStyles.Right))); dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells; dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { Original, Delete, FilterName, Filter, MoveUp, MoveDown });
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; dataGridView1.Location = new System.Drawing.Point(21, 21);
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { dataGridView1.Margin = new System.Windows.Forms.Padding(5);
this.Original, dataGridView1.MultiSelect = false;
this.Delete, dataGridView1.Name = "dataGridView1";
this.Filter, dataGridView1.RowHeadersWidth = 72;
this.MoveUp, dataGridView1.Size = new System.Drawing.Size(1358, 695);
this.MoveDown}); dataGridView1.TabIndex = 0;
this.dataGridView1.Location = new System.Drawing.Point(12, 12); dataGridView1.CellContentClick += DataGridView1_CellContentClick;
this.dataGridView1.MultiSelect = false; dataGridView1.DefaultValuesNeeded += dataGridView1_DefaultValuesNeeded;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(776, 397);
this.dataGridView1.TabIndex = 0;
this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.DataGridView1_CellContentClick);
this.dataGridView1.DefaultValuesNeeded += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView1_DefaultValuesNeeded);
// //
// Original // Original
// //
this.Original.HeaderText = "Original"; Original.HeaderText = "Original";
this.Original.Name = "Original"; Original.MinimumWidth = 9;
this.Original.ReadOnly = true; Original.Name = "Original";
this.Original.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; Original.ReadOnly = true;
this.Original.Visible = false; Original.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Original.Width = 48; Original.Visible = false;
Original.Width = 150;
// //
// Delete // Delete
// //
this.Delete.HeaderText = "Delete"; Delete.HeaderText = "Delete";
this.Delete.Name = "Delete"; Delete.MinimumWidth = 9;
this.Delete.ReadOnly = true; Delete.Name = "Delete";
this.Delete.Text = "x"; Delete.ReadOnly = true;
this.Delete.Width = 44; Delete.Text = "x";
Delete.Width = 127;
//
// FilterName
//
FilterName.HeaderText = "Name";
FilterName.MinimumWidth = 300;
FilterName.Name = "FilterName";
FilterName.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
FilterName.Width = 300;
// //
// Filter // Filter
// //
this.Filter.HeaderText = "Filter"; Filter.HeaderText = "Filter";
this.Filter.Name = "Filter"; Filter.MinimumWidth = 400;
this.Filter.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; Filter.Name = "Filter";
this.Filter.Width = 35; Filter.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
Filter.Width = 400;
// //
// MoveUp // MoveUp
// //
this.MoveUp.HeaderText = "Move Up"; MoveUp.HeaderText = "Move Up";
this.MoveUp.Name = "MoveUp"; MoveUp.MinimumWidth = 9;
this.MoveUp.ReadOnly = true; MoveUp.Name = "MoveUp";
this.MoveUp.Text = "^"; MoveUp.ReadOnly = true;
this.MoveUp.Width = 57; MoveUp.Text = "^";
MoveUp.Width = 169;
// //
// MoveDown // MoveDown
// //
this.MoveDown.HeaderText = "Move Down"; MoveDown.HeaderText = "Move Down";
this.MoveDown.Name = "MoveDown"; MoveDown.MinimumWidth = 9;
this.MoveDown.ReadOnly = true; MoveDown.Name = "MoveDown";
this.MoveDown.Text = "v"; MoveDown.ReadOnly = true;
this.MoveDown.Width = 71; MoveDown.Text = "v";
MoveDown.Width = 215;
// //
// EditQuickFilters // EditQuickFilters
// //
this.AcceptButton = this.saveBtn; AcceptButton = saveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); AutoScaleDimensions = new System.Drawing.SizeF(168F, 168F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.CancelButton = this.cancelBtn; CancelButton = cancelBtn;
this.ClientSize = new System.Drawing.Size(800, 450); ClientSize = new System.Drawing.Size(1400, 788);
this.Controls.Add(this.dataGridView1); Controls.Add(dataGridView1);
this.Controls.Add(this.cancelBtn); Controls.Add(cancelBtn);
this.Controls.Add(this.saveBtn); Controls.Add(saveBtn);
this.Name = "EditQuickFilters"; Margin = new System.Windows.Forms.Padding(5);
this.Text = "Edit Quick Filters"; Name = "EditQuickFilters";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); Text = "Edit Quick Filters";
this.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
ResumeLayout(false);
} }
#endregion #endregion
@ -146,6 +157,7 @@
private System.Windows.Forms.DataGridView dataGridView1; private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewTextBoxColumn Original; private System.Windows.Forms.DataGridViewTextBoxColumn Original;
private DisableButtonColumn Delete; private DisableButtonColumn Delete;
private System.Windows.Forms.DataGridViewTextBoxColumn FilterName;
private System.Windows.Forms.DataGridViewTextBoxColumn Filter; private System.Windows.Forms.DataGridViewTextBoxColumn Filter;
private DisableButtonColumn MoveUp; private DisableButtonColumn MoveUp;
private DisableButtonColumn MoveDown; private DisableButtonColumn MoveDown;

View File

@ -6,14 +6,6 @@ using LibationFileManager;
namespace LibationWinForms.Dialogs namespace LibationWinForms.Dialogs
{ {
public class DisableButtonColumn : DataGridViewButtonColumn
{
public DisableButtonColumn()
{
CellTemplate = new EditQuickFilters.DisableButtonCell();
}
}
public partial class EditQuickFilters : Form public partial class EditQuickFilters : Form
{ {
private const string BLACK_UP_POINTING_TRIANGLE = "\u25B2"; private const string BLACK_UP_POINTING_TRIANGLE = "\u25B2";
@ -21,7 +13,8 @@ namespace LibationWinForms.Dialogs
private const string COL_Original = nameof(Original); private const string COL_Original = nameof(Original);
private const string COL_Delete = nameof(Delete); private const string COL_Delete = nameof(Delete);
private const string COL_Filter = nameof(Filter); private const string COL_Filter = nameof(Filter);
private const string COL_MoveUp = nameof(MoveUp); private const string COL_FilterName = nameof(FilterName);
private const string COL_MoveUp = nameof(MoveUp);
private const string COL_MoveDown = nameof(MoveDown); private const string COL_MoveDown = nameof(MoveDown);
internal class DisableButtonCell : AccessibleDataGridViewButtonCell internal class DisableButtonCell : AccessibleDataGridViewButtonCell
@ -76,10 +69,11 @@ namespace LibationWinForms.Dialogs
return; return;
foreach (var filter in filters) foreach (var filter in filters)
dataGridView1.Rows.Add(filter, "X", filter, BLACK_UP_POINTING_TRIANGLE, BLACK_DOWN_POINTING_TRIANGLE); dataGridView1.Rows.Add(filter.Filter, "X", filter.Name, filter.Filter, BLACK_UP_POINTING_TRIANGLE, BLACK_DOWN_POINTING_TRIANGLE);
} //dataGridView1.Rows.Add(filter, "X", filter, BLACK_UP_POINTING_TRIANGLE, BLACK_DOWN_POINTING_TRIANGLE);
}
private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e) private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
{ {
e.Row.Cells[COL_Delete].Value = "X"; e.Row.Cells[COL_Delete].Value = "X";
e.Row.Cells[COL_MoveUp].Value = BLACK_UP_POINTING_TRIANGLE; e.Row.Cells[COL_MoveUp].Value = BLACK_UP_POINTING_TRIANGLE;
@ -90,7 +84,9 @@ namespace LibationWinForms.Dialogs
{ {
var list = dataGridView1.Rows var list = dataGridView1.Rows
.OfType<DataGridViewRow>() .OfType<DataGridViewRow>()
.Select(r => r.Cells[COL_Filter].Value?.ToString()) .Select(r => new QuickFilters.NamedFilter(
r.Cells[COL_Filter].Value?.ToString(),
r.Cells[COL_FilterName].Value?.ToString()))
.ToList(); .ToList();
QuickFilters.ReplaceAll(list); QuickFilters.ReplaceAll(list);
@ -137,4 +133,12 @@ namespace LibationWinForms.Dialogs
} }
} }
} }
public class DisableButtonColumn : DataGridViewButtonColumn
{
public DisableButtonColumn()
{
CellTemplate = new EditQuickFilters.DisableButtonCell();
}
}
} }

View File

@ -1,5 +1,64 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
@ -61,16 +120,10 @@
<metadata name="Original.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Original.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Delete.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="FilterName.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="Filter.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="Filter.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value> <value>True</value>
</metadata> </metadata>
<metadata name="MoveUp.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="MoveDown.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root> </root>

View File

@ -34,9 +34,9 @@ namespace LibationWinForms
var quickFilterMenuItem = new ToolStripMenuItem var quickFilterMenuItem = new ToolStripMenuItem
{ {
Tag = quickFilterTag, Tag = quickFilterTag,
Text = $"&{++index}: {filter}" Text = $"&{++index}: {(string.IsNullOrWhiteSpace(filter.Name) ? filter.Filter : filter.Name)}"
}; };
quickFilterMenuItem.Click += (_, __) => performFilter(filter); quickFilterMenuItem.Click += (_, __) => performFilter(filter.Filter);
quickFiltersToolStripMenuItem.DropDownItems.Add(quickFilterMenuItem); quickFiltersToolStripMenuItem.DropDownItems.Add(quickFilterMenuItem);
} }
} }
@ -47,14 +47,17 @@ namespace LibationWinForms
private void firstFilterIsDefaultToolStripMenuItem_Click(object sender, EventArgs e) private void firstFilterIsDefaultToolStripMenuItem_Click(object sender, EventArgs e)
=> QuickFilters.UseDefault = !firstFilterIsDefaultToolStripMenuItem.Checked; => QuickFilters.UseDefault = !firstFilterIsDefaultToolStripMenuItem.Checked;
private void addQuickFilterBtn_Click(object sender, EventArgs e) => QuickFilters.Add(this.filterSearchTb.Text); private void addQuickFilterBtn_Click(object sender, EventArgs e)
{
QuickFilters.Add(new QuickFilters.NamedFilter(this.filterSearchTb.Text, null));
}
private void editQuickFiltersToolStripMenuItem_Click(object sender, EventArgs e) => new EditQuickFilters().ShowDialog(); private void editQuickFiltersToolStripMenuItem_Click(object sender, EventArgs e) => new EditQuickFilters().ShowDialog();
private void productsDisplay_InitialLoaded(object sender, EventArgs e) private void productsDisplay_InitialLoaded(object sender, EventArgs e)
{ {
if (QuickFilters.UseDefault) if (QuickFilters.UseDefault)
performFilter(QuickFilters.Filters.FirstOrDefault()); performFilter(QuickFilters.Filters.FirstOrDefault().Filter);
} }
} }
} }