Compare commits

...

19 Commits

Author SHA1 Message Date
Robert McRackan
8b76da0dbe incr ver 2024-10-25 15:05:08 -04:00
Mbucari
0a749d2d88 Update Bundle_MacOS.sh 2024-10-25 10:51:56 -06:00
Robert McRackan
4521c5d5ed incr ver 2024-10-16 12:04:04 -04:00
rmcrackan
eb39f994e1 Merge pull request #1006 from cbordeman/Friendly-name-filters-995
Fixed bug in main view quick filter binding.
2024-10-16 08:03:44 -04:00
Chris Bordeman
c19833b34e Fixed bug in main view quick filter binding. 2024-10-15 21:46:22 -04:00
Robert McRackan
6dcf456d06 fix ver 2024-10-15 13:20:58 -04:00
rmcrackan
8a87462cf5 Merge pull request #997 from cbordeman/Friendly-name-filters-995
Implemented Name on Quick Filters.
2024-10-15 13:09:38 -04:00
Chris Bordeman
9da2a44eff Small fix 2024-10-15 00:13:40 -04:00
Chris Bordeman
7af8d8aa70 Remove some warnings. 2024-10-15 00:07:57 -04:00
Chris Bordeman
4801f37e7c Moved QuickFilters migration to AppScaffolding. 2024-10-14 23:59:05 -04:00
rmcrackan
4f5df44d40 Merge pull request #999 from cbordeman/Add-default-theme-setting
Implemented "System" option for theme.
2024-10-14 15:09:21 -04:00
Chris Bordeman
63e28b13c1 Implemented "System" option for theme. 2024-10-12 02:17:35 -04:00
Chris Bordeman
f92b2b65b2 Implemented Name on Quick Filters. 2024-10-11 05:45:04 -04:00
rmcrackan
f7a4a95e3b Merge pull request #994 from cbordeman/master
Disable shrink/expand on mouseover for all scrollbars.
2024-10-10 07:38:24 -04:00
Chris Bordeman
71b8e9e51c Disable shrink/expand on mouseover for all scrollbars. 2024-10-10 02:22:36 -04:00
Robert McRackan
c6788ccb48 typo 2024-09-25 10:12:01 -04:00
Robert McRackan
0503ee1404 incr ver 2024-09-18 08:17:35 -04:00
rmcrackan
303192c6c3 Merge pull request #978 from muchtall/allow-UseCoverAsFolderIcon-on-linux
Allow Non-Windows installations to populate Windows folder artwork
2024-09-18 08:15:05 -04:00
muchtall
6e21e96aa2 Allow Non-Windows installations to populate Windows folder artwork (https://github.com/rmcrackan/Libation/issues/977) 2024-09-16 19:42:26 +00:00
19 changed files with 356 additions and 187 deletions

View File

@@ -86,8 +86,12 @@ delfiles=( 'libmp3lame.arm64.so' 'libmp3lame.x64.so' 'libmp3lame.x64.dll' 'libmp
if [[ "$ARCH" == "arm64" ]]
then
delfiles+=('libmp3lame.x64.dylib' 'ffmpegaac.x64.dylib')
mv $BUNDLE_MACOS/ffmpegaac.arm64.dylib $BUNDLE_MACOS/ffmpegaac.dylib
mv $BUNDLE_MACOS/libmp3lame.arm64.dylib $BUNDLE_MACOS/libmp3lame.dylib
else
delfiles+=('libmp3lame.arm64.dylib' 'ffmpegaac.arm64.dylib')
mv $BUNDLE_MACOS/ffmpegaac.x64.dylib $BUNDLE_MACOS/ffmpegaac.dylib
mv $BUNDLE_MACOS/libmp3lame.x64.dylib $BUNDLE_MACOS/libmp3lame.dylib
fi
@@ -111,4 +115,4 @@ mv $APP_FILE ./bundle/$APP_FILE
rm -r $BUNDLE
echo "Done!"
echo "Done!"

View File

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

View File

@@ -1,21 +1,22 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using ApplicationServices;
using ApplicationServices;
using AudibleUtilities;
using Dinah.Core;
using Dinah.Core.IO;
using Dinah.Core.Logging;
using LibationFileManager;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
namespace AppScaffolding
{
public enum ReleaseIdentifier
public enum ReleaseIdentifier
{
None,
WindowsClassic = OS.Windows | Variety.Classic | Architecture.X64,
@@ -87,7 +88,8 @@ namespace AppScaffolding
//
Migrations.migrate_to_v6_6_9(config);
}
Migrations.migrate_to_v11_5_0(config);
}
/// <summary>Initialize logging. Wire-up events. Run after migration</summary>
public static void RunPostMigrationScaffolding(Variety variety, Configuration config)
@@ -404,5 +406,55 @@ namespace AppScaffolding
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

@@ -191,7 +191,7 @@ namespace DataLayer
ArgumentValidator.EnsureNotNull(ladders, nameof(ladders));
//Replace all existing category ladders.
//Some books make have duplocate ladders
//Some books make have duplicate ladders
CategoriesLink.Clear();
CategoriesLink.UnionWith(ladders.Distinct().Select(l => new BookCategory(this, l)));
}

View File

@@ -77,6 +77,10 @@
<Style Selector="Button">
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
<Style Selector="ScrollBar">
<!-- It's called AutoHide, but this is really the mouseover shrink/expand. -->
<Setter Property="AllowAutoHide" Value="false"/>
</Style>
</Application.Styles>
<NativeMenu.Menu>

View File

@@ -90,14 +90,10 @@ namespace LibationAvalonia
if (setupDialog.Config.LibationSettingsAreValid)
{
var theme
= setupDialog.SelectedTheme.Content is nameof(ThemeVariant.Dark)
? nameof(ThemeVariant.Dark)
: nameof(ThemeVariant.Light);
string theme = setupDialog.SelectedTheme.Content as string;
setupDialog.Config.SetString(theme, nameof(ThemeVariant));
await RunMigrationsAsync(setupDialog.Config);
LibraryTask = Task.Run(() => DbContexts.GetLibrary_Flat_NoTracking(includeParents: true));
AudibleUtilities.AudibleApiStorage.EnsureAccountsSettingsFileExists();
@@ -208,9 +204,15 @@ namespace LibationAvalonia
private static void ShowMainWindow(IClassicDesktopStyleApplicationLifetime desktop)
{
Current.RequestedThemeVariant = Configuration.Instance.GetString(propertyName: nameof(ThemeVariant)) is "Dark" ? ThemeVariant.Dark : ThemeVariant.Light;
Current.RequestedThemeVariant = Configuration.Instance.GetString(propertyName: nameof(ThemeVariant)) switch
{
nameof(ThemeVariant.Dark) => ThemeVariant.Dark,
nameof(ThemeVariant.Light) => ThemeVariant.Light,
// "System"
_ => ThemeVariant.Default
};
//Reload colors for current theme
//Reload colors for current theme
LoadStyles();
var mainWindow = new MainWindow();
desktop.MainWindow = MainWindow = mainWindow;

View File

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

View File

@@ -12,8 +12,18 @@ namespace LibationAvalonia.Dialogs
public ObservableCollection<Filter> Filters { get; } = new();
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
{
get => _filterString;
@@ -25,6 +35,9 @@ namespace LibationAvalonia.Dialogs
}
}
public bool IsDefault { get; private set; } = true;
public QuickFilters.NamedFilter AsNamedFilter() => new(FilterString, Name);
}
public EditQuickFilters()
{
@@ -40,7 +53,7 @@ namespace LibationAvalonia.Dialogs
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());
foreach (var f in allFilters)
@@ -61,7 +74,7 @@ namespace LibationAvalonia.Dialogs
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();
}

