Compare commits

...

32 Commits

Author SHA1 Message Date
Robert McRackan
453904261b Bug fix. Audible's api acts weird when page count gets to ~400 2024-05-16 07:53:19 -04:00
Robert McRackan
f9340db90a update references. audible api bugfix 2024-05-15 06:55:25 -04:00
Robert McRackan
5cd329dd26 refactor 2024-05-13 15:23:37 -04:00
Robert McRackan
b2a882b79d Bug fix #904 -- navigation bug with new Accessibility feature 2024-05-13 15:17:17 -04:00
Robert McRackan
75df78a2f7 Add OSVersion to logs 2024-05-13 14:01:34 -04:00
Robert McRackan
3ad52cbecc docker to .net8 2024-05-09 10:01:38 -04:00
Robert McRackan
27b2fe741c Add accessibility 2024-05-07 10:39:30 -04:00
Robert McRackan
d19fe2250c Add accessibility text to grid stoplight buttons 2024-05-06 21:56:00 -04:00
Robert McRackan
d16d0c8de2 Merge branch 'master' of https://github.com/rmcrackan/Libation 2024-05-05 16:24:07 -04:00
Robert McRackan
c213d5d9f6 Attempt to solve networking issue by disabling ipv6 2024-05-05 16:24:00 -04:00
rmcrackan
c73a023572 Update FrequentlyAskedQuestions.md 2024-04-30 22:42:34 -04:00
rmcrackan
67389917fd Merge pull request #879 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.4
Bump SixLabors.ImageSharp from 3.1.3 to 3.1.4 in /Source/LibationUiBase
2024-04-15 17:03:13 -04:00
dependabot[bot]
b3264d5f42 Bump SixLabors.ImageSharp from 3.1.3 to 3.1.4 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.3...v3.1.4)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 20:27:24 +00:00
Robert McRackan
962d9b550f "Unable to load module" should just be a warning, not error 2024-04-15 08:03:49 -04:00
Robert McRackan
91ce7272ae Bug fix #874 : Chardonnay wasn't allowing custom directories ending in "Books" 2024-04-04 08:13:37 -04:00
rmcrackan
2f64ca6856 Merge pull request #870 from ScubyG/patch-1
Update InstallOnLinux.md
2024-03-22 07:37:00 -04:00
Davy Jones
cfe5db436c Update InstallOnLinux.md
Fixed typo
2024-03-22 01:23:52 +00:00
rmcrackan
3653fc8094 Merge pull request #863 from rmcrackan/dependabot/github_actions/softprops/action-gh-release-2
Bump softprops/action-gh-release from 1 to 2
2024-03-11 10:45:44 -04:00
dependabot[bot]
662c0ec871 Bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:20:12 +00:00
rmcrackan
44d39eabdb Merge pull request #861 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.3
Bump SixLabors.ImageSharp from 3.1.2 to 3.1.3 in /Source/LibationUiBase
2024-03-05 11:45:59 -05:00
dependabot[bot]
a0550d5c97 Bump SixLabors.ImageSharp from 3.1.2 to 3.1.3 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 16:38:00 +00:00
Robert McRackan
14eaca6d45 Update dependency. Security update 2024-03-05 11:36:36 -05:00
Robert McRackan
93ccc206ef Update dependencies 2024-03-04 14:02:42 -05:00
Robert McRackan
d3f0fd711e Remove validation check: SeriesName is null . At least 1 exception found in the wild 2024-02-29 14:44:41 -05:00
rmcrackan
3f4604e877 Update FrequentlyAskedQuestions.md
reformat
2024-02-29 10:15:47 -05:00
rmcrackan
c316709af8 Update FrequentlyAskedQuestions.md
Classic vs Chardonnay
2024-02-29 10:15:01 -05:00
Robert McRackan
221d5c7f1c paypal link 2024-02-19 10:32:26 -05:00
Robert McRackan
5a86a1a27b Typo 2024-02-13 21:42:24 -05:00
rmcrackan
dc5e55de68 Merge pull request #848 from patienttruth/master
Update Docker.md
2024-02-13 07:22:33 -05:00
patienttruth
ee37864a42 Update Docker.md
Included an explanation that you may have to manually input the InProgress variable.
2024-02-13 06:49:33 +00:00
Robert McRackan
efe347667c Better error reporting in audible api -- incl. inner exceptions 2024-01-20 21:44:29 -05:00
Robert McRackan
f27a18bdbb Better error reporting in audible api 2024-01-19 09:30:48 -05:00
43 changed files with 335 additions and 140 deletions

