mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-05-09 08:04:13 -04:00
@@ -118,6 +118,7 @@ mkdir Libation/.background
|
||||
mv background.png Libation/.background/
|
||||
ln -s /Applications "./Libation/ "
|
||||
mkdir ./bundle
|
||||
sync
|
||||
hdiutil create -srcFolder ./Libation -o "./bundle/$DMG_FILE"
|
||||
# Create a .DS_Store by:
|
||||
# - mounting an existing image in shadow mode (hdiutil attach Libation.dmg -shadow junk.dmg)
|
||||
|
||||
@@ -288,64 +288,64 @@ public static class LibationScaffolding
|
||||
}
|
||||
|
||||
private static void logStartupState(Configuration config)
|
||||
{
|
||||
{
|
||||
#if DEBUG
|
||||
var mode = "Debug";
|
||||
var mode = "Debug";
|
||||
#else
|
||||
var mode = "Release";
|
||||
#endif
|
||||
if (Debugger.IsAttached)
|
||||
mode += " (Debugger attached)";
|
||||
if (Debugger.IsAttached)
|
||||
mode += " (Debugger attached)";
|
||||
|
||||
// begin logging session with a form feed
|
||||
Log.Logger.Information("\r\n\f");
|
||||
// begin logging session with a form feed
|
||||
Log.Logger.Information("\r\n\f");
|
||||
|
||||
static int fileCount(FileManager.LongPath? longPath)
|
||||
{
|
||||
if (longPath is null)
|
||||
return -1;
|
||||
try { return FileManager.FileUtility.SaferEnumerateFiles(longPath).Count(); }
|
||||
catch { return -1; }
|
||||
}
|
||||
static int fileCount(FileManager.LongPath? longPath)
|
||||
{
|
||||
if (longPath is null)
|
||||
return -1;
|
||||
try { return FileManager.FileUtility.SaferEnumerateFiles(longPath).Count(); }
|
||||
catch { return -1; }
|
||||
}
|
||||
|
||||
Log.Logger.Information("Begin. {@DebugInfo}", new
|
||||
{
|
||||
AppName = EntryAssembly?.GetName().Name,
|
||||
Version = BuildVersion?.ToString(),
|
||||
ReleaseIdentifier,
|
||||
Configuration.OS,
|
||||
Environment.OSVersion,
|
||||
InteropFactory.InteropFunctionsType,
|
||||
Mode = mode,
|
||||
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
|
||||
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
|
||||
LogLevel_Information_Enabled = Log.Logger.IsInformationEnabled(),
|
||||
LogLevel_Warning_Enabled = Log.Logger.IsWarningEnabled(),
|
||||
LogLevel_Error_Enabled = Log.Logger.IsErrorEnabled(),
|
||||
LogLevel_Fatal_Enabled = Log.Logger.IsFatalEnabled(),
|
||||
Log.Logger.Information("Begin. {@DebugInfo}", new
|
||||
{
|
||||
AppName = EntryAssembly?.GetName().Name,
|
||||
Version = BuildVersion?.ToString(),
|
||||
ReleaseIdentifier,
|
||||
Configuration.OS,
|
||||
Environment.OSVersion,
|
||||
InteropFactory.InteropFunctionsType,
|
||||
Mode = mode,
|
||||
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
|
||||
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
|
||||
LogLevel_Information_Enabled = Log.Logger.IsInformationEnabled(),
|
||||
LogLevel_Warning_Enabled = Log.Logger.IsWarningEnabled(),
|
||||
LogLevel_Error_Enabled = Log.Logger.IsErrorEnabled(),
|
||||
LogLevel_Fatal_Enabled = Log.Logger.IsFatalEnabled(),
|
||||
|
||||
config.AutoScan,
|
||||
config.BetaOptIn,
|
||||
config.UseCoverAsFolderIcon,
|
||||
config.LibationFiles,
|
||||
AudibleFileStorage.BooksDirectory,
|
||||
config.AutoScan,
|
||||
config.BetaOptIn,
|
||||
config.UseCoverAsFolderIcon,
|
||||
config.LibationFiles,
|
||||
AudibleFileStorage.BooksDirectory,
|
||||
|
||||
config.InProgress,
|
||||
config.InProgress,
|
||||
|
||||
AudibleFileStorage.DownloadsInProgressDirectory,
|
||||
DownloadsInProgressFiles = fileCount(AudibleFileStorage.DownloadsInProgressDirectory),
|
||||
AudibleFileStorage.DownloadsInProgressDirectory,
|
||||
DownloadsInProgressFiles = fileCount(AudibleFileStorage.DownloadsInProgressDirectory),
|
||||
|
||||
AudibleFileStorage.DecryptInProgressDirectory,
|
||||
DecryptInProgressFiles = fileCount(AudibleFileStorage.DecryptInProgressDirectory),
|
||||
AudibleFileStorage.DecryptInProgressDirectory,
|
||||
DecryptInProgressFiles = fileCount(AudibleFileStorage.DecryptInProgressDirectory),
|
||||
|
||||
disableIPv6 = AppContext.TryGetSwitch("System.Net.DisableIPv6", out bool disableIPv6Value),
|
||||
});
|
||||
disableIPv6 = AppContext.TryGetSwitch("System.Net.DisableIPv6", out bool disableIPv6Value),
|
||||
});
|
||||
|
||||
if (InteropFactory.InteropFunctionsType is null)
|
||||
Serilog.Log.Logger.Warning("WARNING: OSInteropProxy.InteropFunctionsType is null");
|
||||
}
|
||||
if (InteropFactory.InteropFunctionsType is null)
|
||||
Serilog.Log.Logger.Warning("WARNING: OSInteropProxy.InteropFunctionsType is null");
|
||||
}
|
||||
|
||||
private static void wireUpSystemEvents(Configuration configuration)
|
||||
private static void wireUpSystemEvents(Configuration configuration)
|
||||
{
|
||||
LibraryCommands.LibrarySizeChanged += (object? _, List<DataLayer.LibraryBook> libraryBooks)
|
||||
=> SearchEngineCommands.FullReIndex(libraryBooks);
|
||||
|
||||
@@ -29,7 +29,7 @@ public partial record UpgradeProperties
|
||||
ZipUrl = zipUrl;
|
||||
LatestRelease = latestRelease;
|
||||
|
||||
var text = NoAppBlockRegex().Replace(notes, "");
|
||||
var text = NoAppBlockRegex().Replace(notes, "");
|
||||
text = LinkStripRegex().Replace(text, "$1");
|
||||
Notes = text.Trim();
|
||||
}
|
||||
@@ -37,6 +37,6 @@ public partial record UpgradeProperties
|
||||
[GeneratedRegex(@"\[(.*)\]\(.*\)")]
|
||||
private static partial Regex LinkStripRegex();
|
||||
|
||||
[GeneratedRegex(@"<!-- BEGIN NO-APP -->.*?<!-- END NO-APP -->", RegexOptions.Singleline)]
|
||||
private static partial Regex NoAppBlockRegex();
|
||||
[GeneratedRegex(@"<!-- BEGIN NO-APP -->.*?<!-- END NO-APP -->", RegexOptions.Singleline)]
|
||||
private static partial Regex NoAppBlockRegex();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AudibleApi" Version="10.1.5.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.33.5" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.34.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -33,7 +33,7 @@ public static class Mkb79AuthImporter
|
||||
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
|
||||
|
||||
if (persister.AccountsSettings.Accounts.Any(a =>
|
||||
a.AccountId == account.AccountId && a.IdentityTokens?.Locale.Name == account.Locale?.Name))
|
||||
a.AccountId == account.AccountId && a.IdentityTokens?.Locale.Name == account.Locale?.Name))
|
||||
{
|
||||
return new Mkb79ImportResult(Mkb79ImportOutcome.DuplicateAccount, account);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
namespace DataLayer.Postgres.Migrations;
|
||||
|
||||
namespace DataLayer.Postgres.Migrations
|
||||
/// <inheritdoc />
|
||||
public partial class ReAddCategoryName2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ReAddCategoryName2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Categories",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Categories",
|
||||
type: "text",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Categories");
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Categories");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
namespace DataLayer.Migrations;
|
||||
|
||||
namespace DataLayer.Migrations
|
||||
/// <inheritdoc />
|
||||
public partial class ReAddCategoryName2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ReAddCategoryName2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Categories",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Name",
|
||||
table: "Categories",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Categories");
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Name",
|
||||
table: "Categories");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core" Version="10.0.0.1" />
|
||||
<PackageReference Include="Dinah.EntityFrameworkCore" Version="10.0.0.1" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.2">
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core" Version="10.0.0.1" />
|
||||
<PackageReference Include="Polly" Version="8.6.5" />
|
||||
<PackageReference Include="Polly" Version="8.6.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
@@ -216,7 +216,7 @@ public static partial class CommonFormatters
|
||||
public static string Unescape(ReadOnlySpan<char> valueSpan, ReadOnlySpan<char> quoteChars, bool unquoteBackslash = true, bool unescapeDoubleQuotesInsideQuotes = true)
|
||||
{
|
||||
if (valueSpan.IsEmpty) return "";
|
||||
|
||||
|
||||
Span<char> search = stackalloc char[quoteChars.Length + 1];
|
||||
search[0] = '\\';
|
||||
quoteChars.CopyTo(search[1..]);
|
||||
@@ -245,8 +245,8 @@ public static partial class CommonFormatters
|
||||
{
|
||||
i++; // skip
|
||||
if (!unescapeDoubleQuotesInsideQuotes ||
|
||||
i >= valueSpan.Length ||
|
||||
valueSpan[i] != c)
|
||||
i >= valueSpan.Length ||
|
||||
valueSpan[i] != c)
|
||||
// end block if no 2nd quote follows or doubled quotes don't have special meaning
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -307,7 +307,8 @@ public partial class ConditionalTagCollection<TClass>(bool caseSensitive = true)
|
||||
{
|
||||
var cmp = GetStringComparer(culture);
|
||||
return e1.OrderBy(e => e, cmp).SequenceEqual(e2.OrderBy(e => e, cmp), cmp);
|
||||
},
|
||||
}
|
||||
,
|
||||
_ => throw new ArgumentOutOfRangeException() // this should never happen because the regex only allows these values
|
||||
};
|
||||
return (v1, v2, culture) => v1 is not null && v2 is not null && checklist(ToEnumerable(v1), ToEnumerable(v2), culture);
|
||||
@@ -386,7 +387,7 @@ public partial class ConditionalTagCollection<TClass>(bool caseSensitive = true)
|
||||
{
|
||||
return StringComparer.Create(culture ?? CultureInfo.CurrentCulture, ignoreCase: true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Build a regular expression check. Uses culture-invariant matching for thread-safety and consistency.
|
||||
/// Applies a timeout to prevent regex patterns from causing excessive backtracking and blocking.
|
||||
|
||||
@@ -63,7 +63,7 @@ public class NamingTemplate
|
||||
|
||||
return (_templateToString.DynamicInvoke(delegateArgs) as TemplatePart)!.FirstPart;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Parse a template string to a <see cref="NamingTemplate"/></summary>
|
||||
/// <param name="template">The template string to parse</param>
|
||||
/// <param name="tagCollections">A collection of <see cref="TagCollection"/> with
|
||||
|
||||
@@ -20,10 +20,10 @@ public class PropertyTagCollection<TClass> : TagCollection
|
||||
var parameters = formatter.Method.GetParameters();
|
||||
|
||||
if (formatter.Method.ReturnType != typeof(string)
|
||||
|| parameters.Length != 4
|
||||
|| parameters[0].ParameterType != typeof(ITemplateTag)
|
||||
|| parameters[2].ParameterType != typeof(string)
|
||||
|| !typeof(CultureInfo).IsAssignableFrom(parameters[3].ParameterType))
|
||||
|| parameters.Length != 4
|
||||
|| parameters[0].ParameterType != typeof(ITemplateTag)
|
||||
|| parameters[2].ParameterType != typeof(string)
|
||||
|| !typeof(CultureInfo).IsAssignableFrom(parameters[3].ParameterType))
|
||||
throw new ArgumentException(
|
||||
$"{nameof(defaultFormatters)} must have a signature of [{nameof(String)} PropertyFormatter<T>({nameof(ITemplateTag)}, T, {nameof(String)}, {nameof(CultureInfo)})]");
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public static class RegExpExtensions
|
||||
{
|
||||
// part before match
|
||||
if (m.Index > pos)
|
||||
sb.Append(gapEvaluator(input[pos .. m.Index]));
|
||||
sb.Append(gapEvaluator(input[pos..m.Index]));
|
||||
|
||||
// the match itself
|
||||
sb.Append(matchEvaluator(m));
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:controls="clr-namespace:HangoverAvalonia.Controls"
|
||||
xmlns:vms="clr-namespace:HangoverAvalonia.ViewModels"
|
||||
x:Class="HangoverAvalonia.Controls.CheckedListBox">
|
||||
|
||||
<ScrollViewer
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding $parent[1].Items}">
|
||||
<ItemsControl ItemsSource="{Binding $parent[controls:CheckedListBox].Items}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DataTemplate x:DataType="vms:CheckBoxViewModel">
|
||||
<CheckBox HorizontalAlignment="Stretch" Margin="10,0,0,0" Content="{Binding Item}" IsChecked="{Binding IsChecked, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -70,12 +70,11 @@
|
||||
<TrimmableAssembly Include="Avalonia.Themes.Default" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.11" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="12.0.2" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.11" />
|
||||
<PackageReference Include="ReactiveUI.Avalonia" Version="11.3.8" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.11" />
|
||||
<PackageReference Include="Tmds.DBus.Protocol" Version="0.21.3" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.3.14" />
|
||||
<PackageReference Include="ReactiveUI.Avalonia" Version="12.0.1" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="12.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HangoverBase\HangoverBase.csproj" />
|
||||
|
||||
@@ -18,5 +18,5 @@ internal class Program
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI();
|
||||
.UseReactiveUI(_ => { });
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:HangoverAvalonia.Controls"
|
||||
xmlns:vms="clr-namespace:HangoverAvalonia.ViewModels"
|
||||
x:DataType="vms:MainVM"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="500"
|
||||
Width="800" Height="500"
|
||||
x:Class="HangoverAvalonia.Views.MainWindow"
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
</Style>
|
||||
|
||||
<Style Selector="dialogs|DialogWindow">
|
||||
<Setter Property="SystemDecorations" Value="Full"/>
|
||||
<Setter Property="WindowDecorations" Value="Full"/>
|
||||
<Setter Property="Icon" Value="/Assets/libation.ico"/>
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
|
||||
@@ -47,9 +47,6 @@ public class App : Application
|
||||
MessageBoxBase.ShowAsyncImpl = (owner, message, caption, buttons, icon, defaultButton, saveAndRestorePosition) =>
|
||||
MessageBox.Show(owner as Window, message, caption, buttons, icon, defaultButton, saveAndRestorePosition);
|
||||
|
||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
||||
DisableAvaloniaDataAnnotationValidation();
|
||||
if (LibraryTask is null)
|
||||
{
|
||||
RunSetupIfNeededAsync(desktop, Configuration.Instance);
|
||||
@@ -114,19 +111,6 @@ public class App : Application
|
||||
LibationScaffolding.RunPostMigrationScaffolding(Variety.Chardonnay, config);
|
||||
}
|
||||
|
||||
private void DisableAvaloniaDataAnnotationValidation()
|
||||
{
|
||||
// Get an array of plugins to remove
|
||||
DataAnnotationsValidationPlugin[] dataValidationPluginsToRemove =
|
||||
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
|
||||
|
||||
// remove each entry found
|
||||
foreach (DataAnnotationsValidationPlugin? plugin in dataValidationPluginsToRemove)
|
||||
{
|
||||
BindingPlugins.DataValidators.Remove(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowMainWindow(IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
Configuration.Instance.PropertyChanged += ThemeVariant_PropertyChanged;
|
||||
|
||||
@@ -24,7 +24,7 @@ internal static class AvaloniaUtils
|
||||
: Task.FromResult(DialogResult.None);
|
||||
|
||||
public static Window GetParentWindow(this Control control)
|
||||
=> control.GetVisualRoot() as Window ?? App.MainWindow
|
||||
=> TopLevel.GetTopLevel(control) as Window ?? App.MainWindow
|
||||
?? throw new InvalidOperationException("Cannot find parent window.");
|
||||
|
||||
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
x:Class="LibationAvalonia.Controls.CheckedListBox">
|
||||
|
||||
<ScrollViewer
|
||||
HorizontalScrollBarVisibility="Disabled"
|
||||
VerticalScrollBarVisibility="Auto">
|
||||
<ItemsControl ItemsSource="{Binding $parent[1].Items}">
|
||||
<ItemsControl ItemsSource="{Binding $parent[controls:CheckedListBox].Items}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DataTemplate x:DataType="controls:CheckBoxViewModel">
|
||||
<CheckBox HorizontalAlignment="Stretch" Margin="10,0,0,0" Content="{Binding Item}" IsChecked="{Binding IsChecked, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace LibationAvalonia.Controls;
|
||||
|
||||
public class DataGridMyRatingColumn : DataGridBoundColumn
|
||||
{
|
||||
[AssignBinding] public IBinding? BackgroundBinding { get; set; }
|
||||
[AssignBinding] public IBinding? OpacityBinding { get; set; }
|
||||
[AssignBinding] public BindingBase? BackgroundBinding { get; set; }
|
||||
[AssignBinding] public BindingBase? OpacityBinding { get; set; }
|
||||
private static Rating DefaultRating => new Rating(0, 0, 0);
|
||||
public DataGridMyRatingColumn()
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
x:DataType="controls:DirectoryOrCustomSelectControl"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="LibationAvalonia.Controls.DirectoryOrCustomSelectControl">
|
||||
|
||||
@@ -39,7 +40,7 @@
|
||||
Margin="0,0,0,8"
|
||||
Name="tboxKnownDirPath"
|
||||
IsEnabled="{Binding #rbKnown.IsChecked}"
|
||||
Text="{Binding #cmbKnownDirs.SelectedItem.Directory}" />
|
||||
Text="{Binding #cmbKnownDirs.((controls:KnownDirectoryItem)SelectedItem).Directory}"/>
|
||||
|
||||
|
||||
<RadioButton
|
||||
@@ -53,7 +54,7 @@
|
||||
Name="tboxCustomDirPath"
|
||||
Margin="0,0,10,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding $parent[1].Directory, Mode=OneWayToSource}"
|
||||
Text="{Binding $parent[controls:DirectoryOrCustomSelectControl].Directory, Mode=OneWayToSource}"
|
||||
IsEnabled="{Binding #rbCustom.IsChecked}"/>
|
||||
|
||||
<Button
|
||||
|
||||
@@ -124,57 +124,54 @@ public partial class DirectoryOrCustomSelectControl : UserControl
|
||||
|
||||
public async void Browse_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
if (VisualRoot is not Window window)
|
||||
return;
|
||||
|
||||
var options = new FolderPickerOpenOptions
|
||||
{
|
||||
AllowMultiple = false
|
||||
};
|
||||
|
||||
var selectedFolders = await window.StorageProvider.OpenFolderPickerAsync(options);
|
||||
var selectedFolders = await this.GetParentWindow().StorageProvider.OpenFolderPickerAsync(options);
|
||||
Directory = selectedFolders.SingleOrDefault()?.TryGetLocalPath() ?? Directory;
|
||||
}
|
||||
|
||||
private class KnownDirectoryItem : ReactiveObject
|
||||
{
|
||||
public Configuration.KnownDirectories KnownDirectory { get; set; }
|
||||
public string? Directory { get => field; set => this.RaiseAndSetIfChanged(ref field, value); }
|
||||
public string? Name { get; }
|
||||
public string? SubDirectory
|
||||
{
|
||||
get => field;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
if (Configuration.GetKnownDirectoryPath(KnownDirectory) is string dir)
|
||||
{
|
||||
Directory = Path.Combine(dir, field ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public KnownDirectoryItem(Configuration.KnownDirectories known, string? subDir)
|
||||
{
|
||||
Name = known.GetDescription();
|
||||
KnownDirectory = known;
|
||||
SubDirectory = subDir;
|
||||
}
|
||||
|
||||
public bool IsSamePathAs(string? otherPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(otherPath) || string.IsNullOrWhiteSpace(Directory))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var p1 = Path.GetFullPath(Directory);
|
||||
var p2 = Path.GetFullPath(otherPath);
|
||||
return p1.Equals(p2, System.StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
public override string? ToString() => Name?.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class KnownDirectoryItem : ReactiveObject
|
||||
{
|
||||
public Configuration.KnownDirectories KnownDirectory { get; set; }
|
||||
public string? Directory { get => field; set => this.RaiseAndSetIfChanged(ref field, value); }
|
||||
public string? Name { get; }
|
||||
public string? SubDirectory
|
||||
{
|
||||
get => field;
|
||||
set
|
||||
{
|
||||
field = value;
|
||||
if (Configuration.GetKnownDirectoryPath(KnownDirectory) is string dir)
|
||||
{
|
||||
Directory = Path.Combine(dir, field ?? "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public KnownDirectoryItem(Configuration.KnownDirectories known, string? subDir)
|
||||
{
|
||||
Name = known.GetDescription();
|
||||
KnownDirectory = known;
|
||||
SubDirectory = subDir;
|
||||
}
|
||||
|
||||
public bool IsSamePathAs(string? otherPath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(otherPath) || string.IsNullOrWhiteSpace(Directory))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
var p1 = Path.GetFullPath(Directory);
|
||||
var p2 = Path.GetFullPath(otherPath);
|
||||
return p1.Equals(p2, System.StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
public override string? ToString() => Name?.ToString();
|
||||
}
|
||||
@@ -18,13 +18,13 @@
|
||||
<Setter Property="Height" Value="NaN"/>
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
<!-- MinHeight="{Binding #displayPathTbox.MinHeight}" -->
|
||||
<controls:WheelComboBox
|
||||
HorizontalContentAlignment = "Stretch"
|
||||
HorizontalAlignment = "Stretch"
|
||||
Name="combo"
|
||||
MinHeight="{Binding #displayPathTbox.MinHeight}"
|
||||
SelectedItem="{Binding $parent[1].SelectedDirectory, Mode=TwoWay}"
|
||||
ItemsSource="{Binding $parent[1].KnownDirectories}">
|
||||
SelectedItem="{Binding $parent[controls:DirectorySelectControl].SelectedDirectory, Mode=TwoWay}"
|
||||
ItemsSource="{Binding $parent[controls:DirectorySelectControl].KnownDirectories}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={StaticResource KnownDirectoryConverter}}" />
|
||||
@@ -36,7 +36,7 @@
|
||||
<MultiBinding Converter="{StaticResource KnownDirectoryPath}">
|
||||
<MultiBinding.Bindings>
|
||||
<Binding Path="#combo.SelectedItem"/>
|
||||
<Binding Path="$parent[1].SubDirectory"/>
|
||||
<Binding Path="$parent[controls:DirectorySelectControl].SubDirectory"/>
|
||||
</MultiBinding.Bindings>
|
||||
</MultiBinding>
|
||||
</TextBox.Text>
|
||||
|
||||
@@ -30,29 +30,26 @@ public partial class Audio : UserControl
|
||||
|
||||
if (!accounts.AccountsSettings.Accounts.All(a => a.IdentityTokens?.DeviceType == AudibleApi.Resources.DeviceType))
|
||||
{
|
||||
if (VisualRoot is Window parent)
|
||||
{
|
||||
var choice = await MessageBox.Show(parent,
|
||||
"In order to enable widevine content, Libation will need to log into your accounts again.\r\n\r\n" +
|
||||
"Do you want Libation to clear your current account settings and prompt you to login before the next download?",
|
||||
"Widevine Content Unavailable",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question,
|
||||
MessageBoxDefaultButton.Button2);
|
||||
var choice = await MessageBox.Show(this.GetParentWindow(),
|
||||
"In order to enable widevine content, Libation will need to log into your accounts again.\r\n\r\n" +
|
||||
"Do you want Libation to clear your current account settings and prompt you to login before the next download?",
|
||||
"Widevine Content Unavailable",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question,
|
||||
MessageBoxDefaultButton.Button2);
|
||||
|
||||
if (choice == DialogResult.Yes)
|
||||
if (choice == DialogResult.Yes)
|
||||
{
|
||||
foreach (var account in accounts.AccountsSettings.Accounts.ToArray())
|
||||
{
|
||||
foreach (var account in accounts.AccountsSettings.Accounts.ToArray())
|
||||
if (account.Locale is not null && account.IdentityTokens?.DeviceType != AudibleApi.Resources.DeviceType)
|
||||
{
|
||||
if (account.Locale is not null && account.IdentityTokens?.DeviceType != AudibleApi.Resources.DeviceType)
|
||||
{
|
||||
accounts.AccountsSettings.Delete(account);
|
||||
var acc = accounts.AccountsSettings.Upsert(account.AccountId, account.Locale.Name);
|
||||
acc.AccountName = account.AccountName;
|
||||
}
|
||||
accounts.AccountsSettings.Delete(account);
|
||||
var acc = accounts.AccountsSettings.Upsert(account.AccountId, account.Locale.Name);
|
||||
acc.AccountName = account.AccountName;
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_viewModel?.UseWidevine = false;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<controls:GroupBox
|
||||
Grid.Row="0"
|
||||
Margin="5"
|
||||
Label="{CompiledBinding BadBookGroupboxText}">
|
||||
Label="{Binding BadBookGroupboxText}">
|
||||
|
||||
<Grid
|
||||
ColumnDefinitions="*,*"
|
||||
@@ -29,36 +29,36 @@
|
||||
<RadioButton
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
IsChecked="{CompiledBinding BadBookAsk, Mode=TwoWay}">
|
||||
IsChecked="{Binding BadBookAsk, Mode=TwoWay}">
|
||||
|
||||
<TextBlock Text="{CompiledBinding BadBookAskText}" />
|
||||
<TextBlock Text="{Binding BadBookAskText}" />
|
||||
|
||||
</RadioButton>
|
||||
|
||||
<RadioButton
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
IsChecked="{CompiledBinding BadBookAbort, Mode=TwoWay}">
|
||||
IsChecked="{Binding BadBookAbort, Mode=TwoWay}">
|
||||
|
||||
<TextBlock Text="{CompiledBinding BadBookAbortText}" />
|
||||
<TextBlock Text="{Binding BadBookAbortText}" />
|
||||
|
||||
</RadioButton>
|
||||
|
||||
<RadioButton
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
IsChecked="{CompiledBinding BadBookRetry, Mode=TwoWay}">
|
||||
IsChecked="{Binding BadBookRetry, Mode=TwoWay}">
|
||||
|
||||
<TextBlock Text="{CompiledBinding BadBookRetryText}" />
|
||||
<TextBlock Text="{Binding BadBookRetryText}" />
|
||||
|
||||
</RadioButton>
|
||||
|
||||
<RadioButton
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
IsChecked="{CompiledBinding BadBookIgnore, Mode=TwoWay}">
|
||||
IsChecked="{Binding BadBookIgnore, Mode=TwoWay}">
|
||||
|
||||
<TextBlock Text="{CompiledBinding BadBookIgnoreText}" />
|
||||
<TextBlock Text="{Binding BadBookIgnoreText}" />
|
||||
|
||||
</RadioButton>
|
||||
</Grid>
|
||||
@@ -90,12 +90,12 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="0,5,0,0"
|
||||
Text="{CompiledBinding FolderTemplateText}" />
|
||||
Text="{Binding FolderTemplateText}" />
|
||||
|
||||
<TextBox
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Text="{CompiledBinding FolderTemplate}" />
|
||||
Text="{Binding FolderTemplate}" />
|
||||
|
||||
<Button
|
||||
Grid.Row="1"
|
||||
@@ -106,12 +106,12 @@
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Text="{CompiledBinding FileTemplateText}" />
|
||||
Text="{Binding FileTemplateText}" />
|
||||
|
||||
<TextBox
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Text="{CompiledBinding FileTemplate}" />
|
||||
Text="{Binding FileTemplate}" />
|
||||
|
||||
<Button
|
||||
Grid.Row="3"
|
||||
@@ -122,12 +122,12 @@
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Text="{CompiledBinding ChapterFileTemplateText}" />
|
||||
Text="{Binding ChapterFileTemplateText}" />
|
||||
|
||||
<TextBox
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Text="{CompiledBinding ChapterFileTemplate}" />
|
||||
Text="{Binding ChapterFileTemplate}" />
|
||||
|
||||
<Button
|
||||
Grid.Row="5"
|
||||
@@ -140,7 +140,7 @@
|
||||
Grid.Column="0"
|
||||
Height="30"
|
||||
Margin="0"
|
||||
Content="{CompiledBinding EditCharReplacementText}"
|
||||
Content="{Binding EditCharReplacementText}"
|
||||
Click="EditCharReplacementButton_Click" />
|
||||
|
||||
</Grid>
|
||||
@@ -156,11 +156,11 @@
|
||||
<TextBlock
|
||||
Margin="0,0,0,10"
|
||||
TextWrapping="Wrap"
|
||||
Text="{CompiledBinding InProgressDescriptionText}" />
|
||||
Text="{Binding InProgressDescriptionText}" />
|
||||
|
||||
<controls:DirectoryOrCustomSelectControl
|
||||
Directory="{CompiledBinding InProgressDirectory, Mode=TwoWay}"
|
||||
KnownDirectories="{CompiledBinding KnownDirectories}" />
|
||||
Directory="{Binding InProgressDirectory, Mode=TwoWay}"
|
||||
KnownDirectories="{Binding KnownDirectories}" />
|
||||
|
||||
</StackPanel>
|
||||
</controls:GroupBox>
|
||||
@@ -172,23 +172,23 @@
|
||||
<CheckBox
|
||||
Margin="5"
|
||||
VerticalAlignment="Top"
|
||||
IsVisible="{CompiledBinding !Config.IsLinux}"
|
||||
IsChecked="{CompiledBinding UseCoverAsFolderIcon, Mode=TwoWay}">
|
||||
IsVisible="{Binding !Config.IsLinux}"
|
||||
IsChecked="{Binding UseCoverAsFolderIcon, Mode=TwoWay}">
|
||||
|
||||
<TextBlock
|
||||
TextWrapping="Wrap"
|
||||
Text="{CompiledBinding UseCoverAsFolderIconText}" />
|
||||
Text="{Binding UseCoverAsFolderIconText}" />
|
||||
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox
|
||||
Margin="5"
|
||||
VerticalAlignment="Top"
|
||||
IsChecked="{CompiledBinding SaveMetadataToFile, Mode=TwoWay}">
|
||||
IsChecked="{Binding SaveMetadataToFile, Mode=TwoWay}">
|
||||
|
||||
<TextBlock
|
||||
TextWrapping="Wrap"
|
||||
Text="{CompiledBinding SaveMetadataToFileText}" />
|
||||
Text="{Binding SaveMetadataToFileText}" />
|
||||
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
|
||||
@@ -18,29 +18,29 @@
|
||||
</Style>
|
||||
</StackPanel.Styles>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding AutoScan, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding AutoScanText}" />
|
||||
<CheckBox IsChecked="{Binding AutoScan, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding AutoScanText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding ShowImportedStats, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding ShowImportedStatsText}" />
|
||||
<CheckBox IsChecked="{Binding ShowImportedStats, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding ShowImportedStatsText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding ImportEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding ImportEpisodesText}" />
|
||||
<CheckBox IsChecked="{Binding ImportEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding ImportEpisodesText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding ImportPlusTitles, Mode=TwoWay}"
|
||||
ToolTip.Tip="{CompiledBinding ImportPlusTitlesTip}">
|
||||
<TextBlock Text="{CompiledBinding ImportPlusTitlesText}" />
|
||||
<CheckBox IsChecked="{Binding ImportPlusTitles, Mode=TwoWay}"
|
||||
ToolTip.Tip="{Binding ImportPlusTitlesTip}">
|
||||
<TextBlock Text="{Binding ImportPlusTitlesText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding DownloadEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding DownloadEpisodesText}" />
|
||||
<CheckBox IsChecked="{Binding DownloadEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding DownloadEpisodesText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding AutoDownloadEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding AutoDownloadEpisodesText}" />
|
||||
<CheckBox IsChecked="{Binding AutoDownloadEpisodes, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding AutoDownloadEpisodesText}" />
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -17,19 +17,19 @@
|
||||
<StackPanel>
|
||||
<TextBlock
|
||||
Margin="5"
|
||||
Text="{CompiledBinding BooksText}" />
|
||||
Text="{Binding BooksText}" />
|
||||
|
||||
<controls:DirectoryOrCustomSelectControl Margin="0,10,0,10"
|
||||
SubDirectory="Books"
|
||||
Directory="{CompiledBinding BooksDirectory, Mode=TwoWay}"
|
||||
KnownDirectories="{CompiledBinding KnownDirectories}" />
|
||||
Directory="{Binding BooksDirectory, Mode=TwoWay}"
|
||||
KnownDirectories="{Binding KnownDirectories}" />
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding SavePodcastsToParentFolder, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding SavePodcastsToParentFolderText}" />
|
||||
<CheckBox IsChecked="{Binding SavePodcastsToParentFolder, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding SavePodcastsToParentFolderText}" />
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox IsChecked="{CompiledBinding OverwriteExisting, Mode=TwoWay}">
|
||||
<TextBlock Text="{CompiledBinding OverwriteExistingText}" />
|
||||
<CheckBox IsChecked="{Binding OverwriteExisting, Mode=TwoWay}">
|
||||
<TextBlock Text="{Binding OverwriteExistingText}" />
|
||||
</CheckBox>
|
||||
|
||||
<Grid
|
||||
@@ -39,21 +39,21 @@
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,10,0"
|
||||
Text="{CompiledBinding CreationTimeText}" />
|
||||
Text="{Binding CreationTimeText}" />
|
||||
|
||||
<controls:WheelComboBox
|
||||
Height="25"
|
||||
Grid.Column="1"
|
||||
Margin="0,5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
SelectedItem="{CompiledBinding CreationTime, Mode=TwoWay}"
|
||||
ItemsSource="{CompiledBinding DateTimeSources}" />
|
||||
SelectedItem="{Binding CreationTime, Mode=TwoWay}"
|
||||
ItemsSource="{Binding DateTimeSources}" />
|
||||
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Grid.Row="1"
|
||||
Margin="0,0,10,0"
|
||||
Text="{CompiledBinding LastWriteTimeText}" />
|
||||
Text="{Binding LastWriteTimeText}" />
|
||||
|
||||
<controls:WheelComboBox
|
||||
Height="25"
|
||||
@@ -61,8 +61,8 @@
|
||||
Grid.Column="1"
|
||||
Margin="0,5"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
SelectedItem="{CompiledBinding LastWriteTime, Mode=TwoWay}"
|
||||
ItemsSource="{CompiledBinding DateTimeSources}" />
|
||||
SelectedItem="{Binding LastWriteTime, Mode=TwoWay}"
|
||||
ItemsSource="{Binding DateTimeSources}" />
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -72,16 +72,16 @@
|
||||
<CheckBox
|
||||
Grid.Row="1"
|
||||
Margin="10,5"
|
||||
IsEnabled="{CompiledBinding !UseWebViewSettingDisabled}"
|
||||
IsChecked="{CompiledBinding UseWebView, Mode=TwoWay}">
|
||||
IsEnabled="{Binding !UseWebViewSettingDisabled}"
|
||||
IsChecked="{Binding UseWebView, Mode=TwoWay}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="{CompiledBinding UseWebViewText}" />
|
||||
<TextBlock Text="{Binding UseWebViewText}" />
|
||||
<TextBlock
|
||||
IsVisible="{CompiledBinding UseWebViewSettingDisabled}"
|
||||
IsVisible="{Binding UseWebViewSettingDisabled}"
|
||||
FontStyle="Italic"
|
||||
Opacity="0.8"
|
||||
Margin="0,2,0,0"
|
||||
Text="{CompiledBinding UseWebViewSnapMessage}" />
|
||||
Text="{Binding UseWebViewSnapMessage}" />
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
|
||||
@@ -98,15 +98,15 @@
|
||||
Width="120"
|
||||
Height="25"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
SelectedItem="{CompiledBinding LoggingLevel, Mode=TwoWay}"
|
||||
ItemsSource="{CompiledBinding LoggingLevels}" />
|
||||
SelectedItem="{Binding LoggingLevel, Mode=TwoWay}"
|
||||
ItemsSource="{Binding LoggingLevels}" />
|
||||
|
||||
<Button
|
||||
Margin="50,0,0,0"
|
||||
Padding="20,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Content="Open Log Folder"
|
||||
Command="{CompiledBinding OpenLogFolderButton}" />
|
||||
Command="{Binding OpenLogFolderButton}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
@@ -121,12 +121,12 @@
|
||||
<TextBlock
|
||||
Margin="0,0,10,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{CompiledBinding GridScaleFactorText}"/>
|
||||
Text="{Binding GridScaleFactorText}"/>
|
||||
|
||||
<Slider
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Value="{CompiledBinding GridScaleFactor, Mode=TwoWay}"
|
||||
Value="{Binding GridScaleFactor, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"
|
||||
Minimum="-100"
|
||||
Maximum="100"
|
||||
@@ -139,13 +139,13 @@
|
||||
Margin="0,0,10,0"
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{CompiledBinding GridFontScaleFactorText}"/>
|
||||
Text="{Binding GridFontScaleFactorText}"/>
|
||||
|
||||
<Slider
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
Width="200"
|
||||
Value="{CompiledBinding GridFontScaleFactor, Mode=TwoWay}"
|
||||
Value="{Binding GridFontScaleFactor, Mode=TwoWay}"
|
||||
VerticalAlignment="Center"
|
||||
Minimum="-100"
|
||||
Maximum="100"
|
||||
@@ -161,7 +161,7 @@
|
||||
Padding="20,0"
|
||||
VerticalAlignment="Stretch"
|
||||
Content="Apply Display Settings"
|
||||
Command="{CompiledBinding ApplyDisplaySettings}"/>
|
||||
Command="{Binding ApplyDisplaySettings}"/>
|
||||
</Grid>
|
||||
</controls:GroupBox>
|
||||
|
||||
@@ -181,8 +181,8 @@
|
||||
Name="ThemeComboBox"
|
||||
Grid.Column="1"
|
||||
MinWidth="80"
|
||||
SelectedItem="{CompiledBinding ThemeVariant, Mode=TwoWay}"
|
||||
ItemsSource="{CompiledBinding Themes}"/>
|
||||
SelectedItem="{Binding ThemeVariant, Mode=TwoWay}"
|
||||
ItemsSource="{Binding Themes}"/>
|
||||
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="650"
|
||||
xmlns:views="clr-namespace:LibationAvalonia.Views"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
x:DataType="controls:ThemePreviewControl"
|
||||
x:Class="LibationAvalonia.Controls.ThemePreviewControl">
|
||||
<Grid RowDefinitions="Auto,Auto,*">
|
||||
<controls:GroupBox>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
Width="450" Height="540"
|
||||
x:Class="LibationAvalonia.Dialogs.AboutDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:AboutVM"
|
||||
Title="About Libation">
|
||||
|
||||
<Grid Margin="10" RowDefinitions="Auto,Auto,Auto,Auto,*">
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
Width="800" Height="450"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:AccountsDialog"
|
||||
x:Class="LibationAvalonia.Dialogs.AccountsDialog"
|
||||
Title="Audible Accounts">
|
||||
<Grid RowDefinitions="*,Auto">
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
mc:Ignorable="d" d:DesignWidth="700" d:DesignHeight="450"
|
||||
Width="700" Height="450"
|
||||
x:Class="LibationAvalonia.Dialogs.BookRecordsDialog"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:BookRecordsDialog"
|
||||
Title="BookRecordsDialog">
|
||||
|
||||
<Grid RowDefinitions="*,Auto">
|
||||
@@ -28,45 +30,52 @@
|
||||
</DataGrid.Styles>
|
||||
|
||||
<DataGrid.Columns>
|
||||
|
||||
<DataGridCheckBoxColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="False"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding IsChecked, Mode=TwoWay}"
|
||||
Header="Checked"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Type}"
|
||||
Header="Type"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Created}"
|
||||
Header="Created"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Start}"
|
||||
Header="Start"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Modified}"
|
||||
Header="Modified"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding End}"
|
||||
Header="End"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Note}"
|
||||
Header="Note"/>
|
||||
<DataGridTextColumn
|
||||
Width="Auto"
|
||||
IsReadOnly="True"
|
||||
x:DataType="dialogs:BookRecordsDialog+BookRecordEntry"
|
||||
Binding="{Binding Title}"
|
||||
Header="Title"/>
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ public partial class BookRecordsDialog : DialogWindow
|
||||
|
||||
#region DataGrid Bindings
|
||||
|
||||
private class BookRecordEntry : ViewModels.ViewModelBase
|
||||
public class BookRecordEntry : ViewModels.ViewModelBase
|
||||
{
|
||||
private const string DateFormat = "yyyy-MM-dd HH\\:mm";
|
||||
public IRecord Record { get; }
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="540" d:DesignHeight="140"
|
||||
x:Class="LibationAvalonia.Dialogs.DescriptionDisplayDialog"
|
||||
SystemDecorations="None"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:DescriptionDisplayDialog"
|
||||
WindowDecorations="None"
|
||||
Title="DescriptionDisplay">
|
||||
|
||||
<Window.Styles>
|
||||
|
||||
@@ -46,7 +46,7 @@ public partial class DescriptionDisplayDialog : Window
|
||||
this.Position = new PixelPoint((int)SpawnLocation.X, (int)Math.Min(SpawnLocation.Y, workingHeight - DescriptionTextBox.DesiredSize.Height));
|
||||
}
|
||||
|
||||
private void DescriptionTextBox_LostFocus(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
private void DescriptionTextBox_LostFocus(object sender, Avalonia.Input.FocusChangedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -21,9 +21,8 @@ public abstract class DialogWindow : Window
|
||||
{
|
||||
SaveAndRestorePosition = saveAndRestorePosition;
|
||||
KeyDown += DialogWindow_KeyDown;
|
||||
Initialized += DialogWindow_Initialized;
|
||||
Opened += DialogWindow_Opened;
|
||||
Loaded += DialogWindow_Loaded;
|
||||
Opened += DialogWindow_Opened;
|
||||
Closing += DialogWindow_Closing;
|
||||
|
||||
if (Design.IsDesignMode)
|
||||
@@ -38,12 +37,6 @@ public abstract class DialogWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
private void DialogWindow_Loaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
if (!CanResize)
|
||||
this.HideMinMaxBtns();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
@@ -51,12 +44,14 @@ public abstract class DialogWindow : Window
|
||||
if (MinHeight == MaxHeight && MinWidth == MaxWidth)
|
||||
{
|
||||
CanResize = false;
|
||||
CanMinimize = false;
|
||||
CanMaximize = false;
|
||||
Height = MinHeight;
|
||||
Width = MinWidth;
|
||||
}
|
||||
}
|
||||
|
||||
private void DialogWindow_Initialized(object? sender, EventArgs e)
|
||||
private void DialogWindow_Loaded(object? sender, EventArgs e)
|
||||
{
|
||||
this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
if (SaveAndRestorePosition)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
CanUserSortColumns="False"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="False"
|
||||
ItemsSource="{CompiledBinding Filters}"
|
||||
ItemsSource="{Binding Filters}"
|
||||
GridLinesVisibility="All">
|
||||
<DataGrid.Columns>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Center"
|
||||
IsEnabled="{CompiledBinding !IsDefault}"
|
||||
IsEnabled="{Binding !IsDefault}"
|
||||
Click="DeleteButton_Clicked" />
|
||||
|
||||
</DataTemplate>
|
||||
@@ -39,13 +39,13 @@
|
||||
<DataGridTextColumn
|
||||
Width="*"
|
||||
IsReadOnly="False"
|
||||
Binding="{CompiledBinding Name, Mode=TwoWay}"
|
||||
Binding="{Binding Name, Mode=TwoWay}"
|
||||
Header="Name"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="*"
|
||||
IsReadOnly="False"
|
||||
Binding="{CompiledBinding FilterString, Mode=TwoWay}"
|
||||
Binding="{Binding FilterString, Mode=TwoWay}"
|
||||
Header="Filter"/>
|
||||
|
||||
<DataGridTemplateColumn Header="Move
Up">
|
||||
@@ -60,8 +60,8 @@
|
||||
Click="MoveUpButton_Clicked">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<CompiledBinding Path="!IsTop" />
|
||||
<CompiledBinding Path="!IsDefault" />
|
||||
<Binding Path="!IsTop" />
|
||||
<Binding Path="!IsDefault" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
@@ -82,8 +82,8 @@
|
||||
Click="MoveDownButton_Clicked">
|
||||
<Button.IsEnabled>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.And}">
|
||||
<CompiledBinding Path="!IsBottom" />
|
||||
<CompiledBinding Path="!IsDefault" />
|
||||
<Binding Path="!IsBottom" />
|
||||
<Binding Path="!IsDefault" />
|
||||
</MultiBinding>
|
||||
</Button.IsEnabled>
|
||||
</Button>
|
||||
|
||||
@@ -86,7 +86,7 @@ public partial class EditQuickFilters : DialogWindow
|
||||
ReIndexFilters();
|
||||
}
|
||||
|
||||
protected override void SaveAndClose()
|
||||
public new void SaveAndClose()
|
||||
{
|
||||
QuickFilters.ReplaceAll(Filters.Select(x => x.AsNamedFilter()).OfType<QuickFilters.NamedFilter>());
|
||||
base.SaveAndClose();
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Margin="0,0,0,10"
|
||||
Text="{CompiledBinding Description}" />
|
||||
Text="{Binding Description}" />
|
||||
|
||||
<TextBox
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
Name="userEditTbox"
|
||||
Text="{CompiledBinding UserTemplateText, Mode=TwoWay}" />
|
||||
Text="{Binding UserTemplateText, Mode=TwoWay}" />
|
||||
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
@@ -36,7 +36,7 @@
|
||||
VerticalAlignment="Stretch"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="Reset to Default"
|
||||
Command="{CompiledBinding ResetToDefault}"/>
|
||||
Command="{Binding ResetToDefault}"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" ColumnDefinitions="Auto,*"
|
||||
Margin="0,0,0,10">
|
||||
@@ -49,13 +49,13 @@
|
||||
GridLinesVisibility="All"
|
||||
AutoGenerateColumns="False"
|
||||
DoubleTapped="EditTemplateViewModel_DoubleTapped"
|
||||
ItemsSource="{CompiledBinding ListItems}" >
|
||||
ItemsSource="{Binding ListItems}" >
|
||||
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Width="Auto" Header="Tag">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Height="18" Margin="10,0,10,0" VerticalAlignment="Center" Text="{CompiledBinding Item1}" />
|
||||
<TextBlock Height="18" Margin="10,0,10,0" VerticalAlignment="Center" Text="{Binding Item1}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -66,7 +66,7 @@
|
||||
<TextBlock
|
||||
Height="18"
|
||||
Margin="10,0,10,0"
|
||||
VerticalAlignment="Center" Text="{CompiledBinding Item2}" />
|
||||
VerticalAlignment="Center" Text="{Binding Item2}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
<TextBlock
|
||||
TextWrapping="WrapWithOverflow"
|
||||
Inlines="{CompiledBinding Inlines}" />
|
||||
Inlines="{Binding Inlines}" />
|
||||
|
||||
</Border>
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
Grid.Row="2"
|
||||
Margin="5"
|
||||
Foreground="Firebrick"
|
||||
Text="{CompiledBinding WarningText}"
|
||||
IsVisible="{CompiledBinding WarningText, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
Text="{Binding WarningText}"
|
||||
IsVisible="{Binding WarningText, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<controls:LinkLabel
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
CanUserSortColumns="True"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
ItemsSource="{CompiledBinding Books}">
|
||||
ItemsSource="{Binding Books}">
|
||||
<DataGrid.Styles>
|
||||
<Style x:DataType="vm:BookDataViewModel" Selector="DataGridRow">
|
||||
<Setter Property="Background" Value="{CompiledBinding ScanStatus, Converter={x:Static dialogs:FindBetterQualityBooksDialog.RowConverter }}" />
|
||||
<Setter Property="Background" Value="{Binding ScanStatus, Converter={x:Static dialogs:FindBetterQualityBooksDialog.RowConverter }}" />
|
||||
</Style>
|
||||
</DataGrid.Styles>
|
||||
<DataGrid.Columns>
|
||||
@@ -30,51 +30,51 @@
|
||||
<DataGridTextColumn
|
||||
Width="120"
|
||||
IsReadOnly="False"
|
||||
Binding="{CompiledBinding Asin}"
|
||||
Binding="{Binding Asin}"
|
||||
Header="ASIN"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="120"
|
||||
IsReadOnly="True"
|
||||
Binding="{CompiledBinding Title}"
|
||||
Binding="{Binding Title}"
|
||||
Header="Title"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="120"
|
||||
IsReadOnly="True"
|
||||
Binding="{CompiledBinding FoundFile}"
|
||||
Binding="{Binding FoundFile}"
|
||||
Header="Best Found File"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="90"
|
||||
IsReadOnly="True"
|
||||
Binding="{CompiledBinding Codec}"
|
||||
Binding="{Binding Codec}"
|
||||
Header="Existing
Codec"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="90"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="Bitrate"
|
||||
Binding="{CompiledBinding BitrateString}"
|
||||
Binding="{Binding BitrateString}"
|
||||
Header="Existing
Bitrate"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="90"
|
||||
IsReadOnly="True"
|
||||
Binding="{CompiledBinding AvailableCodec}"
|
||||
Binding="{Binding AvailableCodec}"
|
||||
Header="Available
Codec"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Width="90"
|
||||
IsReadOnly="True"
|
||||
SortMemberPath="AvailableBitrate"
|
||||
Binding="{CompiledBinding AvailableBitrateString}"
|
||||
Binding="{Binding AvailableBitrateString}"
|
||||
Header="Available
Bitrate"/>
|
||||
|
||||
<DataGridCheckBoxColumn
|
||||
Width="90"
|
||||
IsReadOnly="True"
|
||||
Binding="{CompiledBinding IsSignificant}"
|
||||
Binding="{Binding IsSignificant}"
|
||||
Header="Significantly
Greater?"/>
|
||||
|
||||
</DataGrid.Columns>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
MinWidth="500" MinHeight="500"
|
||||
Width="500" Height="520"
|
||||
Title="Cover"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:ImageDisplayDialog+BitmapHolder"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Image Stretch="Uniform" Source="{Binding CoverImage}">
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
Width="800" Height="165"
|
||||
x:Class="LibationAvalonia.Dialogs.LibationFilesDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:LibationFilesDialog+DirSelectOptions"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="Book Details">
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace LibationAvalonia.Dialogs;
|
||||
|
||||
public partial class LibationFilesDialog : DialogWindow, ILibationInstallLocation
|
||||
{
|
||||
private class DirSelectOptions
|
||||
public class DirSelectOptions
|
||||
{
|
||||
public List<Configuration.KnownDirectories> KnownDirectories { get; } = new()
|
||||
{
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
MinHeight="135" MaxHeight="135"
|
||||
MinWidth="550" MaxWidth="550"
|
||||
Width="550" Height="135"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:LiberatedStatusBatchAutoDialog"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Grid Margin="10" RowDefinitions="Auto,Auto">
|
||||
|
||||
@@ -11,4 +11,8 @@ public partial class LiberatedStatusBatchAutoDialog : DialogWindow
|
||||
DataContext = this;
|
||||
ControlToFocusOnShow = SaveButton;
|
||||
}
|
||||
|
||||
// For compiled bindings
|
||||
public new void SaveAndClose() => base.SaveAndClose();
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
MinWidth="400" MinHeight="100"
|
||||
MaxWidth="400" MaxHeight="100"
|
||||
Width="400" Height="100"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:LiberatedStatusBatchManualDialog"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Grid RowDefinitions="Auto,Auto" ColumnDefinitions="*,Auto">
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace LibationAvalonia.Dialogs;
|
||||
|
||||
public partial class LiberatedStatusBatchManualDialog : DialogWindow
|
||||
{
|
||||
private class liberatedComboBoxItem
|
||||
public class liberatedComboBoxItem
|
||||
{
|
||||
public LiberatedStatus Status { get; set; }
|
||||
public string? Text { get; set; }
|
||||
@@ -27,11 +27,11 @@ public partial class LiberatedStatusBatchManualDialog : DialogWindow
|
||||
}
|
||||
}
|
||||
|
||||
public IList BookStatuses { get; } = new List<liberatedComboBoxItem>
|
||||
{
|
||||
public List<liberatedComboBoxItem> BookStatuses { get; } =
|
||||
[
|
||||
new liberatedComboBoxItem { Status = LiberatedStatus.Liberated, Text = "Downloaded" },
|
||||
new liberatedComboBoxItem { Status = LiberatedStatus.NotLiberated, Text = "Not Downloaded" },
|
||||
};
|
||||
];
|
||||
|
||||
public LiberatedStatusBatchManualDialog(bool isPdf) : this()
|
||||
{
|
||||
@@ -42,7 +42,7 @@ public partial class LiberatedStatusBatchManualDialog : DialogWindow
|
||||
public LiberatedStatusBatchManualDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
SelectedItem = BookStatuses[0] as liberatedComboBoxItem;
|
||||
SelectedItem = BookStatuses[0];
|
||||
DataContext = this;
|
||||
ControlToFocusOnShow = SaveButton;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
CanResize="True"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
x:Class="LibationAvalonia.Dialogs.Login.LoginExternalDialog"
|
||||
xmlns:login="clr-namespace:LibationAvalonia.Dialogs.Login"
|
||||
x:DataType="login:LoginExternalDialog"
|
||||
Title="Audible Login External">
|
||||
|
||||
<Grid RowDefinitions="Auto,Auto,2*,Auto,*" ColumnDefinitions="*" Margin="5">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using AudibleUtilities;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input.Platform;
|
||||
using Dinah.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
Width="600" Height="450"
|
||||
x:Class="LibationAvalonia.Dialogs.MessageBoxAlertAdminDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:MessageBoxAlertAdminDialog"
|
||||
Title="MessageBoxAlertAdminDialog"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
mc:Ignorable="d" d:DesignWidth="265" d:DesignHeight="110"
|
||||
MinWidth="265" MinHeight="110"
|
||||
CanMaximize="False"
|
||||
CanMinimize="False"
|
||||
x:DataType="vm:MessageBoxViewModel"
|
||||
x:Class="LibationAvalonia.Dialogs.MessageBoxWindow"
|
||||
Title="{CompiledBinding Caption}" ShowInTaskbar="True">
|
||||
Title="{Binding Caption}" ShowInTaskbar="True">
|
||||
|
||||
<Grid ColumnDefinitions="*" RowDefinitions="*,Auto">
|
||||
|
||||
@@ -18,19 +20,19 @@
|
||||
<Panel Height="32" Width="32" Grid.Column="0" Margin="5,0,5,0" VerticalAlignment="Top">
|
||||
<Panel.IsVisible>
|
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}">
|
||||
<CompiledBinding Path="IsAsterisk" />
|
||||
<CompiledBinding Path="IsError" />
|
||||
<CompiledBinding Path="IsQuestion" />
|
||||
<CompiledBinding Path="IsExclamation" />
|
||||
<Binding Path="IsAsterisk" />
|
||||
<Binding Path="IsError" />
|
||||
<Binding Path="IsQuestion" />
|
||||
<Binding Path="IsExclamation" />
|
||||
</MultiBinding>
|
||||
</Panel.IsVisible>
|
||||
<Image IsVisible="{CompiledBinding IsAsterisk}" Stretch="Uniform" Source="/Assets/MBIcons/Asterisk_64.png"/>
|
||||
<Image IsVisible="{CompiledBinding IsError}" Stretch="Uniform" Source="/Assets/MBIcons/Error_64.png"/>
|
||||
<Image IsVisible="{CompiledBinding IsQuestion}" Stretch="Uniform" Source="/Assets/MBIcons/Question_64.png"/>
|
||||
<Image IsVisible="{CompiledBinding IsExclamation}" Stretch="Uniform" Source="/Assets/MBIcons/Exclamation_64.png"/>
|
||||
<Image IsVisible="{Binding IsAsterisk}" Stretch="Uniform" Source="/Assets/MBIcons/Asterisk_64.png"/>
|
||||
<Image IsVisible="{Binding IsError}" Stretch="Uniform" Source="/Assets/MBIcons/Error_64.png"/>
|
||||
<Image IsVisible="{Binding IsQuestion}" Stretch="Uniform" Source="/Assets/MBIcons/Question_64.png"/>
|
||||
<Image IsVisible="{Binding IsExclamation}" Stretch="Uniform" Source="/Assets/MBIcons/Exclamation_64.png"/>
|
||||
</Panel>
|
||||
|
||||
<TextBlock Margin="5,0,0,0" Name="messageTextBlock" MinHeight="45" MinWidth="193" TextWrapping="WrapWithOverflow" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="12" Text="{CompiledBinding Message}" />
|
||||
<TextBlock Margin="5,0,0,0" Name="messageTextBlock" MinHeight="45" MinWidth="193" TextWrapping="WrapWithOverflow" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="12" Text="{Binding Message}" />
|
||||
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
@@ -38,13 +40,13 @@
|
||||
<DockPanel Height="45" Grid.Row="1" Background="{DynamicResource SystemChromeMediumLowColor}">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="5" DockPanel.Dock="Bottom">
|
||||
<Button Grid.Column="0" MinWidth="75" MinHeight="28" Name="Button1" Click="Button1_Click" Margin="5">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{CompiledBinding Button1Text}"/>
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Button1Text}"/>
|
||||
</Button>
|
||||
<Button Grid.Column="1" IsVisible="{CompiledBinding HasButton2}" MinWidth="75" MinHeight="28" Name="Button2" Click="Button2_Click" Margin="5">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{CompiledBinding Button2Text}"/>
|
||||
<Button Grid.Column="1" IsVisible="{Binding HasButton2}" MinWidth="75" MinHeight="28" Name="Button2" Click="Button2_Click" Margin="5">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Button2Text}"/>
|
||||
</Button>
|
||||
<Button Grid.Column="2" IsVisible="{CompiledBinding HasButton3}" MinWidth="75" MinHeight="28" Name="Button3" Click="Button3_Click" Margin="5">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{CompiledBinding Button3Text}"/>
|
||||
<Button Grid.Column="2" IsVisible="{Binding HasButton3}" MinWidth="75" MinHeight="28" Name="Button3" Click="Button3_Click" Margin="5">
|
||||
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Button3Text}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
|
||||
@@ -49,26 +49,26 @@
|
||||
|
||||
<Grid Grid.Row="1" RowDefinitions="Auto,Auto,*">
|
||||
<TextBlock Text="STRING FIELDS" />
|
||||
<TextBlock Grid.Row="1" Text="{CompiledBinding StringUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{CompiledBinding StringFields}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding StringUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{Binding StringFields}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1" RowDefinitions="Auto,Auto,*">
|
||||
<TextBlock Text="NUMBER FIELDS" />
|
||||
<TextBlock Grid.Row="1" Text="{CompiledBinding NumberUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{CompiledBinding NumberFields}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding NumberUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{Binding NumberFields}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="2" RowDefinitions="Auto,Auto,*">
|
||||
<TextBlock Text="BOOLEAN (TRUE/FALSE) FIELDS" />
|
||||
<TextBlock Grid.Row="1" Text="{CompiledBinding BoolUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{CompiledBinding BoolFields}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding BoolUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{Binding BoolFields}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="3" RowDefinitions="Auto,Auto,*">
|
||||
<TextBlock Text="ID FIELDS" />
|
||||
<TextBlock Grid.Row="1" Text="{CompiledBinding IdUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{CompiledBinding IdFields}"/>
|
||||
<TextBlock Grid.Row="1" Text="{Binding IdUsage}" />
|
||||
<ListBox Grid.Row="2" DoubleTapped="ListBox_DoubleTapped" ItemsSource="{Binding IdFields}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</TabItem.Header>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Important DataContext="{CompiledBinding ImportantSettings}" />
|
||||
<settings:Important DataContext="{Binding ImportantSettings, Mode=OneTime}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem>
|
||||
@@ -58,7 +58,7 @@
|
||||
</TabItem.Header>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Import DataContext="{CompiledBinding ImportSettings}" />
|
||||
<settings:Import DataContext="{Binding ImportSettings, Mode=OneTime}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
</TabItem.Header>
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:DownloadDecrypt DataContext="{CompiledBinding DownloadDecryptSettings}" />
|
||||
<settings:DownloadDecrypt DataContext="{Binding DownloadDecryptSettings, Mode=OneTime}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<TextBlock Text="Audio File Settings"/>
|
||||
</TabItem.Header>
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Audio DataContext="{CompiledBinding AudioSettings}" />
|
||||
<settings:Audio DataContext="{Binding AudioSettings, Mode=OneTime}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="630" d:DesignHeight="90"
|
||||
x:Class="LibationAvalonia.Dialogs.TagsBatchDialog"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:TagsBatchDialog"
|
||||
MinWidth="630" MinHeight="90"
|
||||
MaxWidth="630" MaxHeight="90"
|
||||
Width="630" Height="110"
|
||||
|
||||
@@ -12,4 +12,7 @@ public partial class TagsBatchDialog : DialogWindow
|
||||
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
// For compiled bindings
|
||||
public new void SaveAndClose() => base.SaveAndClose();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
Width="965" Height="850"
|
||||
x:Class="LibationAvalonia.Dialogs.ThemePickerDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:ThemePickerDialog"
|
||||
Title="Theme Editor">
|
||||
|
||||
<Grid ColumnDefinitions="Auto,*">
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace LibationAvalonia.Dialogs;
|
||||
|
||||
public partial class ThemePickerDialog : DialogWindow
|
||||
{
|
||||
protected DataGridCollectionView ThemeColors { get; }
|
||||
public AvaloniaList<ThemeItemColor> ThemeColors { get; }
|
||||
private ChardonnayTheme ExistingTheme { get; } = ChardonnayTheme.GetLiveTheme();
|
||||
private ChardonnayTheme WorkingTheme { get; set; }
|
||||
|
||||
@@ -38,7 +38,7 @@ public partial class ThemePickerDialog : DialogWindow
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task ImportTheme()
|
||||
public async Task ImportTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -74,7 +74,7 @@ public partial class ThemePickerDialog : DialogWindow
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task ExportTheme()
|
||||
public async Task ExportTheme()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -110,22 +110,24 @@ public partial class ThemePickerDialog : DialogWindow
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CancelAndClose()
|
||||
public new void CancelAndClose()
|
||||
{
|
||||
ExistingTheme.ApplyTheme(ActualThemeVariant);
|
||||
base.CancelAndClose();
|
||||
}
|
||||
|
||||
protected void ResetColors()
|
||||
|
||||
|
||||
public void ResetColors()
|
||||
=> ResetTheme(ExistingTheme);
|
||||
|
||||
protected void LoadDefaultColors()
|
||||
public void LoadDefaultColors()
|
||||
{
|
||||
if (App.DefaultThemeColors is ChardonnayTheme defaults)
|
||||
ResetTheme(defaults);
|
||||
}
|
||||
|
||||
protected override async Task SaveAndCloseAsync()
|
||||
public new async Task SaveAndCloseAsync()
|
||||
{
|
||||
using (var themePersister = ChardonnayThemePersister.Create())
|
||||
{
|
||||
@@ -174,7 +176,7 @@ public partial class ThemePickerDialog : DialogWindow
|
||||
WorkingTheme.ApplyTheme(ActualThemeVariant);
|
||||
}
|
||||
|
||||
private class ThemeItemColor : ViewModels.ViewModelBase
|
||||
public class ThemeItemColor : ViewModels.ViewModelBase
|
||||
{
|
||||
public required string ThemeItemName { get; init; }
|
||||
public required Action<Color, string>? ColorSetter { get; set; }
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
DisableContextMenu="True"
|
||||
DisableColumnCustomization="True"
|
||||
IsEnabled="{Binding $parent.((dialogs:TrashBinViewModel)DataContext).ControlsEnabled}"
|
||||
DataContext="{Binding ProductsDisplay}" />
|
||||
DataContext="{Binding ProductsDisplay, Mode=OneTime}" />
|
||||
|
||||
<Grid
|
||||
Margin="0,5,0,0"
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
mc:Ignorable="d" d:DesignWidth="550" d:DesignHeight="450"
|
||||
x:Class="LibationAvalonia.Dialogs.UpgradeNotificationDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:dialogs="clr-namespace:LibationAvalonia.Dialogs"
|
||||
x:DataType="dialogs:UpgradeNotificationDialog"
|
||||
MinWidth="500" MinHeight="400"
|
||||
Height="450" Width="550"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
|
||||
@@ -111,62 +111,4 @@ public static class FormSaveExtension
|
||||
public int Width;
|
||||
public bool IsMaximized;
|
||||
}
|
||||
|
||||
public static void HideMinMaxBtns(this Window form)
|
||||
{
|
||||
if (Design.IsDesignMode || !Configuration.IsWindows || form.TryGetPlatformHandle() is not IPlatformHandle handle)
|
||||
return;
|
||||
|
||||
var windowStyle
|
||||
= GetWindowStyle(handle.Handle)
|
||||
.Remove(WINDOW_STYLE.WS_MINIMIZEBOX)
|
||||
.Remove(WINDOW_STYLE.WS_MAXIMIZEBOX);
|
||||
|
||||
SetWindowStyle(handle.Handle, windowStyle);
|
||||
}
|
||||
|
||||
const int GWL_STYLE = -16;
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
||||
static extern long GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong);
|
||||
|
||||
static WINDOW_STYLE GetWindowStyle(IntPtr hWnd) => (WINDOW_STYLE)GetWindowLong(hWnd, GWL_STYLE);
|
||||
static void SetWindowStyle(IntPtr hWnd, WINDOW_STYLE style) => SetWindowLong(hWnd, GWL_STYLE, (long)style);
|
||||
|
||||
|
||||
[Flags]
|
||||
enum WINDOW_STYLE : long
|
||||
{
|
||||
WS_OVERLAPPED = 0x0,
|
||||
WS_TILED = 0x0,
|
||||
WS_ACTIVECAPTION = 0x1,
|
||||
WS_MAXIMIZEBOX = 0x10000,
|
||||
WS_TABSTOP = 0x10000,
|
||||
WS_MINIMIZEBOX = 0x20000,
|
||||
WS_GROUP = 0x20000,
|
||||
WS_THICKFRAME = 0x40000,
|
||||
WS_SIZEBOX = 0x40000,
|
||||
WS_SYSMENU = 0x80000,
|
||||
WS_HSCROLL = 0x100000,
|
||||
WS_VSCROLL = 0x200000,
|
||||
WS_DLGFRAME = 0x400000,
|
||||
WS_BORDER = 0x800000,
|
||||
WS_CAPTION = 0xc00000,
|
||||
WS_OVERLAPPEDWINDOW = 0xcf0000,
|
||||
WS_TILEDWINDOW = 0xcf0000,
|
||||
WS_MAXIMIZE = 0x1000000,
|
||||
WS_CLIPCHILDREN = 0x2000000,
|
||||
WS_CLIPSIBLINGS = 0x4000000,
|
||||
WS_DISABLED = 0x8000000,
|
||||
WS_VISIBLE = 0x10000000,
|
||||
WS_ICONIC = 0x20000000,
|
||||
WS_MINIMIZE = 0x20000000,
|
||||
WS_CHILD = 0x40000000,
|
||||
WS_CHILDWINDOW = 0x40000000,
|
||||
WS_POPUP = 0x80000000,
|
||||
WS_POPUPWINDOW = 0x80880000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<Nullable>enable</Nullable>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -73,14 +72,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Controls.ColorPicker" Version="11.3.11" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.11" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.11" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.3.11" />
|
||||
<PackageReference Include="ReactiveUI.Avalonia" Version="11.3.8" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.11" />
|
||||
<PackageReference Include="WebViewControlAvaloniaFree" Version="11.3.16" />
|
||||
<PackageReference Include="Tmds.DBus.Protocol" Version="0.21.3" />
|
||||
<PackageReference Include="Avalonia.Controls.ColorPicker" Version="12.0.2" />
|
||||
<PackageReference Include="Avalonia.Controls.WebView" Version="12.0.0" />
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.14" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="12.0.0" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="12.0.2" />
|
||||
<PackageReference Include="ReactiveUI.Avalonia" Version="12.0.1" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="12.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -189,7 +189,7 @@ public class MessageBox
|
||||
IsVisible = false,
|
||||
Height = 1,
|
||||
Width = 1,
|
||||
SystemDecorations = SystemDecorations.None,
|
||||
WindowDecorations = WindowDecorations.None,
|
||||
ShowInTaskbar = false
|
||||
};
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static class Program
|
||||
return AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI()
|
||||
.UseReactiveUI(_ => { })
|
||||
.AfterSetup(_ => SetupLock.Exit());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ partial class MainVM
|
||||
private void Configure_Filters()
|
||||
{
|
||||
FirstFilterIsDefault = QuickFilters.UseDefault;
|
||||
MainWindow.Initialized += updateFiltersMenu;
|
||||
MainWindow.Loaded += updateFiltersMenu;
|
||||
QuickFilters.Updated += updateFiltersMenu;
|
||||
|
||||
//We need to be able to dynamically add and remove menu items from the Quick Filters menu.
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Padding="0"
|
||||
IsEnabled="{CompiledBinding IsButtonEnabled}" Click="Button_Click" >
|
||||
IsEnabled="{Binding IsButtonEnabled}" Click="Button_Click" >
|
||||
|
||||
<Grid RowDefinitions="*,8*,*">
|
||||
<Viewbox
|
||||
@@ -45,31 +45,31 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch">
|
||||
<Panel>
|
||||
<Panel IsVisible="{CompiledBinding !IsError}">
|
||||
<Panel IsVisible="{Binding !IsError}">
|
||||
|
||||
<Panel IsVisible="{CompiledBinding IsSeries}">
|
||||
<Path IsVisible="{CompiledBinding Expanded}" Data="{StaticResource CollapseIcon}" />
|
||||
<Path IsVisible="{CompiledBinding !Expanded}" Data="{StaticResource ExpandIcon}" />
|
||||
<Panel IsVisible="{Binding IsSeries}">
|
||||
<Path IsVisible="{Binding Expanded}" Data="{StaticResource CollapseIcon}" />
|
||||
<Path IsVisible="{Binding !Expanded}" Data="{StaticResource ExpandIcon}" />
|
||||
</Panel>
|
||||
|
||||
<Grid
|
||||
IsVisible="{CompiledBinding !IsSeries}"
|
||||
IsVisible="{Binding !IsSeries}"
|
||||
HorizontalAlignment="Center"
|
||||
ColumnDefinitions="Auto,Auto">
|
||||
<Canvas Width="29.44" Height="64">
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="5" IsVisible="{CompiledBinding RedVisible}" Fill="{DynamicResource StoplightRed}" />
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="23" IsVisible="{CompiledBinding YellowVisible}" Fill="{DynamicResource StoplightYellow}" />
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="42" IsVisible="{CompiledBinding GreenVisible}" Fill="{DynamicResource StoplightGreen}" />
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="5" IsVisible="{Binding RedVisible}" Fill="{DynamicResource StoplightRed}" />
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="23" IsVisible="{Binding YellowVisible}" Fill="{DynamicResource StoplightYellow}" />
|
||||
<Rectangle Canvas.Left="5" Canvas.Top="42" IsVisible="{Binding GreenVisible}" Fill="{DynamicResource StoplightGreen}" />
|
||||
<Path Height="64" Stretch="Uniform" Data="{StaticResource StoplightBodyIcon}"/>
|
||||
</Canvas>
|
||||
<Path Grid.Column="1" IsVisible="{CompiledBinding PdfDownloadedVisible}" Data="{StaticResource PdfDownloadedIcon}"/>
|
||||
<Path Grid.Column="1" IsVisible="{CompiledBinding PdfNotDownloadedVisible}" Data="{StaticResource PdfNotDownloadedIcon}"/>
|
||||
<Path Grid.Column="1" IsVisible="{Binding PdfDownloadedVisible}" Data="{StaticResource PdfDownloadedIcon}"/>
|
||||
<Path Grid.Column="1" IsVisible="{Binding PdfNotDownloadedVisible}" Data="{StaticResource PdfNotDownloadedIcon}"/>
|
||||
</Grid>
|
||||
</Panel>
|
||||
|
||||
<Path
|
||||
Stretch="None" Width="64"
|
||||
IsVisible="{CompiledBinding IsError}"
|
||||
IsVisible="{Binding IsError}"
|
||||
Fill="{DynamicResource CancelRed}"
|
||||
Data="{StaticResource BookErrorIcon}" />
|
||||
</Panel>
|
||||
|
||||
@@ -19,56 +19,56 @@
|
||||
<NativeMenu>
|
||||
<NativeMenuItem
|
||||
Header="Auto Scan Library"
|
||||
Command="{CompiledBinding ToggleAutoScan}"
|
||||
IsChecked="{CompiledBinding AutoScanChecked}"
|
||||
Command="{Binding ToggleAutoScan}"
|
||||
IsChecked="{Binding AutoScanChecked}"
|
||||
ToggleType="CheckBox" />
|
||||
<NativeMenuItemSeparator />
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
<NativeMenuItem Header="Liberate">
|
||||
<NativeMenu>
|
||||
<NativeMenuItem Command="{CompiledBinding BackupAllBooks}" Header="{CompiledBinding BookBackupsToolStripText}" Gesture="{OnPlatform macOS='alt+⌘+B'}" />
|
||||
<NativeMenuItem Command="{CompiledBinding BackupAllPdfs}" Header="{CompiledBinding PdfBackupsToolStripText}" Gesture="{OnPlatform macOS='alt+⌘+P'}"/>
|
||||
<NativeMenuItem Command="{CompiledBinding ConvertAllToMp3Async}" Header="Convert all M4b to Mp3 [Long-running]..." />
|
||||
<NativeMenuItem Command="{CompiledBinding LiberateVisible}" Header="{CompiledBinding LiberateVisibleToolStripText}" IsEnabled="{CompiledBinding AnyVisibleNotLiberated}" />
|
||||
<NativeMenuItem Command="{Binding BackupAllBooks}" Header="{Binding BookBackupsToolStripText}" Gesture="{OnPlatform macOS='alt+⌘+B'}" />
|
||||
<NativeMenuItem Command="{Binding BackupAllPdfs}" Header="{Binding PdfBackupsToolStripText}" Gesture="{OnPlatform macOS='alt+⌘+P'}"/>
|
||||
<NativeMenuItem Command="{Binding ConvertAllToMp3Async}" Header="Convert all M4b to Mp3 [Long-running]..." />
|
||||
<NativeMenuItem Command="{Binding LiberateVisible}" Header="{Binding LiberateVisibleToolStripText}" IsEnabled="{Binding AnyVisibleNotLiberated}" />
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
<NativeMenuItem Header="Export">
|
||||
<NativeMenu>
|
||||
<NativeMenuItem Command="{CompiledBinding ExportLibraryAsync}" Header="Export Library" Gesture="{OnPlatform macOS='alt+⌘+X'}"/>
|
||||
<NativeMenuItem Command="{Binding ExportLibraryAsync}" Header="Export Library" Gesture="{OnPlatform macOS='alt+⌘+X'}"/>
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
<NativeMenuItem Header="Quick Filters">
|
||||
<NativeMenu>
|
||||
<NativeMenuItem
|
||||
Header="Start Libation with 1st filter Default"
|
||||
Command="{CompiledBinding ToggleFirstFilterIsDefault}"
|
||||
IsChecked="{CompiledBinding FirstFilterIsDefault}"
|
||||
Command="{Binding ToggleFirstFilterIsDefault}"
|
||||
IsChecked="{Binding FirstFilterIsDefault}"
|
||||
ToggleType="CheckBox" />
|
||||
<NativeMenuItem Command="{CompiledBinding EditQuickFiltersAsync}" Header="Edit quick filters..." Gesture="{OnPlatform macOS='alt+⌘+Q'}" />
|
||||
<NativeMenuItem Command="{Binding EditQuickFiltersAsync}" Header="Edit quick filters..." Gesture="{OnPlatform macOS='alt+⌘+Q'}" />
|
||||
<NativeMenuItemSeparator />
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
<NativeMenuItem Header="Visible Books">
|
||||
<NativeMenu>
|
||||
<NativeMenuItem Command="{CompiledBinding LiberateVisible}" Header="{CompiledBinding LiberateVisibleToolStripText_2}" IsEnabled="{CompiledBinding AnyVisibleNotLiberated}" Gesture="{OnPlatform macOS='alt+⌘+V'}" />
|
||||
<NativeMenuItem Command="{CompiledBinding ReplaceTagsAsync}" Header="Replace Tags..." />
|
||||
<NativeMenuItem Command="{CompiledBinding SetBookDownloadedAsync}" Header="Set book 'Downloaded' status manually..." />
|
||||
<NativeMenuItem Command="{CompiledBinding SetPdfDownloadedAsync}" Header="Set PDF 'Downloaded' status manually..." />
|
||||
<NativeMenuItem Command="{CompiledBinding SetDownloadedAutoAsync}" Header="Set 'Downloaded' status automatically..." />
|
||||
<NativeMenuItem Command="{CompiledBinding RemoveVisibleAsync}" Header="Remove from library..." />
|
||||
<NativeMenuItem Command="{Binding LiberateVisible}" Header="{Binding LiberateVisibleToolStripText_2}" IsEnabled="{Binding AnyVisibleNotLiberated}" Gesture="{OnPlatform macOS='alt+⌘+V'}" />
|
||||
<NativeMenuItem Command="{Binding ReplaceTagsAsync}" Header="Replace Tags..." />
|
||||
<NativeMenuItem Command="{Binding SetBookDownloadedAsync}" Header="Set book 'Downloaded' status manually..." />
|
||||
<NativeMenuItem Command="{Binding SetPdfDownloadedAsync}" Header="Set PDF 'Downloaded' status manually..." />
|
||||
<NativeMenuItem Command="{Binding SetDownloadedAutoAsync}" Header="Set 'Downloaded' status automatically..." />
|
||||
<NativeMenuItem Command="{Binding RemoveVisibleAsync}" Header="Remove from library..." />
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
<NativeMenuItem Header="Settings">
|
||||
<NativeMenu>
|
||||
<NativeMenuItem Command="{CompiledBinding ShowAccountsAsync}" Header="Accounts..." Gesture="{OnPlatform macOS='⌘+.'}" />
|
||||
<NativeMenuItem Command="{CompiledBinding ShowSettingsAsync}" Header="Settings..." Gesture="{OnPlatform macOS='⌘+,'}" />
|
||||
<NativeMenuItem Command="{Binding ShowAccountsAsync}" Header="Accounts..." Gesture="{OnPlatform macOS='⌘+.'}" />
|
||||
<NativeMenuItem Command="{Binding ShowSettingsAsync}" Header="Settings..." Gesture="{OnPlatform macOS='⌘+,'}" />
|
||||
<NativeMenuItemSeparator />
|
||||
<NativeMenuItem Command="{CompiledBinding ShowTrashBinAsync}" Header="Trash Bin" Gesture="{OnPlatform macOS='alt+⌘+T'}" />
|
||||
<NativeMenuItem Command="{CompiledBinding LaunchHangover}" Header="Launch Hangover" />
|
||||
<NativeMenuItem Command="{Binding ShowTrashBinAsync}" Header="Trash Bin" Gesture="{OnPlatform macOS='alt+⌘+T'}" />
|
||||
<NativeMenuItem Command="{Binding LaunchHangover}" Header="Launch Hangover" />
|
||||
<NativeMenuItemSeparator />
|
||||
<NativeMenuItem Command="{CompiledBinding StartWalkthroughAsync}" Header="Take a Guided Tour of Libation" />
|
||||
<NativeMenuItem Command="{CompiledBinding ShowAboutAsync}" Header="About..." />
|
||||
<NativeMenuItem Command="{Binding StartWalkthroughAsync}" Header="Take a Guided Tour of Libation" />
|
||||
<NativeMenuItem Command="{Binding ShowAboutAsync}" Header="About..." />
|
||||
</NativeMenu>
|
||||
</NativeMenuItem>
|
||||
</NativeMenu>
|
||||
@@ -78,7 +78,7 @@
|
||||
<Border Grid.Row="0" BorderBrush="{DynamicResource SystemBaseLowColor}" BorderThickness="0,1">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<!-- Menu Strip -->
|
||||
<Menu VerticalAlignment="Top" IsVisible="{CompiledBinding MenuBarVisible}">
|
||||
<Menu VerticalAlignment="Top" IsVisible="{Binding MenuBarVisible}">
|
||||
|
||||
<!-- Decrease height of menu strop -->
|
||||
<Menu.Styles>
|
||||
@@ -90,80 +90,80 @@
|
||||
<!-- Import Menu -->
|
||||
|
||||
<MenuItem Name="importToolStripMenuItem" Header="_Import">
|
||||
<MenuItem IsVisible="{CompiledBinding AnyAccounts}" Command="{CompiledBinding ToggleAutoScan}" Header="A_uto Scan Library">
|
||||
<MenuItem IsVisible="{Binding AnyAccounts}" Command="{Binding ToggleAutoScan}" Header="A_uto Scan Library">
|
||||
<MenuItem.Icon>
|
||||
<CheckBox BorderThickness="0" IsChecked="{CompiledBinding AutoScanChecked, Mode=TwoWay}" IsHitTestVisible="False" />
|
||||
<CheckBox BorderThickness="0" IsChecked="{Binding AutoScanChecked, Mode=TwoWay}" IsHitTestVisible="False" />
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem IsVisible="{CompiledBinding !AnyAccounts}" Command="{CompiledBinding AddAccountsAsync}" Header="No accounts yet. A_dd Account..." />
|
||||
<MenuItem IsVisible="{Binding !AnyAccounts}" Command="{Binding AddAccountsAsync}" Header="No accounts yet. A_dd Account..." />
|
||||
|
||||
<!-- Scan Library -->
|
||||
<MenuItem IsVisible="{CompiledBinding OneAccount}" IsEnabled="{CompiledBinding !ActivelyScanning}" Name="scanLibraryToolStripMenuItem" Command="{CompiledBinding ScanAccountAsync}" Header="Scan _Library" />
|
||||
<MenuItem IsVisible="{CompiledBinding MultipleAccounts}" IsEnabled="{CompiledBinding !ActivelyScanning}" Name="scanLibraryOfAllAccountsToolStripMenuItem" Command="{CompiledBinding ScanAllAccountsAsync}" Header="Scan Library of _All Accounts" />
|
||||
<MenuItem IsVisible="{CompiledBinding MultipleAccounts}" IsEnabled="{CompiledBinding !ActivelyScanning}" Command="{CompiledBinding ScanSomeAccountsAsync}" Header="Scan Library of _Some Accounts" />
|
||||
<MenuItem IsVisible="{Binding OneAccount}" IsEnabled="{Binding !ActivelyScanning}" Name="scanLibraryToolStripMenuItem" Command="{Binding ScanAccountAsync}" Header="Scan _Library" />
|
||||
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding !ActivelyScanning}" Name="scanLibraryOfAllAccountsToolStripMenuItem" Command="{Binding ScanAllAccountsAsync}" Header="Scan Library of _All Accounts" />
|
||||
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding !ActivelyScanning}" Command="{Binding ScanSomeAccountsAsync}" Header="Scan Library of _Some Accounts" />
|
||||
|
||||
<Separator IsVisible="{CompiledBinding AnyAccounts}" />
|
||||
<Separator IsVisible="{Binding AnyAccounts}" />
|
||||
|
||||
<!-- Remove Books -->
|
||||
<MenuItem IsVisible="{CompiledBinding OneAccount}" IsEnabled="{CompiledBinding RemoveMenuItemsEnabled}" Command="{CompiledBinding RemoveBooksAsync}" Header="_Remove Library Books" />
|
||||
<MenuItem IsVisible="{CompiledBinding MultipleAccounts}" IsEnabled="{CompiledBinding RemoveMenuItemsEnabled}" Command="{CompiledBinding RemoveBooksAllAsync}" Header="_Remove Books from All Accounts" />
|
||||
<MenuItem IsVisible="{CompiledBinding MultipleAccounts}" IsEnabled="{CompiledBinding RemoveMenuItemsEnabled}" Command="{CompiledBinding RemoveBooksSomeAsync}" Header="_Remove Books from Some Accounts" />
|
||||
<MenuItem IsVisible="{Binding OneAccount}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Command="{Binding RemoveBooksAsync}" Header="_Remove Library Books" />
|
||||
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Command="{Binding RemoveBooksAllAsync}" Header="_Remove Books from All Accounts" />
|
||||
<MenuItem IsVisible="{Binding MultipleAccounts}" IsEnabled="{Binding RemoveMenuItemsEnabled}" Command="{Binding RemoveBooksSomeAsync}" Header="_Remove Books from Some Accounts" />
|
||||
|
||||
<Separator />
|
||||
<MenuItem Command="{CompiledBinding LocateAudiobooksAsync}" Header="L_ocate Audiobooks..." ToolTip.Tip="{CompiledBinding LocateAudiobooksTip}" />
|
||||
<MenuItem Command="{Binding LocateAudiobooksAsync}" Header="L_ocate Audiobooks..." ToolTip.Tip="{Binding LocateAudiobooksTip}" />
|
||||
|
||||
</MenuItem>
|
||||
|
||||
<!-- Liberate Menu -->
|
||||
|
||||
<MenuItem Header="_Liberate">
|
||||
<MenuItem Command="{CompiledBinding BackupAllBooks}" Header="{CompiledBinding BookBackupsToolStripText}" />
|
||||
<MenuItem Command="{CompiledBinding BackupAllPdfs}" Header="{CompiledBinding PdfBackupsToolStripText}" />
|
||||
<MenuItem Command="{CompiledBinding ConvertAllToMp3Async}" Header="Convert all _M4b to Mp3 [Long-running]..." />
|
||||
<MenuItem Command="{CompiledBinding LiberateVisible}" Header="{CompiledBinding LiberateVisibleToolStripText}" IsEnabled="{CompiledBinding AnyVisibleNotLiberated}" />
|
||||
<MenuItem Command="{Binding BackupAllBooks}" Header="{Binding BookBackupsToolStripText}" />
|
||||
<MenuItem Command="{Binding BackupAllPdfs}" Header="{Binding PdfBackupsToolStripText}" />
|
||||
<MenuItem Command="{Binding ConvertAllToMp3Async}" Header="Convert all _M4b to Mp3 [Long-running]..." />
|
||||
<MenuItem Command="{Binding LiberateVisible}" Header="{Binding LiberateVisibleToolStripText}" IsEnabled="{Binding AnyVisibleNotLiberated}" />
|
||||
</MenuItem>
|
||||
|
||||
<!-- Export Menu -->
|
||||
|
||||
<MenuItem Header="E_xport">
|
||||
<!-- Remove height style property for menu item -->
|
||||
<MenuItem IsEnabled="{CompiledBinding LibraryStats.HasBookResults}" Command="{CompiledBinding ExportLibraryAsync}" Header="E_xport Library" InputGesture="ctrl+S" />
|
||||
<MenuItem IsEnabled="{Binding LibraryStats?.HasBookResults, TargetNullValue=false}" Command="{Binding ExportLibraryAsync}" Header="E_xport Library" InputGesture="ctrl+S" />
|
||||
</MenuItem>
|
||||
|
||||
<!-- Quick Filters Menu -->
|
||||
|
||||
<MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters" ItemsSource="{CompiledBinding QuickFilterMenuItems}" />
|
||||
<MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters" ItemsSource="{Binding QuickFilterMenuItems}" />
|
||||
|
||||
<!-- Visible Books Menu -->
|
||||
|
||||
<MenuItem Header="{CompiledBinding VisibleCountMenuItemText}" >
|
||||
<MenuItem Command="{CompiledBinding LiberateVisible}" Header="{CompiledBinding LiberateVisibleToolStripText_2}" IsEnabled="{CompiledBinding AnyVisibleNotLiberated}" />
|
||||
<MenuItem Command="{CompiledBinding ReplaceTagsAsync}" Header="Replace _Tags..." />
|
||||
<MenuItem Command="{CompiledBinding SetBookDownloadedAsync}" Header="Set book '_Downloaded' status manually..." />
|
||||
<MenuItem Command="{CompiledBinding SetPdfDownloadedAsync}" Header="Set _PDF 'Downloaded' status manually..." />
|
||||
<MenuItem Command="{CompiledBinding SetDownloadedAutoAsync}" Header="Set '_Downloaded' status automatically..." />
|
||||
<MenuItem Command="{CompiledBinding RemoveVisibleAsync}" Header="_Remove from library..." />
|
||||
<MenuItem Header="{Binding VisibleCountMenuItemText}" >
|
||||
<MenuItem Command="{Binding LiberateVisible}" Header="{Binding LiberateVisibleToolStripText_2}" IsEnabled="{Binding AnyVisibleNotLiberated}" />
|
||||
<MenuItem Command="{Binding ReplaceTagsAsync}" Header="Replace _Tags..." />
|
||||
<MenuItem Command="{Binding SetBookDownloadedAsync}" Header="Set book '_Downloaded' status manually..." />
|
||||
<MenuItem Command="{Binding SetPdfDownloadedAsync}" Header="Set _PDF 'Downloaded' status manually..." />
|
||||
<MenuItem Command="{Binding SetDownloadedAutoAsync}" Header="Set '_Downloaded' status automatically..." />
|
||||
<MenuItem Command="{Binding RemoveVisibleAsync}" Header="_Remove from library..." />
|
||||
</MenuItem>
|
||||
|
||||
<!-- Settings Menu -->
|
||||
|
||||
<MenuItem Header="_Settings" Name="settingsToolStripMenuItem">
|
||||
<MenuItem Name="accountsToolStripMenuItem" Command="{CompiledBinding ShowAccountsAsync}" Header="_Accounts..." InputGesture="ctrl+shift+A"/>
|
||||
<MenuItem Name="basicSettingsToolStripMenuItem" Command="{CompiledBinding ShowSettingsAsync}" Header="_Settings..." InputGesture="ctrl+P" />
|
||||
<MenuItem Name="accountsToolStripMenuItem" Command="{Binding ShowAccountsAsync}" Header="_Accounts..." InputGesture="ctrl+shift+A"/>
|
||||
<MenuItem Name="basicSettingsToolStripMenuItem" Command="{Binding ShowSettingsAsync}" Header="_Settings..." InputGesture="ctrl+P" />
|
||||
<Separator />
|
||||
<MenuItem Command="{CompiledBinding ShowTrashBinAsync}" Header="Trash Bin" />
|
||||
<MenuItem Command="{CompiledBinding LaunchHangover}" Header="Launch _Hangover" />
|
||||
<MenuItem Command="{Binding ShowTrashBinAsync}" Header="Trash Bin" />
|
||||
<MenuItem Command="{Binding LaunchHangover}" Header="Launch _Hangover" />
|
||||
<Separator />
|
||||
<MenuItem Command="{CompiledBinding ShowFindBetterQualityBooksAsync}" Header="Scan for Better Quality Audiobooks" ToolTip.Tip="{CompiledBinding FindBetterQualityBooksTip}"/>
|
||||
<MenuItem Command="{Binding ShowFindBetterQualityBooksAsync}" Header="Scan for Better Quality Audiobooks" ToolTip.Tip="{Binding FindBetterQualityBooksTip}"/>
|
||||
<Separator />
|
||||
<MenuItem Command="{CompiledBinding StartWalkthroughAsync}" Header="Take a Guided _Tour of Libation" />
|
||||
<MenuItem Command="{CompiledBinding ShowAboutAsync}" Header="A_bout..." />
|
||||
<MenuItem Command="{Binding StartWalkthroughAsync}" Header="Take a Guided _Tour of Libation" />
|
||||
<MenuItem Command="{Binding ShowAboutAsync}" Header="A_bout..." />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<StackPanel IsVisible="{CompiledBinding ActivelyScanning}" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<StackPanel IsVisible="{Binding ActivelyScanning}" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Path VerticalAlignment="Center" Fill="{DynamicResource IconFill}" Data="{StaticResource ImportIcon}" />
|
||||
<TextBlock Margin="5,0,5,0" VerticalAlignment="Center" Text="{CompiledBinding ScanningText}"/>
|
||||
<TextBlock Margin="5,0,5,0" VerticalAlignment="Center" Text="{Binding ScanningText}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
@@ -182,21 +182,21 @@
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal">
|
||||
<Button Name="filterHelpBtn" Margin="0" Command="{CompiledBinding FilterHelpBtn}" Content="?"/>
|
||||
<Button Name="addQuickFilterBtn" Command="{CompiledBinding AddQuickFilterBtn}" Content="Add To Quick Filters"/>
|
||||
<StackPanel Grid.Column="0" IsVisible="{Binding !RemoveButtonsVisible}" Orientation="Horizontal">
|
||||
<Button Name="filterHelpBtn" Margin="0" Command="{Binding FilterHelpBtn}" Content="?"/>
|
||||
<Button Name="addQuickFilterBtn" Command="{Binding AddQuickFilterBtn}" Content="Add To Quick Filters"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal">
|
||||
<Button IsVisible="{CompiledBinding RemoveButtonsVisible}" IsEnabled="{CompiledBinding RemoveBooksButtonEnabled}" Command="{CompiledBinding RemoveBooksBtn}" Content="{CompiledBinding RemoveBooksButtonText}"/>
|
||||
<Button IsVisible="{CompiledBinding RemoveButtonsVisible}" Command="{CompiledBinding DoneRemovingBtn}" Content="Done Removing Books"/>
|
||||
<Button IsVisible="{Binding RemoveButtonsVisible}" IsEnabled="{Binding RemoveBooksButtonEnabled}" Command="{Binding RemoveBooksBtn}" Content="{Binding RemoveBooksButtonText}"/>
|
||||
<Button IsVisible="{Binding RemoveButtonsVisible}" Command="{Binding DoneRemovingBtn}" Content="Done Removing Books"/>
|
||||
</StackPanel>
|
||||
|
||||
<Grid
|
||||
Grid.Column="1"
|
||||
Margin="10,0,0,0"
|
||||
ColumnDefinitions="*,Auto"
|
||||
IsVisible="{CompiledBinding !RemoveButtonsVisible}">
|
||||
IsVisible="{Binding !RemoveButtonsVisible}">
|
||||
<TextBox
|
||||
Grid.Column="0"
|
||||
Name="filterSearchTb"
|
||||
@@ -204,7 +204,7 @@
|
||||
InnerRightContent="{x:Null}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Disabled"
|
||||
Text="{CompiledBinding SelectedNamedFilter.Filter, Mode=OneWay}"
|
||||
Text="{Binding SelectedNamedFilter.Filter, Mode=OneWay}"
|
||||
KeyDown="filterSearchTb_KeyPress" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
@@ -218,11 +218,11 @@
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Column="2" Height="30" Orientation="Horizontal">
|
||||
<Button Name="filterBtn" Command="{CompiledBinding FilterBtn}" CommandParameter="{CompiledBinding #filterSearchTb.Text}" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="Filter"/>
|
||||
<Button Padding="2,6" VerticalAlignment="Stretch" Command="{CompiledBinding ToggleQueueHideBtn}">
|
||||
<Button Name="filterBtn" IsVisible="{Binding !RemoveButtonsVisible}" Command="{Binding FilterBtn}" CommandParameter="{Binding #filterSearchTb.Text}" VerticalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="Filter"/>
|
||||
<Button Padding="2,6" VerticalAlignment="Stretch" Command="{Binding ToggleQueueHideBtn}">
|
||||
<Path Stretch="Uniform" Fill="{DynamicResource IconFill}" Data="{StaticResource LeftArrows}">
|
||||
<Path.RenderTransform>
|
||||
<RotateTransform Angle="{CompiledBinding QueueButtonAngle}"/>
|
||||
<RotateTransform Angle="{Binding QueueButtonAngle}"/>
|
||||
</Path.RenderTransform>
|
||||
</Path>
|
||||
</Button>
|
||||
@@ -231,19 +231,19 @@
|
||||
</Grid>
|
||||
|
||||
<Border Grid.Row="2" Margin="8,0" BorderThickness="1" BorderBrush="{DynamicResource SystemBaseMediumLowColor}">
|
||||
<SplitView IsPaneOpen="{CompiledBinding QueueOpen}" DisplayMode="Inline" OpenPaneLength="400" MinWidth="400" PanePlacement="Right">
|
||||
<SplitView IsPaneOpen="{Binding QueueOpen}" DisplayMode="Inline" OpenPaneLength="400" MinWidth="400" PanePlacement="Right">
|
||||
|
||||
<!-- Process Queue -->
|
||||
<SplitView.Pane>
|
||||
<Border BorderThickness="1,0,0,0" BorderBrush="{DynamicResource SystemBaseMediumLowColor}">
|
||||
<views:ProcessQueueControl DataContext="{CompiledBinding ProcessQueue}"/>
|
||||
<views:ProcessQueueControl DataContext="{Binding ProcessQueue, Mode=OneTime}"/>
|
||||
</Border>
|
||||
</SplitView.Pane>
|
||||
|
||||
<!-- Product Display Grid -->
|
||||
<views:ProductsDisplay
|
||||
Name="productsDisplay"
|
||||
DataContext="{CompiledBinding ProductsDisplay}"
|
||||
DataContext="{Binding ProductsDisplay, Mode=OneTime}"
|
||||
LiberateClicked="ProductsDisplay_LiberateClicked"
|
||||
TagsButtonClicked="ProductsDisplay_TagsButtonClicked"
|
||||
LiberateSeriesClicked="ProductsDisplay_LiberateSeriesClicked"
|
||||
@@ -258,10 +258,10 @@
|
||||
<Setter Property="MinWidth" Value="100" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<TextBlock FontSize="14" Grid.Column="0" Text="Upgrading:" VerticalAlignment="Center" IsVisible="{CompiledBinding DownloadProgress, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
||||
<ProgressBar Grid.Column="1" Margin="5,0,10,0" VerticalAlignment="Stretch" Width="100" Value="{CompiledBinding DownloadProgress}" IsVisible="{CompiledBinding DownloadProgress, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||||
<TextBlock FontSize="14" Grid.Column="2" Text="{CompiledBinding VisibleCountText}" VerticalAlignment="Center" />
|
||||
<TextBlock FontSize="14" Grid.Column="3" Text="{CompiledBinding LibraryStats.StatusString}" VerticalAlignment="Center" />
|
||||
<TextBlock FontSize="14" Grid.Column="0" Text="Upgrading:" VerticalAlignment="Center" IsVisible="{Binding DownloadProgress, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
||||
<ProgressBar Grid.Column="1" Margin="5,0,10,0" VerticalAlignment="Stretch" Width="100" Value="{Binding DownloadProgress, TargetNullValue=0}" IsVisible="{Binding DownloadProgress, Converter={x:Static ObjectConverters.IsNotNull}}"/>
|
||||
<TextBlock FontSize="14" Grid.Column="2" Text="{Binding VisibleCountText}" VerticalAlignment="Center" />
|
||||
<TextBlock FontSize="14" Grid.Column="3" Text="{Binding LibraryStats?.StatusString}" VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -25,7 +25,6 @@ public partial class MainWindow : ReactiveWindow<MainVM>
|
||||
if (Design.IsDesignMode)
|
||||
Configuration.CreateMockInstance();
|
||||
|
||||
DataContext = new MainVM(this);
|
||||
ApiExtended.LoginChoiceFactory = account => Dispatcher.UIThread.Invoke(() => new Dialogs.Login.AvaloniaLoginChoiceEager(account));
|
||||
|
||||
AudibleApiStorage.LoadError += AudibleApiStorage_LoadError;
|
||||
@@ -46,6 +45,7 @@ public partial class MainWindow : ReactiveWindow<MainVM>
|
||||
|
||||
Configuration.Instance.PropertyChanged += Settings_PropertyChanged;
|
||||
Settings_PropertyChanged(this, null);
|
||||
DataContext = new MainVM(this);
|
||||
}
|
||||
|
||||
[Dinah.Core.PropertyChangeFilter(nameof(Configuration.Books))]
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="views|ProcessBookControl">
|
||||
<Setter Property="ProcessBookStatus" Value="{CompiledBinding Status}" />
|
||||
<Setter Property="ProcessBookStatus" Value="{Binding Status}" />
|
||||
<Style Selector="^[ProcessBookStatus=Cancelled]">
|
||||
<Setter Property="Background" Value="{DynamicResource ProcessQueueBookCancelledBrush}" />
|
||||
</Style>
|
||||
@@ -34,13 +34,13 @@
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
|
||||
<Panel Grid.Column="0" Margin="3" Width="80" Height="80" HorizontalAlignment="Left">
|
||||
<Image Width="80" Height="80" Source="{CompiledBinding Cover}" Stretch="Uniform" />
|
||||
<Image Width="80" Height="80" Source="{Binding Cover}" Stretch="Uniform" />
|
||||
</Panel>
|
||||
<Grid Margin="0,3,0,3" Grid.Column="1" ColumnDefinitions="*" RowDefinitions="*,16">
|
||||
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Vertical">
|
||||
<TextBlock ClipToBounds="True" TextWrapping="Wrap" FontSize="11" Text="{CompiledBinding Title}" />
|
||||
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{CompiledBinding Author}" />
|
||||
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{CompiledBinding Narrator}" />
|
||||
<TextBlock ClipToBounds="True" TextWrapping="Wrap" FontSize="11" Text="{Binding Title}" />
|
||||
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{Binding Author}" />
|
||||
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{Binding Narrator}" />
|
||||
</StackPanel>
|
||||
<Panel Grid.Column="0" Grid.Row="1">
|
||||
<Panel.Styles>
|
||||
@@ -48,8 +48,8 @@
|
||||
<Setter Property="MinWidth" Value="20" />
|
||||
</Style>
|
||||
</Panel.Styles>
|
||||
<ProgressBar IsVisible="{CompiledBinding IsDownloading}" Value="{CompiledBinding Progress}" ShowProgressText="True" FontSize="12" />
|
||||
<TextBlock IsVisible="{CompiledBinding !IsDownloading}" Text="{CompiledBinding StatusText}"/>
|
||||
<ProgressBar IsVisible="{Binding IsDownloading}" Value="{Binding Progress}" ShowProgressText="True" FontSize="12" />
|
||||
<TextBlock IsVisible="{Binding !IsDownloading}" Text="{Binding StatusText}"/>
|
||||
</Panel>
|
||||
</Grid>
|
||||
<Grid Name="ButtonsGrid" Margin="3" Grid.Column="2" HorizontalAlignment="Right" ColumnDefinitions="Auto,Auto">
|
||||
@@ -64,7 +64,7 @@
|
||||
</Style>
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<StackPanel IsVisible="{CompiledBinding Queued}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical">
|
||||
<StackPanel IsVisible="{Binding Queued}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical">
|
||||
|
||||
<Button ToolTip.Tip="Move book to top of queue" Click="MoveFirst_Click">
|
||||
<Path VerticalAlignment="Top" Data="{StaticResource FirstButtonIcon}" />
|
||||
@@ -79,14 +79,14 @@
|
||||
<Path VerticalAlignment="Bottom" Data="{StaticResource LastButtonIcon}" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<Panel Margin="3,0,0,0" Grid.Column="1" VerticalAlignment="Top" IsVisible="{CompiledBinding !IsFinished}">
|
||||
<Panel Margin="3,0,0,0" Grid.Column="1" VerticalAlignment="Top" IsVisible="{Binding !IsFinished}">
|
||||
<Button Height="32" Background="{DynamicResource CancelRed}" Width="22" CornerRadius="11" Click="Cancel_Click">
|
||||
<Path Fill="{DynamicResource SystemAltHighColor}" VerticalAlignment="Center" Data="{StaticResource CancelButtonIcon}" RenderTransform="{StaticResource Rotate45Transform}" />
|
||||
</Button>
|
||||
</Panel>
|
||||
</Grid>
|
||||
<Panel Margin="3" Width="50" Grid.Column="2">
|
||||
<TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Right" IsVisible="{CompiledBinding IsDownloading}" Text="{CompiledBinding ETA}" />
|
||||
<TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Right" IsVisible="{Binding IsDownloading}" Text="{Binding ETA}" />
|
||||
</Panel>
|
||||
|
||||
</Grid>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:views="clr-namespace:LibationAvalonia.Views"
|
||||
xmlns:viewModels="clr-namespace:LibationAvalonia.ViewModels"
|
||||
xmlns:vmbase="clr-namespace:LibationUiBase.ProcessQueue;assembly=LibationUiBase"
|
||||
x:DataType="vmbase:ProcessQueueViewModel"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="650"
|
||||
Background="{DynamicResource SystemRegionColor}"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Input.Platform;
|
||||
using Avalonia.Threading;
|
||||
using DataLayer;
|
||||
using LibationUiBase;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
ClipboardCopyMode="IncludeHeader"
|
||||
GridLinesVisibility="All"
|
||||
AutoGenerateColumns="False"
|
||||
ItemsSource="{CompiledBinding GridEntries}"
|
||||
ItemsSource="{Binding GridEntries}"
|
||||
CanUserSortColumns="True" BorderThickness="3"
|
||||
CanUserResizeColumns="True"
|
||||
LoadingRow="ProductsDisplay_LoadingRow"
|
||||
@@ -85,7 +85,7 @@
|
||||
<DataGridTemplateColumn
|
||||
CanUserSort="True"
|
||||
CanUserResize="False"
|
||||
IsVisible="{CompiledBinding RemoveColumnVisible}"
|
||||
IsVisible="{Binding RemoveColumnVisible}"
|
||||
PropertyChanged="RemoveColumn_PropertyChanged"
|
||||
Header="Remove"
|
||||
IsReadOnly="False"
|
||||
@@ -97,199 +97,255 @@
|
||||
<CheckBox
|
||||
HorizontalAlignment="Center"
|
||||
IsThreeState="True"
|
||||
IsChecked="{CompiledBinding Remove, Mode=TwoWay}" />
|
||||
IsChecked="{Binding Remove, Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<controls:DataGridTemplateColumnExt CanUserResize="False" CanUserSort="True" Header="Liberate" SortMemberPath="Liberate" ClipboardContentBinding="{Binding Liberate.ToolTip}">
|
||||
<controls:DataGridTemplateColumnExt CanUserResize="False" CanUserSort="True" Header="Liberate" SortMemberPath="Liberate">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<views:LiberateStatusButton
|
||||
ToolTip.Tip="{CompiledBinding Liberate.ToolTip}"
|
||||
BookStatus="{CompiledBinding Liberate.BookStatus}"
|
||||
PdfStatus="{CompiledBinding Liberate.PdfStatus}"
|
||||
IsUnavailable="{CompiledBinding Liberate.IsUnavailable}"
|
||||
IsSeries="{CompiledBinding Liberate.IsSeries}"
|
||||
Expanded="{CompiledBinding Liberate.Expanded}"
|
||||
ToolTip.Tip="{Binding Liberate.ToolTip}"
|
||||
BookStatus="{Binding Liberate.BookStatus}"
|
||||
PdfStatus="{Binding Liberate.PdfStatus}"
|
||||
IsUnavailable="{Binding Liberate.IsUnavailable}"
|
||||
IsSeries="{Binding Liberate.IsSeries}"
|
||||
Expanded="{Binding Liberate.Expanded}"
|
||||
Click="LiberateButton_Click" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Liberate.ToolTip" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Cover" CanUserResize="False" CanUserSort="False" SortMemberPath="Cover" ClipboardContentBinding="{Binding LibraryBook.Book.PictureLarge}">
|
||||
<controls:DataGridTemplateColumnExt Header="Cover" CanUserResize="False" CanUserSort="False" SortMemberPath="Cover">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Image Opacity="{CompiledBinding Liberate.Opacity}" Tapped="Cover_Click" Source="{CompiledBinding Cover}" ToolTip.Tip="Click to see full size" />
|
||||
<Image Opacity="{Binding Liberate.Opacity}" Tapped="Cover_Click" Source="{Binding Cover}" ToolTip.Tip="Click to see full size" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="LibraryBook.Book.PictureLarge" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Title" MinWidth="10" Width="{CompiledBinding TitleWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Title" ClipboardContentBinding="{Binding Title}">
|
||||
<controls:DataGridTemplateColumnExt Header="Title" MinWidth="10" Width="{Binding TitleWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Title">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Classes="h1" Text="{CompiledBinding Title}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Classes="h1" Text="{Binding Title}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Title" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Authors" MinWidth="10" Width="{CompiledBinding AuthorsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Authors" ClipboardContentBinding="{Binding Authors}">
|
||||
<controls:DataGridTemplateColumnExt Header="Authors" MinWidth="10" Width="{Binding AuthorsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Authors">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Authors}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Authors}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Authors" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Narrators" MinWidth="10" Width="{CompiledBinding NarratorsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Narrators" ClipboardContentBinding="{Binding Narrators}">
|
||||
<controls:DataGridTemplateColumnExt Header="Narrators" MinWidth="10" Width="{Binding NarratorsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Narrators">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Narrators}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Narrators}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Narrators" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Length" MinWidth="10" Width="{CompiledBinding LengthWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Length" ClipboardContentBinding="{Binding Length}">
|
||||
<controls:DataGridTemplateColumnExt Header="Length" MinWidth="10" Width="{Binding LengthWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Length">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Length}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Length}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Length" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Series" MinWidth="10" Width="{CompiledBinding SeriesWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Series" ClipboardContentBinding="{Binding Series}">
|
||||
<controls:DataGridTemplateColumnExt Header="Series" MinWidth="10" Width="{Binding SeriesWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Series">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Series}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Series}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Series" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Series
Order" MinWidth="10" Width="{CompiledBinding SeriesOrderWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="SeriesOrder" ClipboardContentBinding="{Binding Series}">
|
||||
<controls:DataGridTemplateColumnExt Header="Series
Order" MinWidth="10" Width="{Binding SeriesOrderWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="SeriesOrder">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding SeriesOrder}" HorizontalAlignment="Center" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding SeriesOrder}" HorizontalAlignment="Center" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="SeriesOrder" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Description" MinWidth="10" Width="{CompiledBinding DescriptionWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Description" ClipboardContentBinding="{Binding Description}">
|
||||
<controls:DataGridTemplateColumnExt Header="Description" MinWidth="10" Width="{Binding DescriptionWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Description">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}" Tapped="Description_Click" ToolTip.Tip="Click to see full description" >
|
||||
<TextBlock Text="{CompiledBinding Description}" VerticalAlignment="Top" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}" Tapped="Description_Click" ToolTip.Tip="Click to see full description" >
|
||||
<TextBlock Text="{Binding Description}" VerticalAlignment="Top" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Description" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Category" MinWidth="10" Width="{CompiledBinding CategoryWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Category" ClipboardContentBinding="{Binding Category}">
|
||||
<controls:DataGridTemplateColumnExt Header="Category" MinWidth="10" Width="{Binding CategoryWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Category">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Category}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Category}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Category" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridMyRatingColumn
|
||||
x:DataType="uibase:GridEntry"
|
||||
Header="Product
Rating"
|
||||
IsReadOnly="true"
|
||||
MinWidth="10" Width="{Binding ProductRatingWidth, Mode=TwoWay}"
|
||||
MinWidth="10"
|
||||
SortMemberPath="ProductRating" CanUserSort="True"
|
||||
OpacityBinding="{CompiledBinding Liberate.Opacity}"
|
||||
ClipboardContentBinding="{CompiledBinding ProductRating}"
|
||||
Binding="{CompiledBinding ProductRating}" />
|
||||
OpacityBinding="{Binding Liberate.Opacity}"
|
||||
ClipboardContentBinding="{Binding ProductRating}"
|
||||
Binding="{Binding ProductRating}">
|
||||
<controls:DataGridMyRatingColumn.Width>
|
||||
<Binding x:DataType="vm:ProductsDisplayViewModel" Path="ProductRatingWidth" Mode="TwoWay" />
|
||||
</controls:DataGridMyRatingColumn.Width>
|
||||
</controls:DataGridMyRatingColumn>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Purchase
Date" MinWidth="10" Width="{CompiledBinding PurchaseDateWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="PurchaseDate" ClipboardContentBinding="{Binding PurchaseDate}">
|
||||
<controls:DataGridTemplateColumnExt Header="Purchase
Date" MinWidth="10" Width="{Binding PurchaseDateWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="PurchaseDate">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding PurchaseDate}" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding PurchaseDate}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="PurchaseDate" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridMyRatingColumn
|
||||
x:DataType="uibase:GridEntry"
|
||||
Header="My Rating"
|
||||
IsReadOnly="false"
|
||||
MinWidth="10" Width="{Binding MyRatingWidth, Mode=TwoWay}"
|
||||
MinWidth="10"
|
||||
SortMemberPath="MyRating" CanUserSort="True"
|
||||
OpacityBinding="{CompiledBinding Liberate.Opacity}"
|
||||
ClipboardContentBinding="{CompiledBinding MyRating}"
|
||||
Binding="{CompiledBinding MyRating, Mode=TwoWay}" />
|
||||
OpacityBinding="{Binding Liberate.Opacity}"
|
||||
ClipboardContentBinding="{Binding MyRating}"
|
||||
Binding="{Binding MyRating, Mode=TwoWay}">
|
||||
<controls:DataGridMyRatingColumn.Width>
|
||||
<Binding x:DataType="vm:ProductsDisplayViewModel" Path="MyRatingWidth" Mode="TwoWay" />
|
||||
</controls:DataGridMyRatingColumn.Width>
|
||||
</controls:DataGridMyRatingColumn>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Misc" MinWidth="10" Width="{CompiledBinding MiscWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Misc" ClipboardContentBinding="{Binding Misc}">
|
||||
<controls:DataGridTemplateColumnExt Header="Misc" MinWidth="10" Width="{Binding MiscWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Misc">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Misc}" TextWrapping="WrapWithOverflow" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Misc}" TextWrapping="WrapWithOverflow" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Misc" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Included
Until" MinWidth="10" Width="{CompiledBinding IncludedUntilWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="IncludedUntil" ClipboardContentBinding="{Binding IncludedUntil}">
|
||||
<controls:DataGridTemplateColumnExt Header="Included
Until" MinWidth="10" Width="{Binding IncludedUntilWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="IncludedUntil">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding IncludedUntil}" TextWrapping="WrapWithOverflow" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding IncludedUntil}" TextWrapping="WrapWithOverflow" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="IncludedUntil" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Last
Download" MinWidth="10" Width="{CompiledBinding LastDownloadWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="LastDownload" ClipboardContentBinding="{Binding LastDownload}">
|
||||
<controls:DataGridTemplateColumnExt Header="Last
Download" MinWidth="10" Width="{Binding LastDownloadWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="LastDownload">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}" ToolTip.Tip="{CompiledBinding LastDownload.ToolTipText}" DoubleTapped="Version_DoubleClick">
|
||||
<TextBlock Text="{CompiledBinding LastDownload}" TextWrapping="WrapWithOverflow" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}" ToolTip.Tip="{Binding LastDownload.ToolTipText}" DoubleTapped="Version_DoubleClick">
|
||||
<TextBlock Text="{Binding LastDownload}" TextWrapping="WrapWithOverflow" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="LastDownload" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Is
Spatial" MinWidth="10" Width="{CompiledBinding IsSpatialWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="IsSpatial" ClipboardContentBinding="{Binding IsSpatial}">
|
||||
<controls:DataGridTemplateColumnExt Header="Is
Spatial" MinWidth="10" Width="{Binding IsSpatialWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="IsSpatial">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<CheckBox IsChecked="{CompiledBinding IsSpatial}" IsEnabled="False" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<CheckBox IsChecked="{Binding IsSpatial}" IsEnabled="False" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="IsSpatial" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Account" MinWidth="10" Width="{CompiledBinding AccountWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Account" ClipboardContentBinding="{Binding Account}">
|
||||
<controls:DataGridTemplateColumnExt Header="Account" MinWidth="10" Width="{Binding AccountWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="Account">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Panel Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
<TextBlock Text="{CompiledBinding Account}" TextWrapping="Wrap" />
|
||||
<Panel Opacity="{Binding Liberate.Opacity}">
|
||||
<TextBlock Text="{Binding Account}" TextWrapping="Wrap" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="Account" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
<controls:DataGridTemplateColumnExt Header="Tags" MinWidth="10" Width="{CompiledBinding BookTagsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="BookTags" ClipboardContentBinding="{Binding BookTags}">
|
||||
<controls:DataGridTemplateColumnExt Header="Tags" MinWidth="10" Width="{Binding BookTagsWidth, Mode=TwoWay}" CanUserSort="True" SortMemberPath="BookTags">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate x:DataType="uibase:GridEntry">
|
||||
<Button
|
||||
IsVisible="{CompiledBinding !Liberate.IsSeries}"
|
||||
IsVisible="{Binding !Liberate.IsSeries}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalContentAlignment="Stretch"
|
||||
@@ -298,23 +354,26 @@
|
||||
ToolTip.Tip="Click to edit tags">
|
||||
<Grid
|
||||
RowDefinitions="*,*,*"
|
||||
Opacity="{CompiledBinding Liberate.Opacity}">
|
||||
Opacity="{Binding Liberate.Opacity}">
|
||||
<Viewbox
|
||||
Grid.Row="1"
|
||||
Stretch="Uniform"
|
||||
IsVisible="{CompiledBinding BookTags, Converter={x:Static StringConverters.IsNullOrEmpty}}">
|
||||
IsVisible="{Binding BookTags, Converter={x:Static StringConverters.IsNullOrEmpty}}">
|
||||
|
||||
<Path Fill="{DynamicResource IconFill}" Data="{StaticResource EditTagsIcon}" />
|
||||
</Viewbox>
|
||||
<TextBlock
|
||||
Classes="h2"
|
||||
Grid.RowSpan="3"
|
||||
IsVisible="{CompiledBinding BookTags, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" TextWrapping="WrapWithOverflow" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{CompiledBinding BookTags}"/>
|
||||
IsVisible="{Binding BookTags, Converter={x:Static StringConverters.IsNotNullOrEmpty}}" TextWrapping="WrapWithOverflow" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding BookTags}"/>
|
||||
|
||||
</Grid>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
<controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
<Binding x:DataType="uibase:GridEntry" Path="BookTags" />
|
||||
</controls:DataGridTemplateColumnExt.ClipboardContentBinding>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
</DataGrid.Columns>
|
||||
|
||||
@@ -33,10 +33,10 @@ public partial class ProductsDisplay : UserControl
|
||||
|
||||
|
||||
public static readonly StyledProperty<bool> DisableContextMenuProperty =
|
||||
AvaloniaProperty.Register<GroupBox, bool>(nameof(DisableContextMenu));
|
||||
AvaloniaProperty.Register<Controls.GroupBox, bool>(nameof(DisableContextMenu));
|
||||
|
||||
public static readonly StyledProperty<bool> DisableColumnCustomizationProperty =
|
||||
AvaloniaProperty.Register<GroupBox, bool>(nameof(DisableColumnCustomization));
|
||||
AvaloniaProperty.Register<Controls.GroupBox, bool>(nameof(DisableColumnCustomization));
|
||||
|
||||
public bool DisableContextMenu
|
||||
{
|
||||
@@ -495,7 +495,7 @@ public partial class ProductsDisplay : UserControl
|
||||
#endregion
|
||||
#region View Bookmarks/Clips (Single book only)
|
||||
|
||||
if (entries.Length == 1 && entries[0] is LibraryBookEntry entry3 && VisualRoot is Window window)
|
||||
if (entries.Length == 1 && entries[0] is LibraryBookEntry entry3 && this.GetParentWindow() is Window window)
|
||||
{
|
||||
args.ContextMenuItems.Add(new MenuItem
|
||||
{
|
||||
@@ -658,7 +658,7 @@ public partial class ProductsDisplay : UserControl
|
||||
var pictureId = gEntry.LibraryBook.Book.PictureLarge ?? gEntry.LibraryBook.Book.PictureId;
|
||||
if (string.IsNullOrEmpty(pictureId))
|
||||
{
|
||||
await MessageBox.Show(VisualRoot as Window, "No cover art is available for this book.", "No Cover Art", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
await MessageBox.Show(this.GetParentWindow(), "No cover art is available for this book.", "No Cover Art", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:local="clr-namespace:LibationAvalonia.Views"
|
||||
x:Class="LibationAvalonia.Views.SeriesViewDialog"
|
||||
x:DataType="local:SeriesViewDialog"
|
||||
Title="View All Items in Series">
|
||||
|
||||
<TabControl
|
||||
ItemsSource="{Binding TabItems}"
|
||||
ItemsSource="{Binding TabItems}"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalAlignment="Stretch">
|
||||
<TabControl.Styles>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
xmlns:local="clr-namespace:LibationAvalonia.Views"
|
||||
x:DataType="local:SeriesViewGrid"
|
||||
xmlns:uibase="clr-namespace:LibationUiBase.SeriesView;assembly=LibationUiBase"
|
||||
x:Class="LibationAvalonia.Views.SeriesViewGrid">
|
||||
|
||||
@@ -39,7 +41,7 @@
|
||||
<Image
|
||||
Tapped="Cover_Click"
|
||||
Height="80"
|
||||
Source="{CompiledBinding Cover}"
|
||||
Source="{Binding Cover}"
|
||||
ToolTip.Tip="Click to see full size" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
@@ -50,7 +52,7 @@
|
||||
<DataTemplate x:DataType="uibase:SeriesItem">
|
||||
<Panel>
|
||||
<TextBlock
|
||||
Text="{CompiledBinding Order}"
|
||||
Text="{Binding Order}"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Panel>
|
||||
@@ -72,17 +74,17 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Click="Availability_Click"
|
||||
IsVisible="{CompiledBinding Button.HasButtonAction}"
|
||||
IsEnabled="{CompiledBinding Button.Enabled}">
|
||||
IsVisible="{Binding Button.HasButtonAction}"
|
||||
IsEnabled="{Binding Button.Enabled}">
|
||||
<TextBlock
|
||||
Text="{CompiledBinding Button.DisplayText}"
|
||||
Text="{Binding Button.DisplayText}"
|
||||
TextAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Button>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
IsVisible="{CompiledBinding !Button.HasButtonAction}"
|
||||
Text="{CompiledBinding Button.DisplayText}" />
|
||||
IsVisible="{Binding !Button.HasButtonAction}"
|
||||
Text="{Binding Button.DisplayText}" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
@@ -94,7 +96,7 @@
|
||||
<Panel ToolTip.Tip="Open Audible product page">
|
||||
<controls:LinkLabel
|
||||
VerticalAlignment="Center"
|
||||
Text="{CompiledBinding Title}"
|
||||
Text="{Binding Title}"
|
||||
Tapped="Title_Click" />
|
||||
</Panel>
|
||||
</DataTemplate>
|
||||
|
||||
@@ -60,7 +60,7 @@ public partial class SeriesViewGrid : UserControl
|
||||
var pictureId = libraryBook.PictureLarge ?? libraryBook.PictureId;
|
||||
if (string.IsNullOrEmpty(pictureId))
|
||||
{
|
||||
await MessageBox.Show(VisualRoot as Window, "No cover art is available for this book.", "No Cover Art", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
await MessageBox.Show(this.GetParentWindow(), "No cover art is available for this book.", "No Cover Art", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AudibleApi" Version="10.1.5.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.7" />
|
||||
<PackageReference Include="NameParserSharp" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -3,7 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using FileManager.NamingTemplate;
|
||||
|
||||
namespace LibationFileManager.Templates;
|
||||
namespace LibationFileManager.Templates;
|
||||
|
||||
public class ContributorDto(string name, string? audibleContributorId) : IFormattable
|
||||
{
|
||||
|
||||
@@ -48,9 +48,9 @@ public record CultureInfoDto : IFormattable
|
||||
{
|
||||
var cultures = CultureInfo.GetCultures(types);
|
||||
return Match(cultures, input, c => c.Name) ??
|
||||
Match(cultures, input, c => c.TwoLetterISOLanguageName) ??
|
||||
Match(cultures, input, c => c.ThreeLetterISOLanguageName) ??
|
||||
Match(cultures, input, c => c.EnglishName);
|
||||
Match(cultures, input, c => c.TwoLetterISOLanguageName) ??
|
||||
Match(cultures, input, c => c.ThreeLetterISOLanguageName) ??
|
||||
Match(cultures, input, c => c.EnglishName);
|
||||
}
|
||||
|
||||
private static CultureInfo? Match(IEnumerable<CultureInfo> cultures, string input, Func<CultureInfo, string?> selector, StringComparison cmp = StringComparison.OrdinalIgnoreCase)
|
||||
|
||||
@@ -368,7 +368,7 @@ public abstract partial class Templates
|
||||
{
|
||||
return intVal;
|
||||
}
|
||||
|
||||
|
||||
// then check for property tags and retrieve their value
|
||||
foreach (var c in allPropertyTags.OfType<PropertyTagCollection<LibraryBookDto>>())
|
||||
{
|
||||
|
||||
@@ -8,20 +8,20 @@ public static class WindowsDirectory
|
||||
const int FolderIconMaxAttempts = 5;
|
||||
|
||||
public static void SetCoverAsFolderIcon(string? pictureId, string directory, CancellationToken cancellationToken)
|
||||
{
|
||||
//Currently only works for Windows and macOS
|
||||
if (!Configuration.Instance.UseCoverAsFolderIcon)
|
||||
{
|
||||
//Currently only works for Windows and macOS
|
||||
if (!Configuration.Instance.UseCoverAsFolderIcon)
|
||||
return;
|
||||
if (string.IsNullOrEmpty(pictureId))
|
||||
{
|
||||
Serilog.Log.Logger.Warning("No picture ID provided to set cover art as folder icon. {@DebugInfo}", new { directory });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load JPEG bytes from Images cache (or download). Prefer bytes → ICO so we never depend on a
|
||||
// path that might not exist when Amazon omits Content-Length or another downloader left a stale cache entry.
|
||||
// Load JPEG bytes from Images cache (or download). Prefer bytes → ICO so we never depend on a
|
||||
// path that might not exist when Amazon omits Content-Length or another downloader left a stale cache entry.
|
||||
|
||||
for (var attempt = 1; attempt <= FolderIconMaxAttempts; attempt++)
|
||||
for (var attempt = 1; attempt <= FolderIconMaxAttempts; attempt++)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ public class SearchEngine
|
||||
// Corruption (e.g. checksum mismatch in segments) is not fixed by waiting; clear and rebuild immediately.
|
||||
var corruptRebuildAttemptsRemaining = 2;
|
||||
|
||||
// Exponential backoff retry: 400 ms, 800 ms, 1600 ms, etc
|
||||
// Exponential backoff retry: 400 ms, 800 ms, 1600 ms, etc
|
||||
// Total wait time before giving up: 12.4 sec
|
||||
for (var attempt = 0; attempt < maxRetries; attempt++)
|
||||
for (var attempt = 0; attempt < maxRetries; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -118,13 +118,13 @@ public class SearchEngine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lucene 3 parses <c>segments_*</c> filenames in the index directory. Cloud sync (e.g. OneDrive) can leave debris
|
||||
/// or conflict copies whose names break that parser, throwing <see cref="ArgumentException"/> with this message shape.
|
||||
/// Actual error is likely to be something like: Invalid or unsupported character in number, hence this string check.
|
||||
/// <see cref="CorruptIndexException"/> (e.g. checksum mismatch in segments) is also recoverable by deleting the index and rebuilding.
|
||||
/// </summary>
|
||||
public static bool IsRecoverableCorruptIndexException(Exception ex)
|
||||
/// <summary>
|
||||
/// Lucene 3 parses <c>segments_*</c> filenames in the index directory. Cloud sync (e.g. OneDrive) can leave debris
|
||||
/// or conflict copies whose names break that parser, throwing <see cref="ArgumentException"/> with this message shape.
|
||||
/// Actual error is likely to be something like: Invalid or unsupported character in number, hence this string check.
|
||||
/// <see cref="CorruptIndexException"/> (e.g. checksum mismatch in segments) is also recoverable by deleting the index and rebuilding.
|
||||
/// </summary>
|
||||
public static bool IsRecoverableCorruptIndexException(Exception ex)
|
||||
=> ex is CorruptIndexException
|
||||
|| (ex is ArgumentException aex && aex.Message.Contains("character in number", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="10.0.0.1" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3719.77" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3912.50" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest.TestFramework" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -321,7 +321,7 @@ public class CommonFormattersTests
|
||||
// THEN
|
||||
Assert.AreEqual(expected, unescaped);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class TestClass
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -74,7 +74,7 @@ public class FormatSearchQuery
|
||||
public void FormattingTest(string input, string output)
|
||||
{
|
||||
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
|
||||
|
||||
|
||||
using var analyzer = new StandardAnalyzer(SearchEngine.Version);
|
||||
|
||||
QuerySanitizer.Sanitize(input, analyzer).Should().Be(output);
|
||||
|
||||
@@ -3,28 +3,28 @@
|
||||
[TestClass]
|
||||
public class ExceptionDisplayTests
|
||||
{
|
||||
/// <summary>Outer exception with a fixed <see cref="Exception.StackTrace"/> so golden-string tests are stable.</summary>
|
||||
private sealed class ExceptionWithFixedStack : Exception
|
||||
{
|
||||
private string _fixedStack { get; }
|
||||
public ExceptionWithFixedStack(string message, Exception? innerException, string fixedStack)
|
||||
: base(message, innerException) => _fixedStack = fixedStack;
|
||||
public override string? StackTrace => _fixedStack;
|
||||
}
|
||||
/// <summary>Outer exception with a fixed <see cref="Exception.StackTrace"/> so golden-string tests are stable.</summary>
|
||||
private sealed class ExceptionWithFixedStack : Exception
|
||||
{
|
||||
private string _fixedStack { get; }
|
||||
public ExceptionWithFixedStack(string message, Exception? innerException, string fixedStack)
|
||||
: base(message, innerException) => _fixedStack = fixedStack;
|
||||
public override string? StackTrace => _fixedStack;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Golden output for <see cref="ExceptionDisplay.FormatMessageAndStackTrace"/> when there are fourteen
|
||||
/// <see cref="Exception.InnerException"/> links (fifteen messages: outer L0 … deepest L14): first ten inners,
|
||||
/// two omitted (L11–L12), then the two deepest (L13–L14), then the outer stack trace.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void _FullText_14Levels()
|
||||
{
|
||||
const string stack = "<<GOLDEN-TEST-STACK-TRACE>>";
|
||||
var messages = Enumerable.Range(0, 15).Select(i => $"L{i}").ToArray();
|
||||
var ex = CreateChainWithFixedStack(stack, messages);
|
||||
/// <summary>
|
||||
/// Golden output for <see cref="ExceptionDisplay.FormatMessageAndStackTrace"/> when there are fourteen
|
||||
/// <see cref="Exception.InnerException"/> links (fifteen messages: outer L0 … deepest L14): first ten inners,
|
||||
/// two omitted (L11–L12), then the two deepest (L13–L14), then the outer stack trace.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void _FullText_14Levels()
|
||||
{
|
||||
const string stack = "<<GOLDEN-TEST-STACK-TRACE>>";
|
||||
var messages = Enumerable.Range(0, 15).Select(i => $"L{i}").ToArray();
|
||||
var ex = CreateChainWithFixedStack(stack, messages);
|
||||
|
||||
const string expected = """
|
||||
const string expected = """
|
||||
L0
|
||||
|
||||
Inner exception: L1
|
||||
@@ -55,129 +55,129 @@ Inner exception: L14
|
||||
|
||||
<<GOLDEN-TEST-STACK-TRACE>>
|
||||
""";
|
||||
Assert.AreEqual(expected.ReplaceLineEndings("\n"), Format(ex));
|
||||
}
|
||||
Assert.AreEqual(expected.ReplaceLineEndings("\n"), Format(ex));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="CreateChain"/>
|
||||
/// <remarks>Same chain shape as <see cref="CreateChain"/>, but the outer exception reports <paramref name="stackTrace"/> from <see cref="Exception.StackTrace"/>.</remarks>
|
||||
private static Exception CreateChainWithFixedStack(string stackTrace, params string[] messages)
|
||||
{
|
||||
if (messages.Length == 0)
|
||||
throw new ArgumentException("At least one message is required.", nameof(messages));
|
||||
/// <inheritdoc cref="CreateChain"/>
|
||||
/// <remarks>Same chain shape as <see cref="CreateChain"/>, but the outer exception reports <paramref name="stackTrace"/> from <see cref="Exception.StackTrace"/>.</remarks>
|
||||
private static Exception CreateChainWithFixedStack(string stackTrace, params string[] messages)
|
||||
{
|
||||
if (messages.Length == 0)
|
||||
throw new ArgumentException("At least one message is required.", nameof(messages));
|
||||
|
||||
var innermost = new Exception(messages[^1]);
|
||||
for (var i = messages.Length - 2; i >= 1; i--)
|
||||
innermost = new Exception(messages[i], innermost);
|
||||
return new ExceptionWithFixedStack(messages[0], innermost, stackTrace);
|
||||
}
|
||||
var innermost = new Exception(messages[^1]);
|
||||
for (var i = messages.Length - 2; i >= 1; i--)
|
||||
innermost = new Exception(messages[i], innermost);
|
||||
return new ExceptionWithFixedStack(messages[0], innermost, stackTrace);
|
||||
}
|
||||
|
||||
/// <summary>messages[0] = outer; each following string is the next <see cref="Exception.InnerException"/> message.</summary>
|
||||
private static Exception CreateChain(params string[] messages)
|
||||
{
|
||||
if (messages.Length == 0)
|
||||
throw new ArgumentException("At least one message is required.", nameof(messages));
|
||||
/// <summary>messages[0] = outer; each following string is the next <see cref="Exception.InnerException"/> message.</summary>
|
||||
private static Exception CreateChain(params string[] messages)
|
||||
{
|
||||
if (messages.Length == 0)
|
||||
throw new ArgumentException("At least one message is required.", nameof(messages));
|
||||
|
||||
var innermost = new Exception(messages[^1]);
|
||||
for (var i = messages.Length - 2; i >= 0; i--)
|
||||
innermost = new Exception(messages[i], innermost);
|
||||
return innermost;
|
||||
}
|
||||
var innermost = new Exception(messages[^1]);
|
||||
for (var i = messages.Length - 2; i >= 0; i--)
|
||||
innermost = new Exception(messages[i], innermost);
|
||||
return innermost;
|
||||
}
|
||||
|
||||
private static string Format(Exception ex) => ExceptionDisplay.FormatMessageAndStackTrace(ex).ReplaceLineEndings("\n");
|
||||
private static string Format(Exception ex) => ExceptionDisplay.FormatMessageAndStackTrace(ex).ReplaceLineEndings("\n");
|
||||
|
||||
[TestMethod]
|
||||
public void NoInnerException_ContainsOuterMessageAndStack()
|
||||
{
|
||||
var ex = new Exception("outer only");
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void NoInnerException_ContainsOuterMessageAndStack()
|
||||
{
|
||||
var ex = new Exception("outer only");
|
||||
var text = Format(ex);
|
||||
|
||||
Assert.StartsWith("outer only\n", text);
|
||||
Assert.IsFalse(text.Contains("Inner exception:", StringComparison.Ordinal));
|
||||
if (ex.StackTrace is not null)
|
||||
Assert.IsTrue(text.Contains(ex.StackTrace, StringComparison.Ordinal));
|
||||
}
|
||||
Assert.StartsWith("outer only\n", text);
|
||||
Assert.IsFalse(text.Contains("Inner exception:", StringComparison.Ordinal));
|
||||
if (ex.StackTrace is not null)
|
||||
Assert.IsTrue(text.Contains(ex.StackTrace, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void OneInner_ShowsInnerLine()
|
||||
{
|
||||
var ex = CreateChain("outer", "inner-a");
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void OneInner_ShowsInnerLine()
|
||||
{
|
||||
var ex = CreateChain("outer", "inner-a");
|
||||
var text = Format(ex);
|
||||
|
||||
var expectedHead = """
|
||||
var expectedHead = """
|
||||
outer
|
||||
|
||||
Inner exception: inner-a
|
||||
|
||||
|
||||
""".ReplaceLineEndings("\n");
|
||||
Assert.AreEqual(expectedHead + ex.StackTrace, text);
|
||||
}
|
||||
Assert.AreEqual(expectedHead + ex.StackTrace, text);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TenInners_ShowsAllTen()
|
||||
{
|
||||
var messages = new[] { "m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10" };
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void TenInners_ShowsAllTen()
|
||||
{
|
||||
var messages = new[] { "m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10" };
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: m{i}\n", StringComparison.Ordinal), $"missing inner m{i}");
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: m{i}\n", StringComparison.Ordinal), $"missing inner m{i}");
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ElevenInners_FirstTenThenDeepestOnly_NoOmitLine()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 12).Select(i => $"n{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void ElevenInners_FirstTenThenDeepestOnly_NoOmitLine()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 12).Select(i => $"n{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: n{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.IsTrue(text.Contains("Inner exception: n11\n", StringComparison.Ordinal));
|
||||
}
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: n{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.IsTrue(text.Contains("Inner exception: n11\n", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TwelveInners_FirstTenThenLastTwo_NoOmitLine()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 13).Select(i => $"p{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void TwelveInners_FirstTenThenLastTwo_NoOmitLine()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 13).Select(i => $"p{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: p{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.IsTrue(text.Contains("Inner exception: p11\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("Inner exception: p12\n", StringComparison.Ordinal));
|
||||
}
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: p{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("omitted", StringComparison.OrdinalIgnoreCase));
|
||||
Assert.IsTrue(text.Contains("Inner exception: p11\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("Inner exception: p12\n", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ThirteenInners_FirstTen_OmitOne_ThenLastTwo()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 14).Select(i => $"q{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void ThirteenInners_FirstTen_OmitOne_ThenLastTwo()
|
||||
{
|
||||
var messages = Enumerable.Range(0, 14).Select(i => $"q{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: q{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("1 inner exception omitted.\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("Inner exception: q11\n", StringComparison.Ordinal), "omitted inner should not appear");
|
||||
Assert.IsTrue(text.Contains("Inner exception: q12\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("Inner exception: q13\n", StringComparison.Ordinal));
|
||||
}
|
||||
for (var i = 1; i <= 10; i++)
|
||||
Assert.IsTrue(text.Contains($"Inner exception: q{i}\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("1 inner exception omitted.\n", StringComparison.Ordinal));
|
||||
Assert.IsFalse(text.Contains("Inner exception: q11\n", StringComparison.Ordinal), "omitted inner should not appear");
|
||||
Assert.IsTrue(text.Contains("Inner exception: q12\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains("Inner exception: q13\n", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ManyInners_OmitCountPlural()
|
||||
{
|
||||
var depth = 20;
|
||||
var messages = Enumerable.Range(0, depth + 1).Select(i => $"x{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
[TestMethod]
|
||||
public void ManyInners_OmitCountPlural()
|
||||
{
|
||||
var depth = 20;
|
||||
var messages = Enumerable.Range(0, depth + 1).Select(i => $"x{i}").ToArray();
|
||||
var ex = CreateChain(messages);
|
||||
var text = Format(ex);
|
||||
|
||||
var omitted = depth - 10 - 2;
|
||||
Assert.IsTrue(text.Contains($"{omitted} inner exceptions omitted.\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains($"Inner exception: x{depth - 1}\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains($"Inner exception: x{depth}\n", StringComparison.Ordinal));
|
||||
}
|
||||
var omitted = depth - 10 - 2;
|
||||
Assert.IsTrue(text.Contains($"{omitted} inner exceptions omitted.\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains($"Inner exception: x{depth - 1}\n", StringComparison.Ordinal));
|
||||
Assert.IsTrue(text.Contains($"Inner exception: x{depth}\n", StringComparison.Ordinal));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest" Version="4.1.0" />
|
||||
<PackageReference Include="MSTest" Version="4.2.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user