View File

@@ -2,12 +2,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="350"
x:Class="LibationAvalonia.Dialogs.SetupDialog"
WindowStartupLocation="CenterScreen"
Width="500" Height="350"
Icon="/Assets/libation.ico"
Title="Welcome to Libation">
Title="Welcome to Libation"
x:DataType="dialogs:SetupDialog">
<Grid
Margin="10"
@@ -58,6 +60,7 @@
SelectedIndex="0"
SelectedItem="{Binding SelectedTheme, Mode=OneWayToSource}">
<ComboBox.Items>
<ComboBoxItem Content="System" />
<ComboBoxItem Content="Light" />
<ComboBoxItem Content="Dark" />
</ComboBox.Items>

View File

@@ -13,12 +13,12 @@ namespace LibationAvalonia.ViewModels
{
partial class MainVM
{
private string lastGoodFilter = "";
private string _filterString;
private QuickFilters.NamedFilter lastGoodFilter = new(string.Empty, null);
private QuickFilters.NamedFilter _selectedNamedFilter = new(string.Empty, null);
private bool _firstFilterIsDefault = true;
/// <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();
/// <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); }
@@ -50,19 +50,19 @@ namespace LibationAvalonia.ViewModels
QuickFilterMenuItems.Add(new Separator());
}
public void AddQuickFilterBtn() => QuickFilters.Add(FilterString);
public async Task FilterBtn() => await PerformFilter(FilterString);
public void AddQuickFilterBtn() => QuickFilters.Add(SelectedNamedFilter);
public async Task FilterBtn() => await PerformFilter(SelectedNamedFilter);
public async Task FilterHelpBtn() => await new LibationAvalonia.Dialogs.SearchSyntaxDialog().ShowDialog(MainWindow);
public void ToggleFirstFilterIsDefault() => FirstFilterIsDefault = !FirstFilterIsDefault;
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
{
await ProductsDisplay.Filter(filterString);
lastGoodFilter = filterString;
await ProductsDisplay.Filter(namedFilter.Filter);
lastGoodFilter = namedFilter;
}
catch (Exception ex)
{
@@ -99,8 +99,8 @@ namespace LibationAvalonia.ViewModels
{
var command = ReactiveCommand.Create(async () => await PerformFilter(filter));
var menuItem = new MenuItem { Header = $"{++index}: {filter}", Command = command };
var nativeMenuItem = new NativeMenuItem { 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}: {(string.IsNullOrWhiteSpace(filter.Name) ? filter.Filter : filter.Name)}", Command = command };
if (Configuration.IsMacOs && index <= 10)
{

View File

@@ -31,10 +31,10 @@ namespace LibationAvalonia.ViewModels.Settings
LoggingLevel = config.LogLevel;
GridScaleFactor = scaleFactorToLinearRange(config.GridScaleFactor);
GridFontScaleFactor = scaleFactorToLinearRange(config.GridFontScaleFactor);
ThemeVariant = initialThemeVariant
= Configuration.Instance.GetString(propertyName: nameof(ThemeVariant)) is nameof(Avalonia.Styling.ThemeVariant.Dark)
? nameof(Avalonia.Styling.ThemeVariant.Dark)
: nameof(Avalonia.Styling.ThemeVariant.Light);
ThemeVariant = initialThemeVariant = Configuration.Instance.GetString(propertyName: nameof(ThemeVariant));
if (string.IsNullOrWhiteSpace(initialThemeVariant))
ThemeVariant = initialThemeVariant = "System";
}
public void SaveSettings(Configuration config)
@@ -83,7 +83,7 @@ namespace LibationAvalonia.ViewModels.Settings
public string GridScaleFactorText { get; } = Configuration.GetDescription(nameof(Configuration.GridScaleFactor));
public string GridFontScaleFactorText { get; } = Configuration.GetDescription(nameof(Configuration.GridFontScaleFactor));
public string BetaOptInText { get; } = Configuration.GetDescription(nameof(Configuration.BetaOptIn));
public string[] Themes { get; } = { nameof(Avalonia.Styling.ThemeVariant.Light), nameof(Avalonia.Styling.ThemeVariant.Dark) };
public string[] Themes { get; } = { "System", nameof(Avalonia.Styling.ThemeVariant.Light), nameof(Avalonia.Styling.ThemeVariant.Dark) };
public string BooksDirectory { get; set; }
public bool SavePodcastsToParentFolder { get; set; }

View File

@@ -191,7 +191,7 @@
<Button IsVisible="{CompiledBinding RemoveButtonsVisible}" Command="{CompiledBinding DoneRemovingBtn}" Content="Done Removing Books"/>
</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.Filter, Mode=TwoWay}" KeyDown="filterSearchTb_KeyPress" />
<StackPanel Grid.Column="2" Height="30" Orientation="Horizontal">
<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)
{
await ViewModel.PerformFilter(ViewModel.FilterString);
await ViewModel.PerformFilter(ViewModel.SelectedNamedFilter);
// silence the 'ding'
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.IO;
using System.Linq;
using Dinah.Core.Collections.Generic;
using Newtonsoft.Json;
#nullable enable
namespace LibationFileManager
@@ -14,24 +14,21 @@ namespace LibationFileManager
public static event EventHandler? UseDefaultChanged;
internal class FilterState
public class FilterState
{
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");
// load json into memory. if file doesn't exist, nothing to do. save() will create if needed
static FilterState inMemoryState { get; }
= File.Exists(JsonFile) && JsonConvert.DeserializeObject<FilterState>(File.ReadAllText(JsonFile)) is FilterState inMemState
? inMemState
: new FilterState();
// load json into memory. if file doesn't exist, nothing to do. save() will create if needed
public static FilterState InMemoryState { get; set; } = null!;
public static bool UseDefault
{
get => inMemoryState.UseDefault;
get => InMemoryState.UseDefault;
set
{
if (UseDefault == value)
@@ -39,7 +36,7 @@ namespace LibationFileManager
lock (locker)
{
inMemoryState.UseDefault = value;
InMemoryState.UseDefault = value;
save(false);
}
@@ -47,68 +44,81 @@ namespace LibationFileManager
}
}
public static IEnumerable<string> Filters => inMemoryState.Filters.AsReadOnly();
public static void Add(string filter)
// Note that records overload equality automagically, so should be able to
// compare these the same way as comparing simple strings.
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;
filter = filter.Trim();
namedFilter.Filter = namedFilter.Filter?.Trim() ?? string.Empty;
namedFilter.Name = namedFilter.Name?.Trim() ?? null;
lock (locker)
{
// check for duplicate
if (inMemoryState.Filters.ContainsInsensative(filter))
// check for duplicates
if (InMemoryState.Filters.Select(x => x.Filter).ContainsInsensative(namedFilter.Filter))
return;
inMemoryState.Filters.Add(filter);
InMemoryState.Filters.Add(namedFilter);
save();
}
}
public static void Remove(string filter)
public static void Remove(NamedFilter filter)
{
lock (locker)
{
inMemoryState.Filters.Remove(filter);
InMemoryState.Filters.Remove(filter);
save();
}
}
public static void Edit(string oldFilter, string newFilter)
public static void Edit(NamedFilter oldFilter, NamedFilter newFilter)
{
lock (locker)
{
var index = inMemoryState.Filters.IndexOf(oldFilter);
var index = InMemoryState.Filters.IndexOf(oldFilter);
if (index < 0)
return;
inMemoryState.Filters = inMemoryState.Filters.Select(f => f == oldFilter ? newFilter : f).ToList();
InMemoryState.Filters = InMemoryState.Filters.Select(f => f == oldFilter ? newFilter : f).ToList();
save();
}
}
public static void ReplaceAll(IEnumerable<string> filters)
public static void ReplaceAll(IEnumerable<NamedFilter> filters)
{
filters = filters
.Where(f => !string.IsNullOrWhiteSpace(f))
.Distinct()
.Select(f => f.Trim());
.Where(f => !string.IsNullOrWhiteSpace(f.Filter))
.Distinct();
foreach (var filter in filters)
filter.Filter = filter.Filter.Trim();
lock (locker)
{
inMemoryState.Filters = new List<string>(filters);
InMemoryState.Filters = new List<NamedFilter>(filters);
save();
}
}
private static object locker { get; } = new object();
private static object locker { get; } = new();
// ONLY call this within lock()
private static void save(bool invokeUpdatedEvent = true)
{
// 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(); }
catch (IOException)
{

View File

@@ -15,7 +15,7 @@ namespace LibationFileManager
try
{
//Currently only works for Windows and macOS
if (!Configuration.Instance.UseCoverAsFolderIcon || Configuration.IsLinux)
if (!Configuration.Instance.UseCoverAsFolderIcon)
return;
// get path of cover art in Images dir. Download first if not exists

View File

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

View File

@@ -6,14 +6,6 @@ using LibationFileManager;
namespace LibationWinForms.Dialogs
{
public class DisableButtonColumn : DataGridViewButtonColumn
{
public DisableButtonColumn()
{
CellTemplate = new EditQuickFilters.DisableButtonCell();
}
}
public partial class EditQuickFilters : Form
{
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_Delete = nameof(Delete);
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);
internal class DisableButtonCell : AccessibleDataGridViewButtonCell
@@ -76,10 +69,11 @@ namespace LibationWinForms.Dialogs
return;
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_MoveUp].Value = BLACK_UP_POINTING_TRIANGLE;
@@ -90,7 +84,9 @@ namespace LibationWinForms.Dialogs
{
var list = dataGridView1.Rows
.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();
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"?>
<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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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">
<value>True</value>
</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>
</metadata>
<metadata name="Filter.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</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>

View File

@@ -34,9 +34,9 @@ namespace LibationWinForms
var quickFilterMenuItem = new ToolStripMenuItem
{
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);
}
}
@@ -47,14 +47,17 @@ namespace LibationWinForms
private void firstFilterIsDefaultToolStripMenuItem_Click(object sender, EventArgs e)
=> 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)
{
if (QuickFilters.UseDefault)
performFilter(QuickFilters.Filters.FirstOrDefault());
performFilter(QuickFilters.Filters.FirstOrDefault().Filter);
}
}
}