View File

@@ -45,7 +45,7 @@ jobs:
- name: Release
id: release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
name: Libation v${{ needs.prerelease.outputs.version }}
body: <Put a body here>

View File

@@ -1,12 +1,12 @@
# Dockerfile
FROM mcr.microsoft.com/dotnet/sdk:7.0 as build-env
FROM mcr.microsoft.com/dotnet/sdk:8.0 as build-env
COPY Source /Source
RUN dotnet publish -c Release -o /Source/bin/Publish/Linux-chardonnay /Source/LibationCli/LibationCli.csproj -p:PublishProfile=/Source/LibationCli/Properties/PublishProfiles/LinuxProfile.pubxml
COPY Docker/liberate.sh /Source/bin/Publish/Linux-chardonnay
FROM mcr.microsoft.com/dotnet/runtime:7.0
FROM mcr.microsoft.com/dotnet/runtime:8.0
ENV SLEEP_TIME "30m"

View File

@@ -1,6 +1,6 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.

View File

@@ -1,10 +1,11 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
### Disclaimer
# Disclaimer
The docker image is provided as-is. We hope it can be useful to you but it is not officially supported.
### Setup
@@ -12,7 +13,15 @@ In order to use the docker image, you'll need to provide it with a copy of the `
In Settings.json, make the following changes:
* Change `Books` to `/data`
* Change `InProgress` to `/tmp`
* Change `InProgress` to `/tmp` *
*You may have to paste the following at the end of your your Settings.json file if `InProgess` is not present:
```
"InProgress": "/tmp"
```
![image](https://github.com/patienttruth/Libation/assets/105557996/cf65a108-cadf-4284-9000-e7672c99c59b)
### Running
Once the configuration files are copied and edited, the docker image can be run with the following command.

View File

@@ -1,16 +1,31 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
### Frequently Asked Questions
**Q: Now that I've downloaded my books, how can I listen to them?**
# Frequently Asked Questions
## Q: What's the difference between 'Classic' and 'Chardonnay'?
**A:** First and most importantly: Classic and Chardonnay have the exact same features.
* **Classic** is Windows only. Its older 'grey boxes' look has a compact design which allows for more information on the screen. Notably, Classic was written using an older, more mature technology which has built-in support for screenreaders.
* **Chardonnay** is available for Windows, Mac, and Linux. Its modern design has a more open look and feel.
## Q: Now that I've downloaded my books, how can I listen to them?
**A:** You can use any app which plays m4b files (or mp3 files if you used that setting). Here are just a few ideas. Disclaimer: I have no affiliation with any of these companies:
* iOS: [BookPlayer](https://apps.apple.com/us/app/bookplayer/id1138219998)
* iOS: [Bound](https://apps.apple.com/us/app/bound-audiobook-player/id1041727137)
* Android: [Smart AudioBook Player](https://play.google.com/store/apps/details?id=ak.alizandro.smartaudiobookplayer&hl=en_US&gl=US)
* Desktop: [VLC](https://www.videolan.org/)
* Desktop: [VLC](https://www.videolan.org/)
## Q: How do I use Libation with a South Africa account?
**A:** Like many countries, amazon gives South Africa it's own amazon site. [Unlike many other regions](https://www.audible.com/ep/country-selector) there is not South Africa specific audible site. Use `US` for your region -- ie: audible.com.
(Not exactly a *frequently* asked question but it's come up more than once)

View File

@@ -1,6 +1,6 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.

View File

@@ -1,15 +1,16 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
### Install and Run Libation on Ubuntu
# Install and Run Libation on Ubuntu
New Libation releases are automatically packed into .deb and .rpm package and are available from the Libation repository's releases page.
Run this command in your terminal to dowbnload and install Libation, replacing the url with the latest Libation package url:
Run this command in your terminal to download and install Libation, replacing the url with the latest Libation package url:
- Debian
```Console

View File

@@ -1,9 +1,10 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
# Run Libation on MacOS
This walkthrough should get you up and running with Libation on your Mac.

View File

@@ -1,3 +1,10 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
# Naming Templates
File and Folder names can be customized using Libation's built-in tag template naming engine. To edit how folder and file names are created, go to Settings \> Download/Decrypt and edit the naming templates. If you're splitting your audiobook into multiple files by chapter, you can also use a custom template to set each chapter's title metadata tag by editing the template in Settings \> Audio File Options.

View File

@@ -1,6 +1,6 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.

View File

@@ -2,9 +2,11 @@
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/mcrackan?locale.x=en_us)
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
# Table of Contents
- [Audible audiobook manager](#audible-audiobook-manager)

View File

@@ -2,10 +2,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>11.3.2.1</Version>
<Version>11.3.13.1</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Octokit" Version="9.1.0" />
<PackageReference Include="Octokit" Version="11.0.1" />
<PackageReference Include="Serilog.Sinks.ZipFile" Version="3.1.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -233,6 +233,7 @@ namespace AppScaffolding
Version = BuildVersion.ToString(),
ReleaseIdentifier,
Configuration.OS,
Environment.OSVersion,
InteropFactory.InteropFunctionsType,
Mode = mode,
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
@@ -242,6 +243,7 @@ namespace AppScaffolding
LogLevel_Error_Enabled = Log.Logger.IsErrorEnabled(),
LogLevel_Fatal_Enabled = Log.Logger.IsFatalEnabled(),
config.AutoScan,
config.BetaOptIn,
config.UseCoverAsFolderIcon,
config.LibationFiles,
@@ -254,6 +256,8 @@ namespace AppScaffolding
AudibleFileStorage.DecryptInProgressDirectory,
DecryptInProgressFiles = FileManager.FileUtility.SaferEnumerateFiles(AudibleFileStorage.DecryptInProgressDirectory).Count(),
disableIPv6 = AppContext.TryGetSwitch("System.Net.DisableIPv6", out bool disableIPv6Value),
});
if (InteropFactory.InteropFunctionsType is null)

View File

@@ -5,8 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="NPOI" Version="2.6.2" />
<PackageReference Include="CsvHelper" Version="32.0.3" />
<PackageReference Include="NPOI" Version="2.7.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -90,8 +90,10 @@ namespace AudibleUtilities
var distinct = items.GetSeriesDistinct();
if (distinct.Any(s => s.SeriesId is null))
exceptions.Add(new ArgumentException($"Collection contains {nameof(Item.Series)} with null {nameof(Series.SeriesId)}", nameof(items)));
if (distinct.Any(s => s.SeriesName is null))
exceptions.Add(new ArgumentException($"Collection contains {nameof(Item.Series)} with null {nameof(Series.SeriesName)}", nameof(items)));
//// unfortunately, a user has a series with no name
//if (distinct.Any(s => s.SeriesName is null))
// exceptions.Add(new ArgumentException($"Collection contains {nameof(Item.Series)} with null {nameof(Series.SeriesName)}", nameof(items)));
return exceptions;
}

View File

@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AudibleApi" Version="9.0.0.1" />
<PackageReference Include="AudibleApi" Version="9.1.2.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,12 +12,12 @@
<ItemGroup>
<PackageReference Include="Dinah.Core" Version="8.0.0.1" />
<PackageReference Include="Dinah.EntityFrameworkCore" Version="8.0.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -6,7 +6,7 @@
<ItemGroup>
<PackageReference Include="Dinah.Core" Version="8.0.0.1" />
<PackageReference Include="Polly" Version="8.2.1" />
<PackageReference Include="Polly" Version="8.4.0" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -21,9 +21,13 @@
<ApplicationIcon>hangover.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.DisableIPv6" Value="true" />
</ItemGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\bin\Avalonia\Debug</OutputPath>

View File

@@ -15,6 +15,10 @@
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.DisableIPv6" Value="true" />
</ItemGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>

View File

@@ -107,7 +107,7 @@ namespace LibationAvalonia.Controls
if (known is Configuration.KnownDirectories.None)
{
directoryState.CustomDir = noSubDir;
directoryState.CustomDir = directory;
directoryState.CustomChecked = true;
}
else

View File

@@ -14,6 +14,10 @@
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.DisableIPv6" Value="true" />
</ItemGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>

View File

@@ -11,6 +11,10 @@
<IsPublishable>True</IsPublishable>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.DisableIPv6" Value="true" />
</ItemGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>

View File

@@ -95,9 +95,9 @@ namespace LibationFileManager
var assembly = CurrentDomain_AssemblyResolve_internal(asmName, here: here);
lowEffortCache[key] = assembly;
//Let the runtime handle any dll not found exceptions.
// Let the runtime handle any dll not found exceptions
if (assembly is null)
Serilog.Log.Logger.Error($"Unable to load module {args.Name}");
Serilog.Log.Logger.Warning($"Unable to load module {args.Name}");
return assembly;
}

View File

@@ -133,7 +133,7 @@ namespace LibationUiBase.GridView
private string GetTooltip()
{
if (IsSeries)
return Expanded ? "Click to Collpase" : "Click to Expand";
return Expanded ? "Click to Collapse" : "Click to Expand";
if (IsUnavailable)
return "This book cannot be downloaded\nbecause it wasn't found during\nthe most recent library scan";

View File

@@ -9,7 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,46 @@
using System.Windows.Forms;
namespace LibationWinForms
{
public class AccessibleDataGridViewButtonCell : DataGridViewButtonCell
{
private string accessibilityDescription;
protected string AccessibilityName { get; }
/// <summary>
/// Get or set description for accessibility. eg: screen readers. Also sets the ToolTipText
/// </summary>
protected string AccessibilityDescription
{
get => accessibilityDescription;
set
{
accessibilityDescription = value;
ToolTipText = value;
}
}
protected override AccessibleObject CreateAccessibilityInstance() => new ButtonCellAccessibilityObject(this, name: AccessibilityName, description: AccessibilityDescription);
public AccessibleDataGridViewButtonCell(string accessibilityName) : base()
{
AccessibilityName = accessibilityName;
}
protected class ButtonCellAccessibilityObject : DataGridViewButtonCellAccessibleObject
{
private string _name;
public override string Name => _name;
private string _description;
public override string Description => _description;
public ButtonCellAccessibilityObject(DataGridViewCell owner, string name, string description) : base(owner)
{
_name = name;
_description = description;
}
}
}
}

View File

@@ -0,0 +1,46 @@
using System.Windows.Forms;
namespace LibationWinForms
{
internal class AccessibleDataGridViewTextBoxCell : DataGridViewTextBoxCell
{
private string accessibilityDescription;
protected string AccessibilityName { get; }
/// <summary>
/// Get or set description for accessibility. eg: screen readers. Also sets the ToolTipText
/// </summary>
protected string AccessibilityDescription
{
get => accessibilityDescription;
set
{
accessibilityDescription = value;
ToolTipText = value;
}
}
protected override AccessibleObject CreateAccessibilityInstance() => new TextBoxCellAccessibilityObject(this, name: AccessibilityName, description: AccessibilityDescription);
public AccessibleDataGridViewTextBoxCell(string accessibilityName) : base()
{
AccessibilityName = accessibilityName;
}
protected class TextBoxCellAccessibilityObject : DataGridViewTextBoxCellAccessibleObject
{
private string _name;
public override string Name => _name;
private string _description;
public override string Description => _description;
public TextBoxCellAccessibilityObject(DataGridViewCell owner, string name, string description) : base(owner)
{
_name = name;
_description = description;
}
}
}
}

View File

@@ -51,13 +51,13 @@ namespace LibationWinForms.Dialogs
private void AddAccountToGrid(Account account)
{
int row = dataGridView1.Rows.Add(
"X",
"Export",
account.LibraryScan,
account.AccountId,
account.Locale.Name,
account.AccountName);
var row = dataGridView1.Rows.Add(
"X",
"Export",
account.LibraryScan,
account.AccountId,
account.Locale.Name,
account.AccountName);
dataGridView1[COL_Export, row].ToolTipText = "Export account authorization to audible-cli";
}

View File

@@ -24,23 +24,39 @@ namespace LibationWinForms.Dialogs
private const string COL_MoveUp = nameof(MoveUp);
private const string COL_MoveDown = nameof(MoveDown);
internal class DisableButtonCell : DataGridViewButtonCell
{
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
internal class DisableButtonCell : AccessibleDataGridViewButtonCell
{
private int LastRowIndex => DataGridView.Rows[^1].IsNewRow ? DataGridView.Rows[^1].Index - 1 : DataGridView.Rows[^1].Index;
public DisableButtonCell() : base("Edit Filter button") { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if ((OwningColumn.Name == COL_MoveUp && rowIndex == 0)
|| (OwningColumn.Name == COL_MoveDown && rowIndex == LastRowIndex)
|| OwningRow.IsNewRow)
{
var isMoveUp = OwningColumn.Name == COL_MoveUp;
var isMoveDown = OwningColumn.Name == COL_MoveDown;
var isDelete = OwningColumn.Name == COL_Delete;
var isNewRow = OwningRow.IsNewRow;
if (isNewRow
|| (isMoveUp && rowIndex == 0)
|| (isMoveDown && rowIndex == LastRowIndex))
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts ^ (DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.SelectionBackground));
ButtonRenderer.DrawButton(graphics, cellBounds, value as string, cellStyle.Font, false, System.Windows.Forms.VisualStyles.PushButtonState.Disabled);
}
}
else
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
int LastRowIndex => DataGridView.Rows[^1].IsNewRow ? DataGridView.Rows[^1].Index - 1 : DataGridView.Rows[^1].Index;
if (isMoveUp)
AccessibilityDescription = "Move up";
else if (isMoveDown)
AccessibilityDescription = "Move down";
else if (isDelete)
AccessibilityDescription = "Delete";
}
}
}
public EditQuickFilters()

View File

@@ -1,11 +1,12 @@
using System.Drawing;
using System.Windows.Forms;
namespace LibationWinForms.GridView
{
public class DataGridViewImageButtonCell : DataGridViewButtonCell
{
protected void DrawButtonImage(Graphics graphics, Image image, Rectangle cellBounds)
public class DataGridViewImageButtonCell : AccessibleDataGridViewButtonCell
{
public DataGridViewImageButtonCell(string accessibilityName) : base(accessibilityName) { }
protected void DrawButtonImage(Graphics graphics, Image image, Rectangle cellBounds)
{
var scaleFactor = OwningColumn is IDataGridScaleColumn scCol ? scCol.ScaleFactor : 1f;

View File

@@ -20,20 +20,33 @@ namespace LibationWinForms.GridView
}
internal class EditTagsDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
private static Image ButtonImage { get; } = Properties.Resources.edit_25x25;
{
public EditTagsDataGridViewImageButtonCell() : base("Edit Tags button") { }
private static Image ButtonImage { get; } = Properties.Resources.edit_25x25;
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (rowIndex >= 0 && DataGridView.GetBoundItem<IGridEntry>(rowIndex) is ISeriesEntry)
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
else if (value is string tagStr && tagStr.Length == 0)
// series
if (rowIndex >= 0 && DataGridView.GetBoundItem<IGridEntry>(rowIndex) is ISeriesEntry)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
}
// tag: empty
else if (value is string tagStr && tagStr.Length == 0)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
DrawButtonImage(graphics, ButtonImage, cellBounds);
}
AccessibilityDescription = "Click to edit tags";
}
// tag: not empty
else
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
AccessibilityDescription = (string)value;
}
}
}
}

View File

@@ -1,7 +1,7 @@
using LibationUiBase.GridView;
using System;
using System;
using System.Drawing;
using System.Windows.Forms;
using LibationUiBase.GridView;
namespace LibationWinForms.GridView
{
@@ -21,15 +21,19 @@ namespace LibationWinForms.GridView
}
}
internal class LastDownloadedGridViewCell : DataGridViewTextBoxCell
{
internal class LastDownloadedGridViewCell : AccessibleDataGridViewTextBoxCell
{
private LastDownloadStatus LastDownload => (LastDownloadStatus)Value;
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
public LastDownloadedGridViewCell() : base("Last Downloaded") { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (value is LastDownloadStatus lastDl)
ToolTipText = lastDl.ToolTipText;
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
if (value is LastDownloadStatus lastDl)
AccessibilityDescription = lastDl.ToolTipText;
}
protected override void OnDoubleClick(DataGridViewCellEventArgs e)
{

View File

@@ -16,7 +16,9 @@ namespace LibationWinForms.GridView
internal class LiberateDataGridViewImageButtonCell : DataGridViewImageButtonCell
{
private static readonly Brush DISABLED_GRAY = new SolidBrush(Color.FromArgb(0x60, Color.LightGray));
public LiberateDataGridViewImageButtonCell() : base("Liberate button") { }
private static readonly Brush DISABLED_GRAY = new SolidBrush(Color.FromArgb(0x60, Color.LightGray));
private static readonly Color HiddenForeColor = Color.LightGray;
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
@@ -31,7 +33,7 @@ namespace LibationWinForms.GridView
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, paintParts);
DrawButtonImage(graphics, (Image)status.ButtonImage, cellBounds);
ToolTipText = status.ToolTip;
AccessibilityDescription = status.ToolTip;
if (status.IsUnavailable || status.Opacity < 1)
graphics.FillRectangle(DISABLED_GRAY, cellBounds);

View File

@@ -1,9 +1,9 @@
using DataLayer;
using System;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using DataLayer;
namespace LibationWinForms.GridView
{
@@ -24,14 +24,17 @@ namespace LibationWinForms.GridView
}
}
internal class MyRatingGridViewCell : DataGridViewTextBoxCell
{
internal class MyRatingGridViewCell : AccessibleDataGridViewTextBoxCell
{
private static Rating DefaultRating => new Rating(0, 0, 0);
public override object DefaultNewRowValue => DefaultRating;
public override Type EditType => typeof(MyRatingCellEditor);
public override Type ValueType => typeof(Rating);
public MyRatingGridViewCell() { ToolTipText = ReadOnly ? "" : "Click to change ratings"; }
public MyRatingGridViewCell() : base("My Rating")
{
AccessibilityDescription = ReadOnly ? "" : "Click to change ratings";
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
@@ -46,14 +49,14 @@ namespace LibationWinForms.GridView
{
if (value is Rating rating)
{
ToolTipText = ReadOnly ? "" : "Click to change ratings";
var starString = rating.ToStarString();
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, starString, starString, errorText, cellStyle, advancedBorderStyle, paintParts);
}
else
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, string.Empty, string.Empty, errorText, cellStyle, advancedBorderStyle, paintParts);
}
AccessibilityDescription = ReadOnly ? "" : "Click to change ratings";
}
else
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, string.Empty, string.Empty, errorText, cellStyle, advancedBorderStyle, paintParts);
}
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
=> value is Rating rating ? rating.ToStarString() : value?.ToString();

View File

@@ -17,6 +17,10 @@
<!-- Version is now in AppScaffolding.csproj -->
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.DisableIPv6" Value="true" />
</ItemGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
</PropertyGroup>

View File

@@ -13,37 +13,40 @@ namespace LibationWinForms.SeriesView
CellTemplate.Style.WrapMode = DataGridViewTriState.True;
}
}
internal class DownloadButtonColumnCell : DataGridViewButtonCell
{
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (value is SeriesButton sentry)
{
string cellValue = sentry.DisplayText;
if (!sentry.Enabled)
{
//Draw disabled button
Rectangle buttonArea = cellBounds;
Rectangle buttonAdjustment = BorderWidths(advancedBorderStyle);
buttonArea.X += buttonAdjustment.X;
buttonArea.Y += buttonAdjustment.Y;
buttonArea.Height -= buttonAdjustment.Height;
buttonArea.Width -= buttonAdjustment.Width;
ButtonRenderer.DrawButton(graphics, buttonArea, cellValue, cellStyle.Font, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak, focused: false, PushButtonState.Disabled);
internal class DownloadButtonColumnCell : AccessibleDataGridViewButtonCell
{
public DownloadButtonColumnCell() : base("Download Series button") { }
}
else if (sentry.HasButtonAction)
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, cellValue, cellValue, errorText, cellStyle, advancedBorderStyle, paintParts);
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
TextRenderer.DrawText(graphics, cellValue, cellStyle.Font, cellBounds, cellStyle.ForeColor);
}
}
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
}
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (value is not SeriesButton seriesEntry)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
return;
}
string cellValue = seriesEntry.DisplayText;
AccessibilityDescription = cellValue;
if (!seriesEntry.Enabled)
{
//Draw disabled button
Rectangle buttonArea = cellBounds;
Rectangle buttonAdjustment = BorderWidths(advancedBorderStyle);
buttonArea.X += buttonAdjustment.X;
buttonArea.Y += buttonAdjustment.Y;
buttonArea.Height -= buttonAdjustment.Height;
buttonArea.Width -= buttonAdjustment.Width;
ButtonRenderer.DrawButton(graphics, buttonArea, cellValue, cellStyle.Font, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordBreak, focused: false, PushButtonState.Disabled);
}
else if (seriesEntry.HasButtonAction)
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, cellValue, cellValue, errorText, cellStyle, advancedBorderStyle, paintParts);
else
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, null, null, null, cellStyle, advancedBorderStyle, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
TextRenderer.DrawText(graphics, cellValue, cellStyle.Font, cellBounds, cellStyle.ForeColor);
}
}
}
}

View File

@@ -26,7 +26,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2478.35" />
</ItemGroup>
<ItemGroup>

View File

@@ -7,10 +7,10 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -7,10 +7,10 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -8,10 +8,10 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -8,10 +8,10 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -8,10 +8,10 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>