Compare commits

...

38 Commits

Author SHA1 Message Date
Robert McRackan
e61418c677 upgrade download bugfix 2021-07-18 16:29:31 -04:00
Robert McRackan
491aa67a81 add thread safety 2021-07-18 10:44:54 -04:00
Robert McRackan
7b3c857042 unsafe migration helper: Get => TryGet 2021-07-17 08:13:23 -04:00
Robert McRackan
71617b9620 Added UNSAFE_MigrationHelper to help with upgrades 2021-07-16 23:06:59 -04:00
Robert McRackan
f94f66da94 Revamped advanced settings dialog to use new control 2021-07-16 17:02:21 -04:00
Robert McRackan
2243e2a124 Get rid of meta directories. Centralize directory logic. New UI component to revamp settings and installation 2021-07-16 16:21:02 -04:00
Robert McRackan
5d6e3ea3f3 cancel buttons should set dialog result to Cancel 2021-07-15 17:14:45 -04:00
Robert McRackan
3c1c718bc7 don't attempt to overwrite advanced settings file if contents are unchanged 2021-07-15 17:14:20 -04:00
Robert McRackan
20a9e4b651 Simple winforms work in modern .net core designer. Only keep edge cases which work best in .net framework designer 2021-07-15 14:43:10 -04:00
Robert McRackan
f0daa12bb7 Remove unused interfaces and param 2021-07-15 11:48:52 -04:00
rmcrackan
c6e1278e42 Merge pull request #54 from Mbucari/master
Added Mp3 support to AAXClean.
2021-07-15 08:15:43 -04:00
Michael Bucari-Tovo
f5e8e4cd7f Removed indeterminate progress bar because decryption stattup time is now insignificant. 2021-07-15 00:17:59 -06:00
Michael Bucari-Tovo
f986462809 Changed default output type to Mp4a. 2021-07-14 23:58:52 -06:00
Michael Bucari-Tovo
49f2112c42 Updated for new AAXClean pattern. 2021-07-14 23:52:46 -06:00
Robert McRackan
0ce4faaf29 - Improved debugging for login
- Add warning when in Verbose logging mode
- Settings: don't try to re-save settings which haven't changed
- Remove unused logging config
2021-07-14 15:51:29 -04:00
Robert McRackan
bfd494cf93 remove unused setting 2021-07-13 14:59:55 -04:00
Robert McRackan
dc7ec3b328 auto-gened files 2021-07-13 14:59:41 -04:00
Robert McRackan
8f2827108b update gitignore 2021-07-13 07:14:32 -04:00
rmcrackan
fdcaf5e534 Merge pull request #53 from Mbucari/master
Removed Ffmpeg and taglib. Updated AAXClean.
2021-07-13 06:56:29 -04:00
Michael Bucari-Tovo
732695c019 Handle possible corrupt partial download. 2021-07-12 23:27:58 -06:00
Michael Bucari-Tovo
2a2faf6f7b Use new AAXClean.AaxFile type and remove unused dependences. 2021-07-12 23:13:18 -06:00
rmcrackan
c653e17c3d Merge pull request #52 from Mbucari/master
Minor fix.
2021-07-11 22:47:01 -04:00
Michael Bucari-Tovo
833bc3a8f2 Merge branch 'master' of https://github.com/Mbucari/Libation 2021-07-11 15:18:53 -06:00
Michael Bucari-Tovo
11e63ae5a2 Minor fix. 2021-07-11 15:18:07 -06:00
Robert McRackan
827eaefd29 Decryption moved to external project: AAXClean 2021-07-11 12:26:04 -04:00
rmcrackan
8240a97f6d Merge pull request #51 from Mbucari/master
Replaced FFMpeg decryptor and taglib with AAXClean
2021-07-11 12:14:15 -04:00
Mbucari
b766e43656 Merge branch 'master' into master 2021-07-11 09:17:07 -06:00
Robert McRackan
7d805728cb Login cvf bug fix 2021-07-11 09:51:39 -04:00
Michael Bucari-Tovo
c3c8a6fa6b Replaced FFMpeg decryptor and taglib with AAXClean 2021-07-10 20:21:28 -06:00
Robert McRackan
f40df002a2 Begin session logging with form feed 2021-07-09 11:34:20 -04:00
Robert McRackan
3180ea993c Startup logging: which logging levels are enabled 2021-07-09 11:06:57 -04:00
Robert McRackan
9f2fd54018 It helps if you wire-up the event. D'oh! 2021-07-09 10:20:46 -04:00
Robert McRackan
07532f7e65 "check for update" should not include pre-releases 2021-07-08 21:00:36 -04:00
Robert McRackan
4bae07d36c debugging added 2021-07-08 20:43:14 -04:00
Robert McRackan
bf23503d67 Added MFA-choice log in. Seems to come up more with German users 2021-07-08 17:04:11 -04:00
Robert McRackan
aeeba0d567 update ver. api bug fix 2021-07-08 10:54:38 -04:00
Robert McRackan
e2f919d625 "approval needed" ui improved wording 2021-07-07 21:34:05 -04:00
Robert McRackan
e821eea333 Bug: fix "approval" login step 2021-07-07 15:53:47 -04:00
109 changed files with 1929 additions and 4706 deletions

72
.gitignore vendored
View File

@@ -4,6 +4,7 @@
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
@@ -12,6 +13,9 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -19,10 +23,15 @@
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -36,9 +45,10 @@ Generated\ Files/
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
@@ -52,7 +62,9 @@ BenchmarkDotNet.Artifacts/
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
@@ -60,7 +72,7 @@ StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*_h.h
*.ilk
*.meta
*.obj
@@ -77,6 +89,7 @@ StyleCopReport.xml
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
@@ -119,9 +132,6 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
@@ -132,6 +142,11 @@ _TeamCity*
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
@@ -179,6 +194,8 @@ PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
@@ -203,12 +220,14 @@ BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
!?*.[Cc]ache/
# Others
ClientBin/
@@ -221,7 +240,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
@@ -252,6 +271,9 @@ ServiceFabricBackup/
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
@@ -287,12 +309,8 @@ paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
@@ -317,7 +335,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
@@ -326,11 +344,29 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
### manually ignored files
# Windows shortcuts
*.lnk
# manually ignored files
/__TODO.txt
/DataLayer/LibationContext.db
*.lnk

View File

@@ -5,41 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TagLibSharp" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\AAXClean\AAXClean.csproj" />
<ProjectReference Include="..\..\Dinah.Core\Dinah.Core\Dinah.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="DecryptLib\avcodec-58.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\avdevice-58.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\avfilter-7.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\avformat-58.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\avutil-56.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\ffmpeg.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\ffprobe.exe">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\swresample-3.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="DecryptLib\swscale-5.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -1,4 +1,5 @@
using Dinah.Core;
using AAXClean;
using Dinah.Core;
using Dinah.Core.Diagnostics;
using Dinah.Core.IO;
using Dinah.Core.StepRunner;
@@ -7,99 +8,52 @@ using System.IO;
namespace AaxDecrypter
{
public interface ISimpleAaxcToM4bConverter
public class AaxcDownloadConverter
{
event EventHandler<AaxcTagLibFile> RetrievedTags;
event EventHandler<byte[]> RetrievedCoverArt;
event EventHandler<TimeSpan> DecryptTimeRemaining;
event EventHandler<int> DecryptProgressUpdate;
bool Run();
string AppName { get; set; }
string outDir { get; }
string outputFileName { get; }
DownloadLicense downloadLicense { get; }
AaxcTagLibFile aaxcTagLib { get; }
byte[] coverArt { get; }
void SetCoverArt(byte[] coverArt);
void SetOutputFilename(string outFileName);
}
public interface IAdvancedAaxcToM4bConverter : ISimpleAaxcToM4bConverter
{
void Cancel();
bool Step1_CreateDir();
bool Step2_GetMetadata();
bool Step3_DownloadAndCombine();
bool Step4_RestoreMetadata();
bool Step5_CreateCue();
bool Step6_CreateNfo();
bool Step7_Cleanup();
}
public class AaxcDownloadConverter : IAdvancedAaxcToM4bConverter
{
public event EventHandler<AaxcTagLibFile> RetrievedTags;
public event EventHandler<AppleTags> RetrievedTags;
public event EventHandler<byte[]> RetrievedCoverArt;
public event EventHandler<int> DecryptProgressUpdate;
public event EventHandler<TimeSpan> DecryptTimeRemaining;
public string AppName { get; set; } = nameof(AaxcDownloadConverter);
public string outDir { get; private set; }
public string cacheDir { get; private set; }
public string outputFileName { get; private set; }
public DownloadLicense downloadLicense { get; private set; }
public AaxcTagLibFile aaxcTagLib { get; private set; }
public byte[] coverArt { get; private set; }
public string OutputFileName { get; private set; }
private string cacheDir { get; }
private DownloadLicense downloadLicense { get; }
private AaxFile aaxFile;
private byte[] coverArt;
private StepSequence steps { get; }
private FFMpegAaxcProcesser aaxcProcesser;
private NetworkFileStreamPersister nfsPersister;
private bool isCanceled { get; set; }
private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(outputFileName) + ".json");
private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(OutputFileName) + ".json");
private string tempFile => PathLib.ReplaceExtension(jsonDownloadState, ".aaxc");
public static AaxcDownloadConverter Create(string cacheDirectory, string outDirectory, DownloadLicense dlLic)
public AaxcDownloadConverter(string outFileName, string cacheDirectory, DownloadLicense dlLic)
{
var converter = new AaxcDownloadConverter(cacheDirectory, outDirectory, dlLic);
converter.SetOutputFilename(Path.GetTempFileName());
return converter;
}
ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName));
OutputFileName = PathLib.ReplaceExtension(outFileName, ".m4b");
var outDir = Path.GetDirectoryName(OutputFileName);
if (!Directory.Exists(outDir))
throw new ArgumentNullException(nameof(outDir), "Directory does not exist");
if (File.Exists(OutputFileName))
File.Delete(OutputFileName);
private AaxcDownloadConverter(string cacheDirectory, string outDirectory, DownloadLicense dlLic)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(outDirectory, nameof(outDirectory));
ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic));
if (!Directory.Exists(outDirectory))
if (!Directory.Exists(cacheDirectory))
throw new ArgumentNullException(nameof(cacheDirectory), "Directory does not exist");
if (!Directory.Exists(outDirectory))
throw new ArgumentNullException(nameof(outDirectory), "Directory does not exist");
cacheDir = cacheDirectory;
outDir = outDirectory;
downloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic));
steps = new StepSequence
{
Name = "Download and Convert Aaxc To M4b",
["Step 1: Create Dir"] = Step1_CreateDir,
["Step 2: Get Aaxc Metadata"] = Step2_GetMetadata,
["Step 3: Download Decrypted Audiobook"] = Step3_DownloadAndCombine,
["Step 4: Restore Aaxc Metadata"] = Step4_RestoreMetadata,
["Step 5: Create Cue"] = Step5_CreateCue,
["Step 6: Create Nfo"] = Step6_CreateNfo,
["Step 7: Cleanup"] = Step7_Cleanup,
["Step 1: Get Aaxc Metadata"] = Step1_GetMetadata,
["Step 2: Download Decrypted Audiobook"] = Step2_DownloadAndCombine,
["Step 3: Create Cue"] = Step3_CreateCue,
["Step 4: Create Nfo"] = Step4_CreateNfo,
["Step 5: Cleanup"] = Step5_Cleanup,
};
aaxcProcesser = new FFMpegAaxcProcesser(dlLic);
aaxcProcesser.ProgressUpdate += AaxcProcesser_ProgressUpdate;
downloadLicense = dlLic;
}
public void SetOutputFilename(string outFileName)
{
outputFileName = PathLib.ReplaceExtension(outFileName, ".m4b");
outDir = Path.GetDirectoryName(outputFileName);
if (File.Exists(outputFileName))
File.Delete(outputFileName);
}
public void SetCoverArt(byte[] coverArt)
@@ -120,169 +74,134 @@ namespace AaxDecrypter
return false;
}
var speedup = (int)(aaxcTagLib.Properties.Duration.TotalSeconds / (long)Elapsed.TotalSeconds);
var speedup = (int)(aaxFile.Duration.TotalSeconds / (long)Elapsed.TotalSeconds);
Console.WriteLine("Speedup is " + speedup + "x realtime.");
Console.WriteLine("Done");
return true;
}
public bool Step1_CreateDir()
{
ProcessRunner.WorkingDir = outDir;
Directory.CreateDirectory(outDir);
return !isCanceled;
}
public bool Step2_GetMetadata()
public bool Step1_GetMetadata()
{
//Get metadata from the file over http
NetworkFileStreamPersister nfsPersister;
if (File.Exists(jsonDownloadState))
{
nfsPersister = new NetworkFileStreamPersister(jsonDownloadState);
//If More thaan ~1 hour has elapsed since getting the download url, it will expire.
//The new url will be to the same file.
nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl));
try
{
nfsPersister = new NetworkFileStreamPersister(jsonDownloadState);
//If More thaan ~1 hour has elapsed since getting the download url, it will expire.
//The new url will be to the same file.
nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl));
}
catch
{
FileExt.SafeDelete(jsonDownloadState);
FileExt.SafeDelete(tempFile);
nfsPersister = NewNetworkFilePersister();
}
}
else
{
var headers = new System.Net.WebHeaderCollection();
headers.Add("User-Agent", downloadLicense.UserAgent);
NetworkFileStream networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers);
nfsPersister = new NetworkFileStreamPersister(networkFileStream, jsonDownloadState);
nfsPersister = NewNetworkFilePersister();
}
nfsPersister.NetworkFileStream.BeginDownloading();
var networkFile = new NetworkFileAbstraction(nfsPersister.NetworkFileStream);
aaxcTagLib = new AaxcTagLibFile(networkFile);
nfsPersister.Dispose();
aaxFile = new AaxFile(nfsPersister.NetworkFileStream);
coverArt = aaxFile.AppleTags.Cover;
if (coverArt is null && aaxcTagLib.AppleTags.Pictures.Length > 0)
{
coverArt = aaxcTagLib.AppleTags.Pictures[0].Data.Data;
}
RetrievedTags?.Invoke(this, aaxcTagLib);
RetrievedTags?.Invoke(this, aaxFile.AppleTags);
RetrievedCoverArt?.Invoke(this, coverArt);
return !isCanceled;
}
public bool Step3_DownloadAndCombine()
private NetworkFileStreamPersister NewNetworkFilePersister()
{
DecryptProgressUpdate?.Invoke(this, int.MaxValue);
var headers = new System.Net.WebHeaderCollection();
headers.Add("User-Agent", downloadLicense.UserAgent);
NetworkFileStreamPersister nfsPersister;
if (File.Exists(jsonDownloadState))
{
nfsPersister = new NetworkFileStreamPersister(jsonDownloadState);
//If More thaan ~1 hour has elapsed since getting the download url, it will expire.
//The new url will be to the same file.
nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl));
}
else
{
var headers = new System.Net.WebHeaderCollection();
headers.Add("User-Agent", downloadLicense.UserAgent);
NetworkFileStream networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers);
return new NetworkFileStreamPersister(networkFileStream, jsonDownloadState);
}
NetworkFileStream networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers);
nfsPersister = new NetworkFileStreamPersister(networkFileStream, jsonDownloadState);
}
string metadataPath = Path.Combine(outDir, Path.GetFileName(outputFileName) + ".ffmeta");
if (downloadLicense.ChapterInfo is null)
{
//If we want to keep the original chapters, we need to get them from the url.
//Ffprobe needs to seek to find metadata and it can't seek a pipe. Also, there's
//no guarantee that enough of the file will have been downloaded at this point
//to be able to use the cache file.
downloadLicense.ChapterInfo = new ChapterInfo(downloadLicense.DownloadUrl);
}
//Only write chapters to the metadata file. All other aaxc metadata will be
//wiped out but is restored in Step 3.
File.WriteAllText(metadataPath, downloadLicense.ChapterInfo.ToFFMeta(true));
aaxcProcesser.ProcessBook(
nfsPersister.NetworkFileStream,
outputFileName,
metadataPath)
.GetAwaiter()
.GetResult();
nfsPersister.NetworkFileStream.Close();
nfsPersister.Dispose();
FileExt.SafeDelete(metadataPath);
public bool Step2_DownloadAndCombine()
{
OutputFormat format = OutputFormat.Mp4a;
DecryptProgressUpdate?.Invoke(this, 0);
return aaxcProcesser.Succeeded && !isCanceled;
if (File.Exists(OutputFileName))
FileExt.SafeDelete(OutputFileName);
FileStream outFile = File.OpenWrite(OutputFileName);
aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
var decryptionResult = aaxFile.DecryptAaxc(outFile, downloadLicense.AudibleKey, downloadLicense.AudibleIV, format, downloadLicense.ChapterInfo);
aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
downloadLicense.ChapterInfo = aaxFile.Chapters;
if (decryptionResult == ConversionResult.NoErrorsDetected
&& coverArt is not null
&& format == OutputFormat.Mp4a)
{
//This handles a special case where the aaxc file doesn't contain cover art and
//Libation downloaded it instead (Animal Farm). Currently only works for Mp4a files.
using var decryptedBook = new Mp4File(OutputFileName, FileAccess.ReadWrite);
decryptedBook.AppleTags?.SetCoverArt(coverArt);
decryptedBook.Save();
decryptedBook.Close();
}
nfsPersister.Dispose();
DecryptProgressUpdate?.Invoke(this, 0);
return decryptionResult == ConversionResult.NoErrorsDetected && !isCanceled;
}
private void AaxcProcesser_ProgressUpdate(object sender, AaxcProcessUpdate e)
private void AaxFile_ConversionProgressUpdate(object sender, ConversionProgressEventArgs e)
{
double remainingSecsToProcess = (aaxcTagLib.Properties.Duration - e.ProcessPosition).TotalSeconds;
var duration = aaxFile.Duration;
double remainingSecsToProcess = (duration - e.ProcessPosition).TotalSeconds;
double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed;
if (double.IsNormal(estTimeRemaining))
DecryptTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining));
double progressPercent = 100 * e.ProcessPosition.TotalSeconds / aaxcTagLib.Properties.Duration.TotalSeconds;
double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds;
DecryptProgressUpdate?.Invoke(this, (int)progressPercent);
}
/// <summary>
/// Copy all aacx metadata to m4b file, including cover art.
/// </summary>
public bool Step4_RestoreMetadata()
{
var outFile = new AaxcTagLibFile(outputFileName);
outFile.CopyTagsFrom(aaxcTagLib);
if (outFile.AppleTags.Pictures.Length == 0 && coverArt is not null)
{
outFile.AddPicture(coverArt);
}
outFile.Save();
return !isCanceled;
}
public bool Step5_CreateCue()
public bool Step3_CreateCue()
{
// not a critical step. its failure should not prevent future steps from running
try
{
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), downloadLicense.ChapterInfo));
File.WriteAllText(PathLib.ReplaceExtension(OutputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(OutputFileName), downloadLicense.ChapterInfo));
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"{nameof(Step5_CreateCue)}. FAILED");
Serilog.Log.Logger.Error(ex, $"{nameof(Step3_CreateCue)}. FAILED");
}
return !isCanceled;
}
public bool Step6_CreateNfo()
public bool Step4_CreateNfo()
{
// not a critical step. its failure should not prevent future steps from running
try
{
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".nfo"), NFO.CreateContents(AppName, aaxcTagLib, downloadLicense.ChapterInfo));
File.WriteAllText(PathLib.ReplaceExtension(OutputFileName, ".nfo"), NFO.CreateContents(AppName, aaxFile, downloadLicense.ChapterInfo));
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"{nameof(Step6_CreateNfo)}. FAILED");
Serilog.Log.Logger.Error(ex, $"{nameof(Step4_CreateNfo)}. FAILED");
}
return !isCanceled;
}
public bool Step7_Cleanup()
public bool Step5_Cleanup()
{
FileExt.SafeDelete(jsonDownloadState);
FileExt.SafeDelete(tempFile);
@@ -292,7 +211,7 @@ namespace AaxDecrypter
public void Cancel()
{
isCanceled = true;
aaxcProcesser.Cancel();
aaxFile?.Cancel();
}
}
}

View File

@@ -1,75 +0,0 @@
using System;
using System.Linq;
using Dinah.Core;
using TagLib;
using TagLib.Mpeg4;
namespace AaxDecrypter
{
public class AaxcTagLibFile : TagLib.Mpeg4.File
{
// ©
private const byte COPYRIGHT = 0xa9;
private static ReadOnlyByteVector narratorType { get; } = new ReadOnlyByteVector(COPYRIGHT, (byte)'n', (byte)'r', (byte)'t');
private static ReadOnlyByteVector descriptionType { get; } = new ReadOnlyByteVector(COPYRIGHT, (byte)'d', (byte)'e', (byte)'s');
private static ReadOnlyByteVector publisherType { get; } = new ReadOnlyByteVector(COPYRIGHT, (byte)'p', (byte)'u', (byte)'b');
public string AsciiTitleSansUnabridged => TitleSansUnabridged?.UnicodeToAscii();
public string AsciiFirstAuthor => FirstAuthor?.UnicodeToAscii();
public string AsciiNarrator => Narrator?.UnicodeToAscii();
public string AsciiComment => Comment?.UnicodeToAscii();
public string AsciiLongDescription => LongDescription?.UnicodeToAscii();
public AppleTag AppleTags => GetTag(TagTypes.Apple) as AppleTag;
public string Comment => AppleTags.Comment;
public string[] Authors => AppleTags.Performers;
public string FirstAuthor => Authors?.Length > 0 ? Authors[0] : default;
public string TitleSansUnabridged => AppleTags.Title?.Replace(" (Unabridged)", "");
public string BookCopyright => _copyright is not null && _copyright.Length > 0 ? _copyright[0] : default;
public string RecordingCopyright => _copyright is not null && _copyright.Length > 1 ? _copyright[1] : default;
private string[] _copyright => AppleTags.Copyright?.Replace("&#169;", string.Empty)?.Replace("(P)", string.Empty)?.Split(';');
public string Narrator => getAppleTagsText(narratorType);
public string LongDescription => getAppleTagsText(descriptionType);
public string ReleaseDate => getAppleTagsText("rldt");
public string Publisher => getAppleTagsText(publisherType);
private string getAppleTagsText(ByteVector byteVector)
{
string[] text = AppleTags.GetText(byteVector);
return text.Length == 0 ? default : text[0];
}
public AaxcTagLibFile(IFileAbstraction abstraction)
: base(abstraction, ReadStyle.Average)
{
}
public AaxcTagLibFile(string path)
: this(new LocalFileAbstraction(path))
{
}
/// <summary>
/// Copy all metadata fields in the source file, even those that TagLib doesn't
/// recognize, to the output file.
/// NOTE: Chapters aren't stored in MPEG-4 metadata. They are encoded as a Timed
/// Text Stream (MPEG-4 Part 17), so taglib doesn't read or write them.
/// </summary>
/// <param name="sourceFile">File from which tags will be coppied.</param>
public void CopyTagsFrom(AaxcTagLibFile sourceFile)
{
AppleTags.Clear();
foreach (var stag in sourceFile.AppleTags)
{
AppleTags.SetData(stag.BoxType, stag.Children.Cast<AppleDataBox>().ToArray());
}
}
public void AddPicture(byte[] coverArt)
{
AppleTags.SetData("covr", coverArt, 0);
}
}
}

View File

@@ -1,86 +0,0 @@
using Dinah.Core;
using Dinah.Core.Diagnostics;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace AaxDecrypter
{
public class ChapterInfo
{
private List<Chapter> _chapterList = new List<Chapter>();
public IEnumerable<Chapter> Chapters => _chapterList.AsEnumerable();
public int Count => _chapterList.Count;
public ChapterInfo() { }
public ChapterInfo(string audiobookFile)
{
var info = new ProcessStartInfo
{
FileName = DecryptSupportLibraries.ffprobePath,
Arguments = "-loglevel panic -show_chapters -print_format json \"" + audiobookFile + "\""
};
var jString = info.RunHidden().Output;
var chapterJObject = JObject.Parse(jString);
var chapters = chapterJObject["chapters"]
.Select(c => new Chapter(
c["tags"]?["title"]?.Value<string>(),
c["start_time"].Value<double>(),
c["end_time"].Value<double>()
));
_chapterList.AddRange(chapters);
}
public void AddChapter(Chapter chapter)
{
ArgumentValidator.EnsureNotNull(chapter, nameof(chapter));
_chapterList.Add(chapter);
}
public string ToFFMeta(bool includeFFMetaHeader)
{
var ffmetaChapters = new StringBuilder();
if (includeFFMetaHeader)
ffmetaChapters.AppendLine(";FFMETADATA1");
foreach (var c in Chapters)
{
ffmetaChapters.AppendLine(c.ToFFMeta());
}
return ffmetaChapters.ToString();
}
}
public class Chapter
{
public string Title { get; }
public TimeSpan StartOffset { get; }
public TimeSpan EndOffset { get; }
public Chapter(string title, long startOffsetMs, long lengthMs)
{
ArgumentValidator.EnsureNotNullOrEmpty(title, nameof(title));
ArgumentValidator.EnsureGreaterThan(startOffsetMs, nameof(startOffsetMs), -1);
// do not validate lengthMs for '> 0'. It is valid to set sections this way. eg: 11-22-63 [B005UR3VFO] by Stephen King
Title = title;
StartOffset = TimeSpan.FromMilliseconds(startOffsetMs);
EndOffset = StartOffset + TimeSpan.FromMilliseconds(lengthMs);
}
public Chapter(string title, double startTimeSec, double endTimeSec)
: this(title, (long)(startTimeSec * 1000), (long)((endTimeSec - startTimeSec) * 1000))
{
}
public string ToFFMeta()
{
return "[CHAPTER]\n" +
"TIMEBASE=1/1000\n" +
"START=" + StartOffset.TotalMilliseconds + "\n" +
"END=" + EndOffset.TotalMilliseconds + "\n" +
"title=" + Title;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Text;
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -1,16 +0,0 @@
using System.IO;
namespace AaxDecrypter
{
public static class DecryptSupportLibraries
{
// OTHER EXTERNAL DEPENDENCIES
// ffprobe has these pre-req.s as I'm using it:
// avcodec-58.dll, avdevice-58.dll, avfilter-7.dll, avformat-58.dll, avutil-56.dll, swresample-3.dll, swscale-5.dll, taglib-sharp.dll
private static string appPath_ { get; } = Path.GetDirectoryName(Dinah.Core.Exe.FileLocationOnDisk);
private static string decryptLib_ { get; } = Path.Combine(appPath_, "DecryptLib");
public static string ffmpegPath { get; } = Path.Combine(decryptLib_, "ffmpeg.exe");
public static string ffprobePath { get; } = Path.Combine(decryptLib_, "ffprobe.exe");
}
}

View File

@@ -1,4 +1,5 @@
using Dinah.Core;
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{

View File

@@ -1,254 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace AaxDecrypter
{
class AaxcProcessUpdate
{
public AaxcProcessUpdate(TimeSpan position, double speed)
{
ProcessPosition = position;
ProcessSpeed = speed;
EventTime = DateTime.Now;
}
public TimeSpan ProcessPosition { get; }
public double ProcessSpeed { get; }
public DateTime EventTime { get; }
}
/// <summary>
/// Download audible aaxc, decrypt, and remux with chapters.
/// </summary>
class FFMpegAaxcProcesser
{
public event EventHandler<AaxcProcessUpdate> ProgressUpdate;
public string FFMpegPath { get; }
public DownloadLicense DownloadLicense { get; }
public bool IsRunning { get; private set; }
public bool Succeeded { get; private set; }
public string FFMpegRemuxerStandardError => remuxerError.ToString();
public string FFMpegDecrypterStandardError => decrypterError.ToString();
private StringBuilder remuxerError { get; } = new StringBuilder();
private StringBuilder decrypterError { get; } = new StringBuilder();
private static Regex processedTimeRegex { get; } = new Regex("time=(\\d{2}):(\\d{2}):(\\d{2}).\\d{2}.*speed=\\s{0,1}([0-9]*[.]?[0-9]+)(?:e\\+([0-9]+)){0,1}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private Process decrypter;
private Process remuxer;
private Stream inputFile;
private bool isCanceled = false;
public FFMpegAaxcProcesser(DownloadLicense downloadLicense)
{
FFMpegPath = DecryptSupportLibraries.ffmpegPath;
DownloadLicense = downloadLicense;
}
public async Task ProcessBook(Stream inputFile, string outputFile, string ffmetaChaptersPath)
{
this.inputFile = inputFile;
//This process gets the aaxc from the url and streams the decrypted
//aac stream to standard output
decrypter = new Process
{
StartInfo = getDownloaderStartInfo()
};
//This process retreves an aac stream from standard input and muxes
// it into an m4b along with the cover art and metadata.
remuxer = new Process
{
StartInfo = getRemuxerStartInfo(outputFile, ffmetaChaptersPath)
};
IsRunning = true;
decrypter.ErrorDataReceived += Downloader_ErrorDataReceived;
decrypter.Start();
decrypter.BeginErrorReadLine();
remuxer.ErrorDataReceived += Remuxer_ErrorDataReceived;
remuxer.Start();
remuxer.BeginErrorReadLine();
//Thic check needs to be placed after remuxer has started.
if (isCanceled) return;
var decrypterInput = decrypter.StandardInput.BaseStream;
var decrypterOutput = decrypter.StandardOutput.BaseStream;
var remuxerInput = remuxer.StandardInput.BaseStream;
//Read inputFile into decrypter stdin in the background
var t = new Thread(() => CopyStream(inputFile, decrypterInput, decrypter));
t.Start();
//All the work done here. Copy download standard output into
//remuxer standard input
await Task.Run(() => CopyStream(decrypterOutput, remuxerInput, remuxer));
//If the remuxer exited due to failure, downloader will still have
//data in the pipe. Force kill downloader to continue.
if (remuxer.HasExited && !decrypter.HasExited)
decrypter.Kill();
remuxer.WaitForExit();
decrypter.WaitForExit();
IsRunning = false;
Succeeded = decrypter.ExitCode == 0 && remuxer.ExitCode == 0;
}
private void CopyStream(Stream inputStream, Stream outputStream, Process returnOnProcExit)
{
try
{
byte[] buffer = new byte[32 * 1024];
int lastRead;
do
{
lastRead = inputStream.Read(buffer, 0, buffer.Length);
outputStream.Write(buffer, 0, lastRead);
} while (lastRead > 0 && !returnOnProcExit.HasExited);
}
catch (IOException ex)
{
//There is no way to tell if the process closed the input stream
//before trying to write to it. If it did close, throws IOException.
isCanceled = true;
}
finally
{
outputStream.Close();
}
}
public void Cancel()
{
isCanceled = true;
if (IsRunning && !remuxer.HasExited)
remuxer.Kill();
if (IsRunning && !decrypter.HasExited)
decrypter.Kill();
inputFile?.Close();
}
private void Downloader_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (string.IsNullOrEmpty(e.Data))
return;
decrypterError.AppendLine(e.Data);
}
private void Remuxer_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (string.IsNullOrEmpty(e.Data))
return;
remuxerError.AppendLine(e.Data);
if (processedTimeRegex.IsMatch(e.Data))
{
//get timestamp of of last processed audio stream position
//and processing speed
var match = processedTimeRegex.Match(e.Data);
int hours = int.Parse(match.Groups[1].Value);
int minutes = int.Parse(match.Groups[2].Value);
int seconds = int.Parse(match.Groups[3].Value);
var position = new TimeSpan(hours, minutes, seconds);
double speed = double.Parse(match.Groups[4].Value);
int exp = match.Groups[5].Success ? int.Parse(match.Groups[5].Value) : 0;
speed *= Math.Pow(10, exp);
ProgressUpdate?.Invoke(this, new AaxcProcessUpdate(position, speed));
}
if (e.Data.Contains("aac bitstream error"))
{
//This happens if input is corrupt (should never happen) or if caller
//supplied wrong key/iv
var process = sender as Process;
process.Kill();
}
}
private ProcessStartInfo getDownloaderStartInfo() =>
new ProcessStartInfo
{
FileName = FFMpegPath,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
WorkingDirectory = Path.GetDirectoryName(FFMpegPath),
ArgumentList ={
"-audible_key",
DownloadLicense.AudibleKey,
"-audible_iv",
DownloadLicense.AudibleIV,
"-f",
"mp4",
"-i",
"pipe:",
"-c:a", //audio codec
"copy", //copy stream
"-f", //force output format: adts
"adts",
"pipe:" //pipe output to stdout
}
};
private ProcessStartInfo getRemuxerStartInfo(string outputFile, string ffmetaChaptersPath = null)
{
var startInfo = new ProcessStartInfo
{
FileName = FFMpegPath,
RedirectStandardError = true,
RedirectStandardInput = true,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
WorkingDirectory = Path.GetDirectoryName(FFMpegPath),
};
startInfo.ArgumentList.Add("-thread_queue_size");
startInfo.ArgumentList.Add("1024");
startInfo.ArgumentList.Add("-f"); //force input format: aac
startInfo.ArgumentList.Add("aac");
startInfo.ArgumentList.Add("-i"); //read input from stdin
startInfo.ArgumentList.Add("pipe:");
//copy metadata from supplied metadata file
startInfo.ArgumentList.Add("-f");
startInfo.ArgumentList.Add("ffmetadata");
startInfo.ArgumentList.Add("-i");
startInfo.ArgumentList.Add(ffmetaChaptersPath);
startInfo.ArgumentList.Add("-map"); //map file 0 (aac audio stream)
startInfo.ArgumentList.Add("0");
startInfo.ArgumentList.Add("-map_chapters"); //copy chapter data from file metadata file
startInfo.ArgumentList.Add("1");
startInfo.ArgumentList.Add("-c"); //copy all mapped streams
startInfo.ArgumentList.Add("copy");
startInfo.ArgumentList.Add("-f"); //force output format: mp4
startInfo.ArgumentList.Add("mp4");
startInfo.ArgumentList.Add("-movflags");
startInfo.ArgumentList.Add("disable_chpl"); //Disable Nero chapters format
startInfo.ArgumentList.Add(outputFile);
startInfo.ArgumentList.Add("-y"); //overwrite existing
return startInfo;
}
}
}

View File

@@ -1,27 +1,29 @@

using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{
public static class NFO
{
public static string CreateContents(string ripper, AaxcTagLibFile aaxcTagLib, ChapterInfo chapters)
public static string CreateContents(string ripper, AAXClean.Mp4File aaxcTagLib, ChapterInfo chapters)
{
var _hours = (int)aaxcTagLib.Properties.Duration.TotalHours;
var _hours = (int)aaxcTagLib.Duration.TotalHours;
var myDuration
= (_hours > 0 ? _hours + " hours, " : string.Empty)
+ aaxcTagLib.Properties.Duration.Minutes + " minutes, "
+ aaxcTagLib.Properties.Duration.Seconds + " seconds";
+ aaxcTagLib.Duration.Minutes + " minutes, "
+ aaxcTagLib.Duration.Seconds + " seconds";
var nfoString
= "General Information\r\n"
+ "======================\r\n"
+ $" Title: {aaxcTagLib.AsciiTitleSansUnabridged ?? "[unknown]"}\r\n"
+ $" Author: {aaxcTagLib.AsciiFirstAuthor ?? "[unknown]"}\r\n"
+ $" Read By: {aaxcTagLib.AsciiNarrator ?? "[unknown]"}\r\n"
+ $" Release Date: {aaxcTagLib.ReleaseDate ?? "[unknown]"}\r\n"
+ $" Book Copyright: {aaxcTagLib.BookCopyright ?? "[unknown]"}\r\n"
+ $" Recording Copyright: {aaxcTagLib.RecordingCopyright ?? "[unknown]"}\r\n"
+ $" Genre: {aaxcTagLib.AppleTags.FirstGenre ?? "[unknown]"}\r\n"
+ $" Publisher: {aaxcTagLib.Publisher ?? "[unknown]"}\r\n"
+ $" Title: {aaxcTagLib.AppleTags.TitleSansUnabridged?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Author: {aaxcTagLib.AppleTags.FirstAuthor?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Read By: {aaxcTagLib.AppleTags.Narrator?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Release Date: {aaxcTagLib.AppleTags.ReleaseDate ?? "[unknown]"}\r\n"
+ $" Book Copyright: {aaxcTagLib.AppleTags.BookCopyright ?? "[unknown]"}\r\n"
+ $" Recording Copyright: {aaxcTagLib.AppleTags.RecordingCopyright ?? "[unknown]"}\r\n"
+ $" Genre: {aaxcTagLib.AppleTags.Generes ?? "[unknown]"}\r\n"
+ $" Publisher: {aaxcTagLib.AppleTags.Publisher ?? "[unknown]"}\r\n"
+ $" Duration: {myDuration}\r\n"
+ $" Chapters: {chapters.Count}\r\n"
+ "\r\n"
@@ -29,22 +31,22 @@ namespace AaxDecrypter
+ "Media Information\r\n"
+ "======================\r\n"
+ " Source Format: Audible AAX\r\n"
+ $" Source Sample Rate: {aaxcTagLib.Properties.AudioSampleRate} Hz\r\n"
+ $" Source Channels: {aaxcTagLib.Properties.AudioChannels}\r\n"
+ $" Source Bitrate: {aaxcTagLib.Properties.AudioBitrate} Kbps\r\n"
+ $" Source Sample Rate: {aaxcTagLib.TimeScale} Hz\r\n"
+ $" Source Channels: {aaxcTagLib.AudioChannels}\r\n"
+ $" Source Bitrate: {aaxcTagLib.AverageBitrate} Kbps\r\n"
+ "\r\n"
+ " Lossless Encode: Yes\r\n"
+ " Encoded Codec: AAC / M4B\r\n"
+ $" Encoded Sample Rate: {aaxcTagLib.Properties.AudioSampleRate} Hz\r\n"
+ $" Encoded Channels: {aaxcTagLib.Properties.AudioChannels}\r\n"
+ $" Encoded Bitrate: {aaxcTagLib.Properties.AudioBitrate} Kbps\r\n"
+ $" Encoded Sample Rate: {aaxcTagLib.TimeScale} Hz\r\n"
+ $" Encoded Channels: {aaxcTagLib.AudioChannels}\r\n"
+ $" Encoded Bitrate: {aaxcTagLib.AverageBitrate} Kbps\r\n"
+ "\r\n"
+ $" Ripper: {ripper}\r\n"
+ "\r\n"
+ "\r\n"
+ "Book Description\r\n"
+ "================\r\n"
+ (!string.IsNullOrWhiteSpace(aaxcTagLib.LongDescription) ? aaxcTagLib.AsciiLongDescription : aaxcTagLib.AsciiComment);
+ (!string.IsNullOrWhiteSpace(aaxcTagLib.AppleTags.LongDescription) ? aaxcTagLib.AppleTags.LongDescription.UnicodeToAscii() : aaxcTagLib.AppleTags.Comment?.UnicodeToAscii());
return nfoString;
}

View File

@@ -1,31 +0,0 @@
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace AaxDecrypter
{
/// <summary>
/// Provides a <see cref="TagLib.File.IFileAbstraction"/> for a file over Http.
/// </summary>
class NetworkFileAbstraction : TagLib.File.IFileAbstraction
{
private NetworkFileStream aaxNetworkStream;
public NetworkFileAbstraction( NetworkFileStream networkFileStream)
{
Name = networkFileStream.SaveFilePath;
aaxNetworkStream = networkFileStream;
}
public string Name { get; private set; }
public Stream ReadStream => aaxNetworkStream;
public Stream WriteStream => throw new NotImplementedException();
public void CloseStream(Stream stream)
{
aaxNetworkStream.Close();
}
}
}

View File

@@ -176,7 +176,7 @@ namespace AaxDecrypter
/// <summary>
/// Begins downloading <see cref="Uri"/> to <see cref="SaveFilePath"/> in a background thread.
/// </summary>
private void BeginDownloading()
public void BeginDownloading()
{
if (ContentLength != 0 && WritePosition == ContentLength)
{
@@ -393,7 +393,7 @@ namespace AaxDecrypter
//read operation will block until file contains enough data
//to fulfil the request, or until cancelled.
while (requiredPosition > WritePosition && !isCancelled)
Thread.Sleep(0);
Thread.Sleep(2);
return _readFile.Read(buffer, offset, count);
}

View File

@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="27.0.2" />
<PackageReference Include="CsvHelper" Version="27.1.1" />
<PackageReference Include="NPOI" Version="2.5.3" />
</ItemGroup>

View File

@@ -35,7 +35,7 @@ namespace ApplicationServices
}
catch (AudibleApi.Authentication.LoginFailedException lfEx)
{
lfEx.MoveResponseBodyFile(FileManager.Configuration.Instance.LibationFiles);
lfEx.SaveFiles(FileManager.Configuration.Instance.LibationFiles);
// nuget Serilog.Exceptions would automatically log custom properties
// However, it comes with a scary warning when used with EntityFrameworkCore which I'm not yet ready to implement:
@@ -46,7 +46,7 @@ namespace ApplicationServices
ResponseStatusCodeNumber = (int)lfEx.ResponseStatusCode,
ResponseStatusCodeDesc = lfEx.ResponseStatusCode,
lfEx.ResponseInputFields,
lfEx.ResponseBodyFilePath
lfEx.ResponseBodyFilePaths
});
throw;
}

View File

@@ -81,24 +81,14 @@ namespace FileLiberator
if (Configuration.Instance.AllowLibationFixup)
{
aaxcDecryptDlLic.ChapterInfo = new ChapterInfo();
aaxcDecryptDlLic.ChapterInfo = new AAXClean.ChapterInfo();
foreach (var chap in contentLic.ContentMetadata?.ChapterInfo?.Chapters)
aaxcDecryptDlLic.ChapterInfo.AddChapter(
new Chapter(
chap.Title,
chap.StartOffsetMs,
chap.LengthMs
));
aaxcDecryptDlLic.ChapterInfo.AddChapter(chap.Title, TimeSpan.FromMilliseconds(chap.LengthMs));
}
aaxcDownloader = AaxcDownloadConverter.Create(cacheDir, destinationDir, aaxcDecryptDlLic);
aaxcDownloader.AppName = "Libation";
// override default which was set in CreateAsync
var proposedOutputFile = Path.Combine(destinationDir, $"{PathLib.ToPathSafeString(libraryBook.Book.Title)} [{libraryBook.Book.AudibleProductId}].m4b");
aaxcDownloader.SetOutputFilename(proposedOutputFile);
aaxcDownloader = new AaxcDownloadConverter(proposedOutputFile, cacheDir, aaxcDecryptDlLic) { AppName = "Libation" };
aaxcDownloader.DecryptProgressUpdate += (s, progress) => UpdateProgress?.Invoke(this, progress);
aaxcDownloader.DecryptTimeRemaining += (s, remaining) => UpdateRemainingTime?.Invoke(this, remaining);
aaxcDownloader.RetrievedCoverArt += AaxcDownloader_RetrievedCoverArt;
@@ -111,7 +101,7 @@ namespace FileLiberator
if (!success)
return null;
return aaxcDownloader.outputFileName;
return aaxcDownloader.OutputFileName;
}
finally
{
@@ -132,7 +122,7 @@ namespace FileLiberator
}
}
private void aaxcDownloader_RetrievedTags(object sender, AaxcTagLibFile e)
private void aaxcDownloader_RetrievedTags(object sender, AAXClean.AppleTags e)
{
TitleDiscovered?.Invoke(this, e.TitleSansUnabridged);
AuthorsDiscovered?.Invoke(this, e.FirstAuthor ?? "[unknown]");

View File

@@ -6,6 +6,7 @@ using Dinah.Core.Net.Http;
namespace FileLiberator
{
// frustratingly copy pasta from DownloadableBase and DownloadPdf
// currently only used to download the .zip flies for upgrade
public class DownloadFile : IDownloadable
{
public event EventHandler<string> DownloadBegin;

View File

@@ -28,39 +28,9 @@ namespace FileManager
public static AudibleFileStorage AAXC { get; } = new AaxcFileStorage();
public static AudibleFileStorage PDF { get; } = new PdfFileStorage();
public static string DownloadsInProgress
{
get
{
if (!Configuration.Instance.DownloadsInProgressEnum.In("WinTemp", "LibationFiles"))
Configuration.Instance.DownloadsInProgressEnum = "WinTemp";
var AaxRootDir
= Configuration.Instance.DownloadsInProgressEnum == "WinTemp"
? Configuration.WinTemp
: Configuration.Instance.LibationFiles;
public static string DownloadsInProgress => Directory.CreateDirectory(Path.Combine(Configuration.Instance.DownloadsInProgressEnum, "DownloadsInProgress")).FullName;
return Directory.CreateDirectory(Path.Combine(AaxRootDir, "DownloadsInProgress")).FullName;
}
}
public static string DecryptInProgress
{
get
{
if (!Configuration.Instance.DecryptInProgressEnum.In("WinTemp", "LibationFiles"))
Configuration.Instance.DecryptInProgressEnum = "WinTemp";
var M4bRootDir
= Configuration.Instance.DecryptInProgressEnum == "WinTemp"
? Configuration.WinTemp
: Configuration.Instance.LibationFiles;
return Directory.CreateDirectory(Path.Combine(M4bRootDir, "DecryptInProgress")).FullName;
}
}
// not customizable. don't move to config
public static string DownloadsFinal => new DirectoryInfo(Configuration.Instance.LibationFiles).CreateSubdirectory("DownloadsFinal").FullName;
public static string DecryptInProgress => Directory.CreateDirectory(Path.Combine(Configuration.Instance.DecryptInProgressEnum, "DecryptInProgress")).FullName;
public static string BooksDirectory
{

View File

@@ -50,24 +50,75 @@ namespace FileManager
set => persistentDictionary.Set(nameof(Books), value);
}
private const string APP_DIR = "AppDir";
public static string AppDir { get; } = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), LIBATION_FILES));
public static string MyDocs { get; } = Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), LIBATION_FILES));
public static string WinTemp { get; } = Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation"));
#region known directories
public const string WIN_TEMP_LABEL = "WinTemp";
public const string LIBATION_FILES_LABEL = "LibationFiles";
public const string USER_PROFILE_LABEL = "UserProfile";
public static string AppDir_Relative => @".\LibationFiles";
public static string AppDir_Absolute => Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Exe.FileLocationOnDisk), LIBATION_FILES_KEY));
public static string MyDocs => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles"));
public static string WinTemp => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation"));
public static string UserProfile => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation"));
private Dictionary<string, string> wellKnownPaths { get; } = new Dictionary<string, string>
public enum KnownDirectories
{
[APP_DIR] = AppDir,
["MyDocs"] = MyDocs,
["WinTemp"] = WinTemp
None = 0,
[Description("My Users folder")]
UserProfile = 1,
[Description("The same folder that Libation is running from")]
AppDir = 2,
[Description("Windows temporary folder")]
WinTemp = 3,
[Description("My Documents")]
MyDocs = 4,
[Description("Your settings folder (aka: Libation Files)")]
LibationFiles = 5
}
// use func calls so we always get the latest value of LibationFiles
private static List<(KnownDirectories directory, Func<string> getPathFunc)> directoryOptionsPaths { get; } = new()
{
(KnownDirectories.None, () => null),
(KnownDirectories.UserProfile, () => UserProfile),
(KnownDirectories.AppDir, () => AppDir_Relative),
(KnownDirectories.WinTemp, () => WinTemp),
(KnownDirectories.MyDocs, () => MyDocs),
// this is important to not let very early calls try to accidentally load LibationFiles too early
(KnownDirectories.LibationFiles, () => libationFilesPathCache)
};
private string libationFilesPathCache;
public static string GetKnownDirectoryPath(KnownDirectories directory)
{
var dirFunc = directoryOptionsPaths.SingleOrDefault(dirFunc => dirFunc.directory == directory);
return dirFunc == default ? null : dirFunc.getPathFunc();
}
public static KnownDirectories GetKnownDirectory(string directory)
{
// especially important so a very early call doesn't match null => LibationFiles
if (string.IsNullOrWhiteSpace(directory))
return KnownDirectories.None;
var dirFunc = directoryOptionsPaths.SingleOrDefault(dirFunc => dirFunc.getPathFunc() == directory);
return dirFunc == default ? KnownDirectories.None : dirFunc.directory;
}
#endregion
// default setting and directory creation occur in class responsible for files.
// config class is only responsible for path. not responsible for setting defaults, dir validation, or dir creation
// exceptions: appsettings.json, LibationFiles dir, Settings.json
// temp/working dir(s) should be outside of dropbox
[Description("Temporary location of files while they're in process of being downloaded and decrypted.\r\nWhen decryption is complete, the final file will be in Books location\r\nRecommend not using a folder which is backed up real time. Eg: Dropbox, iCloud, Google Drive")]
public string InProgress
{
get => persistentDictionary.GetString(nameof(InProgress));
set => persistentDictionary.Set(nameof(InProgress), value);
}
[Description("Temporary location of files while they're in process of being downloaded.\r\nWhen download is complete, the final file will be in [LibationFiles]\\DownloadsFinal")]
public string DownloadsInProgressEnum
{
@@ -96,49 +147,62 @@ namespace FileManager
private Configuration() { }
private const string APPSETTINGS_JSON = "appsettings.json";
private const string LIBATION_FILES = "LibationFiles";
// this is the key in appsettings. The string happens to match the metadirectory name but separate concern. keep separate
private const string LIBATION_FILES_KEY = "LibationFiles";
[Description("Location for storage of program-created files")]
public string LibationFiles => libationFilesPathCache ?? getLibationFiles();
private string getLibationFiles()
public string LibationFiles
{
var value = getLiberationFilesSettingFromJson();
get
{
if (libationFilesPathCache is not null)
return libationFilesPathCache;
// this looks weird but is correct for translating wellKnownPaths
if (wellKnownPaths.ContainsKey(value))
value = wellKnownPaths[value];
// must write here before SettingsFilePath in next step reads cache
libationFilesPathCache = getLiberationFilesSettingFromJson();
// must write here before SettingsFilePath in next step reads cache
libationFilesPathCache = value;
// load json values into memory. create settings if not exists
persistentDictionary = new PersistentDictionary(SettingsFilePath);
// load json values into memory. create if not exists
persistentDictionary = new PersistentDictionary(SettingsFilePath);
return libationFilesPathCache;
return libationFilesPathCache;
}
}
private static string libationFilesPathCache;
private string getLiberationFilesSettingFromJson()
{
string startingContents = null;
try
{
if (File.Exists(APPSETTINGS_JSON))
{
var appSettingsContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(appSettingsContents);
startingContents = File.ReadAllText(APPSETTINGS_JSON);
var startingJObj = JObject.Parse(startingContents);
if (jObj.ContainsKey(LIBATION_FILES))
if (startingJObj.ContainsKey(LIBATION_FILES_KEY))
{
var value = jObj[LIBATION_FILES].Value<string>();
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
if (!string.IsNullOrWhiteSpace(value))
return value;
var startingValue = startingJObj[LIBATION_FILES_KEY].Value<string>();
if (!string.IsNullOrWhiteSpace(startingValue))
return startingValue;
}
}
}
catch { }
File.WriteAllText(APPSETTINGS_JSON, new JObject { { LIBATION_FILES, APP_DIR } }.ToString(Formatting.Indented));
return APP_DIR;
// not found. write to file. read from file
var endingContents = new JObject { { LIBATION_FILES_KEY, UserProfile } }.ToString(Formatting.Indented);
if (startingContents != endingContents)
{
File.WriteAllText(APPSETTINGS_JSON, endingContents);
System.Threading.Thread.Sleep(100);
}
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
// verify from live file. no try/catch. want failures to be visible
var jObjFinal = JObject.Parse(File.ReadAllText(APPSETTINGS_JSON));
var valueFinal = jObjFinal[LIBATION_FILES_KEY].Value<string>();
return valueFinal;
}
public object GetObject(string propertyName) => persistentDictionary.GetObject(propertyName);
@@ -158,29 +222,29 @@ namespace FileManager
public bool TrySetLibationFiles(string directory)
{
if (!Directory.Exists(directory) && !wellKnownPaths.ContainsKey(directory))
return false;
// this is WRONG. need to MOVE settings; not DELETE them
// if moving from default, delete old settings file and dir (if empty)
if (LibationFiles.EqualsInsensitive(AppDir))
{
File.Delete(SettingsFilePath);
System.Threading.Thread.Sleep(100);
if (!Directory.EnumerateDirectories(AppDir).Any() && !Directory.EnumerateFiles(AppDir).Any())
Directory.Delete(AppDir);
}
//// if moving from default, delete old settings file and dir (if empty)
//if (LibationFiles.EqualsInsensitive(AppDir))
//{
// File.Delete(SettingsFilePath);
// System.Threading.Thread.Sleep(100);
// if (!Directory.EnumerateDirectories(AppDir).Any() && !Directory.EnumerateFiles(AppDir).Any())
// Directory.Delete(AppDir);
//}
libationFilesPathCache = null;
var contents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(contents);
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(startingContents);
jObj[LIBATION_FILES] = directory;
jObj[LIBATION_FILES_KEY] = directory;
var output = JsonConvert.SerializeObject(jObj, Formatting.Indented);
File.WriteAllText(APPSETTINGS_JSON, output);
var endingContents = JsonConvert.SerializeObject(jObj, Formatting.Indented);
if (startingContents != endingContents)
File.WriteAllText(APPSETTINGS_JSON, endingContents);
return true;

View File

@@ -5,7 +5,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.33" />
<PackageReference Include="Octokit" Version="0.50.0" />
<PackageReference Include="Polly" Version="7.2.2" />
</ItemGroup>

View File

@@ -100,8 +100,13 @@ namespace FileManager
lock (locker)
{
var jObject = readFile();
var startContents = JsonConvert.SerializeObject(jObject, Formatting.Indented);
jObject[propertyName] = newValue;
File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
var endContents = JsonConvert.SerializeObject(jObject, Formatting.Indented);
if (startContents != endContents)
File.WriteAllText(Filepath, endContents);
}
}
@@ -112,10 +117,13 @@ namespace FileManager
{
var jObject = readFile();
var token = jObject.SelectToken(jsonPath);
var debug_oldValue = (string)token[propertyName];
var oldValue = (string)token[propertyName];
token[propertyName] = newValue;
File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
if (oldValue != newValue)
{
token[propertyName] = newValue;
File.WriteAllText(Filepath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
}
}
}

View File

@@ -86,6 +86,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibationSearchEngine.Tests"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dinah.EntityFrameworkCore.Tests", "..\Dinah.Core\_Tests\Dinah.EntityFrameworkCore.Tests\Dinah.EntityFrameworkCore.Tests.csproj", "{6F5131A0-09AE-4707-B82B-5E53CB74688E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AAXClean", "..\AAXClean\AAXClean.csproj", "{94BEB7CC-511D-45AB-9F09-09BE858EE486}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -208,6 +210,10 @@ Global
{6F5131A0-09AE-4707-B82B-5E53CB74688E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F5131A0-09AE-4707-B82B-5E53CB74688E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F5131A0-09AE-4707-B82B-5E53CB74688E}.Release|Any CPU.Build.0 = Release|Any CPU
{94BEB7CC-511D-45AB-9F09-09BE858EE486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94BEB7CC-511D-45AB-9F09-09BE858EE486}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94BEB7CC-511D-45AB-9F09-09BE858EE486}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94BEB7CC-511D-45AB-9F09-09BE858EE486}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -242,6 +248,7 @@ Global
{8447C956-B03E-4F59-9DD4-877793B849D9} = {67E66E82-5532-4440-AFB3-9FB1DF9DEF53}
{C5B21768-C7C9-4FCB-AC1E-187B223D5A98} = {67E66E82-5532-4440-AFB3-9FB1DF9DEF53}
{6F5131A0-09AE-4707-B82B-5E53CB74688E} = {38E6C6D9-963A-4C5B-89F4-F2F14885ADFD}
{94BEB7CC-511D-45AB-9F09-09BE858EE486} = {7FBBB086-0807-4998-85BF-6D1A49C8AD05}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {615E00ED-BAEF-4E8E-A92A-9B82D87942A9}

View File

@@ -13,7 +13,7 @@
<!-- <PublishSingleFile>true</PublishSingleFile> -->
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Version>5.1.0.1</Version>
<Version>5.1.10.1</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Windows.Forms;
using AudibleApi;
using AudibleApi.Authorization;
using Dinah.Core.Logging;
using FileManager;
using InternalUtilities;
using LibationWinForms;
@@ -24,6 +25,9 @@ namespace LibationLauncher
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// must occur before access to Configuration instance
migrate_to_v5_2_0();
createSettings();
AudibleApiStorage.EnsureAccountsSettingsFileExists();
@@ -31,7 +35,6 @@ namespace LibationLauncher
migrate_to_v4_0_0();
migrate_to_v5_0_0();
ensureLoggingConfig();
ensureSerilogConfig();
configureLogging();
checkForUpdate();
@@ -56,9 +59,9 @@ namespace LibationLauncher
var setupDialog = new SetupDialog();
setupDialog.NoQuestionsBtn_Click += (_, __) =>
{
config.DownloadsInProgressEnum ??= "WinTemp";
config.DecryptInProgressEnum ??= "WinTemp";
config.Books ??= Configuration.AppDir;
config.DownloadsInProgressEnum ??= Configuration.WIN_TEMP_LABEL;
config.DecryptInProgressEnum ??= Configuration.WIN_TEMP_LABEL;
config.Books ??= Configuration.AppDir_Relative;
config.AllowLibationFixup = true;
};
// setupDialog.BasicBtn_Click += (_, __) => // no action needed
@@ -155,7 +158,7 @@ namespace LibationLauncher
// identity has likely been updated above. re-get contents
var legacyContents = File.ReadAllText(AccountsSettingsFileLegacy30);
var identity = AudibleApi.Authorization.Identity.FromJson(legacyContents);
var identity = Identity.FromJson(legacyContents);
if (!identity.IsValid)
return null;
@@ -255,30 +258,41 @@ namespace LibationLauncher
}
}
}
#endregion
#endregion
private static string defaultLoggingLevel { get; } = "Information";
private static void ensureLoggingConfig()
#region migrate to v5.2.0 : get rid of meta-directories, combine DownloadsInProgressEnum and DecryptInProgressEnum => InProgress
private static void migrate_to_v5_2_0()
{
var config = Configuration.Instance;
if (config.GetObject("Logging") != null)
return;
// "Logging": {
// "LogLevel": {
// "Default": "Debug"
// }
// }
var loggingObj = new JObject
{
{
"LogLevel", new JObject { { "Default", defaultLoggingLevel } }
}
};
config.SetObject("Logging", loggingObj);
var settingsKey = "DownloadsInProgressEnum";
if (UNSAFE_MigrationHelper.Settings_TryGet(settingsKey, out var value))
UNSAFE_MigrationHelper.Settings_Update(settingsKey, translatePath(value));
}
{
var settingsKey = "DecryptInProgressEnum";
if (UNSAFE_MigrationHelper.Settings_TryGet(settingsKey, out var value))
UNSAFE_MigrationHelper.Settings_Update(settingsKey, translatePath(value));
}
{ // appsettings.json
var appSettingsKey = UNSAFE_MigrationHelper.LIBATION_FILES_KEY;
if (UNSAFE_MigrationHelper.APPSETTINGS_TryGet(appSettingsKey, out var value))
UNSAFE_MigrationHelper.APPSETTINGS_Update(appSettingsKey, translatePath(value));
}
}
private static string translatePath(string path)
=> path switch
{
"AppDir" => @".\LibationFiles",
"MyDocs" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles")),
"UserProfile" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation")),
"WinTemp" => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation")),
_ => path
};
#endregion
private static void ensureSerilogConfig()
{
var config = Configuration.Instance;
@@ -286,13 +300,6 @@ namespace LibationLauncher
if (config.GetObject("Serilog") != null)
return;
// default. for reference. output example:
// 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation
var default_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
// with class and method info. output example:
// 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForms.Program.init()) Begin Libation
var code_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}";
// "Serilog": {
// "MinimumLevel": "Information"
// "WriteTo": [
@@ -312,7 +319,7 @@ namespace LibationLauncher
// }
var serilogObj = new JObject
{
{ "MinimumLevel", defaultLoggingLevel },
{ "MinimumLevel", "Information" },
{ "WriteTo", new JArray
{
new JObject { {"Name", "Console" } },
@@ -325,7 +332,12 @@ namespace LibationLauncher
// for this sink to work, a path must be provided. we override this below
{ "path", Path.Combine(Configuration.Instance.LibationFiles, "_Log.log") },
{ "rollingInterval", "Month" },
{ "outputTemplate", code_outputTemplate }
// Serilog template formatting examples
// - default: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation
// - with class and method info: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}";
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForms.Program.init()) Begin Libation
{ "outputTemplate", "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}" }
}
}
}
@@ -379,7 +391,7 @@ namespace LibationLauncher
// https://octokitnet.readthedocs.io/en/latest/releases/
var releases = gitHubClient.Repository.Release.GetAll("rmcrackan", "Libation").GetAwaiter().GetResult();
var latest = releases.First(r => !r.Draft);
var latest = releases.First(r => !r.Draft && !r.Prerelease);
var latestVersionString = latest.TagName.Trim('v');
if (!Version.TryParse(latestVersionString, out var latestRelease))
@@ -409,8 +421,7 @@ namespace LibationLauncher
try
{
LibationWinForms.BookLiberation.ProcessorAutomationController.DownloadFileAsync(zipUrl, selectedPath).GetAwaiter().GetResult();
MessageBox.Show("File downloaded");
LibationWinForms.BookLiberation.ProcessorAutomationController.DownloadFile(zipUrl, selectedPath, true);
}
catch (Exception ex)
{
@@ -433,10 +444,19 @@ namespace LibationLauncher
{
var config = Configuration.Instance;
// begin logging session with a form feed
Log.Logger.Information("\r\n\f");
Log.Logger.Information("Begin Libation. {@DebugInfo}", new
{
Version = BuildVersion.ToString(),
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.LibationFiles,
AudibleFileStorage.BooksDirectory,
@@ -444,13 +464,24 @@ namespace LibationLauncher
DownloadsInProgressDir = AudibleFileStorage.DownloadsInProgress,
DownloadsInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsInProgress).Count(),
AudibleFileStorage.DownloadsFinal,
DownloadsFinalFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsFinal).Count(),
config.DecryptInProgressEnum,
DecryptInProgressDir = AudibleFileStorage.DecryptInProgress,
DecryptInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DecryptInProgress).Count(),
});
// when turning on debug (and especially Verbose) to share logs, some privacy settings may not be obscured
if (Log.Logger.IsVerboseEnabled())
MessageBox.Show(@"
Warning: verbose logging is enabled.
This should be used for debugging only. It creates many
more logs and debug files, neither of which are as
strictly anonomous.
When you are finished debugging, it's highly recommended
to set your debug MinimumLevel to Information and restart
Libation.
".Trim(), "Verbose logging enabled", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
private static Version BuildVersion => System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

View File

@@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Dinah.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace LibationLauncher
{
/// <summary>for migrations only. directly manipulatings settings files without going through domain logic</summary>
internal static class UNSAFE_MigrationHelper
{
#region appsettings.json
private const string APPSETTINGS_JSON = "appsettings.json";
public static bool APPSETTINGS_Json_Exists => File.Exists(APPSETTINGS_JSON);
public static bool APPSETTINGS_TryGet(string key, out string value)
{
bool success = false;
JToken val = null;
process_APPSETTINGS_Json(jObj => success = jObj.TryGetValue(key, out val), false);
value = success ? val.Value<string>() : null;
return success;
}
/// <summary>only insert if not exists</summary>
public static void APPSETTINGS_Insert(string key, string value)
=> process_APPSETTINGS_Json(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void APPSETTINGS_Update(string key, string value)
=> process_APPSETTINGS_Json(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void APPSETTINGS_Delete(string key)
=> process_APPSETTINGS_Json(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_APPSETTINGS_Json(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!APPSETTINGS_Json_Exists)
return;
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(APPSETTINGS_JSON, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
#region Settings.json
public const string LIBATION_FILES_KEY = "LibationFiles";
private const string SETTINGS_JSON = "Settings.json";
public static string SettingsJsonPath
{
get
{
var success = APPSETTINGS_TryGet(LIBATION_FILES_KEY, out var value);
return !success || value is null ? null : Path.Combine(value, SETTINGS_JSON);
}
}
public static bool SettingsJson_Exists => SettingsJsonPath is not null && File.Exists(SettingsJsonPath);
public static bool Settings_TryGet(string key, out string value)
{
bool success = false;
JToken val = null;
process_SettingsJson(jObj => success = jObj.TryGetValue(key, out val), false);
value = success ? val.Value<string>() : null;
return success;
}
/// <summary>only insert if not exists</summary>
public static void Settings_Insert(string key, string value)
=> process_SettingsJson(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void Settings_Update(string key, string value)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void Settings_Delete(string key)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_SettingsJson(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!SettingsJson_Exists)
return;
var startingContents = File.ReadAllText(SettingsJsonPath);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(SettingsJsonPath, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
}
}

View File

@@ -6,18 +6,9 @@ namespace LibationWinForms.BookLiberation
{
public partial class AutomatedBackupsForm : Form
{
public bool KeepGoingVisible
{
get => keepGoingCb.Visible;
set => keepGoingCb.Visible = value;
}
public bool KeepGoingChecked => keepGoingCb.Checked;
public bool KeepGoing
=> keepGoingCb.Visible
&& keepGoingCb.Enabled
&& keepGoingCb.Checked;
public bool KeepGoing => keepGoingCb.Enabled && keepGoingCb.Checked;
public AutomatedBackupsForm()
{

View File

@@ -64,14 +64,8 @@ namespace LibationWinForms.BookLiberation
if (percentage == 0)
remainingTimeLbl.UIThread(() => remainingTimeLbl.Text = "ETA:\r\n0 sec");
if (percentage == int.MaxValue)
progressBar1.UIThread(() => progressBar1.Style = ProgressBarStyle.Marquee);
else
progressBar1.UIThread(() =>
{
progressBar1.Value = percentage;
progressBar1.Style = ProgressBarStyle.Blocks;
});
progressBar1.UIThread(() => progressBar1.Value = percentage);
}
public void UpdateRemainingTime(TimeSpan remaining)

View File

@@ -43,14 +43,14 @@ namespace LibationWinForms.BookLiberation
private void timer_Tick(object sender, EventArgs e)
{
// if no update in the last 30 seconds, display frozen label
lastUpdateLbl.Visible = lastDownloadProgress.AddSeconds(30) < DateTime.Now;
lastUpdateLbl.UIThread(() => lastUpdateLbl.Visible = lastDownloadProgress.AddSeconds(30) < DateTime.Now);
if (lastUpdateLbl.Visible)
{
var diff = lastDownloadProgress - DateTime.Now;
var diff = DateTime.Now - lastDownloadProgress;
var min = (int)diff.TotalMinutes;
var minText = min > 0 ? $"{min}min " : "";
lastUpdateLbl.Text = $"Frozen? Last download activity: {minText}{diff.Seconds}sec ago";
lastUpdateLbl.UIThread(() => lastUpdateLbl.Text = $"Frozen? Last download activity: {minText}{diff.Seconds}sec ago");
}
}
private void DownloadForm_FormClosing(object sender, FormClosingEventArgs e) => timer.Stop();

View File

@@ -4,6 +4,7 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using DataLayer;
using Dinah.Core.ErrorHandling;
using Dinah.Core.Windows.Forms;
using FileLiberator;
namespace LibationWinForms.BookLiberation
@@ -168,21 +169,27 @@ namespace LibationWinForms.BookLiberation
return downloadPdf;
}
public static async Task DownloadFileAsync(string url, string destination)
public static void DownloadFile(string url, string destination, bool showDownloadCompletedDialog = false)
{
var downloadFile = new DownloadFile();
// frustratingly copy pasta from wireUpEvents(IDownloadable downloadable) due to Completed being EventHandler<LibraryBook>
var downloadDialog = new DownloadForm();
downloadFile.DownloadBegin += (_, str) =>
{
downloadDialog.UpdateFilename(str);
downloadDialog.Show();
};
downloadFile.DownloadProgressChanged += (_, progress) => downloadDialog.DownloadProgressChanged(progress.BytesReceived, progress.TotalBytesToReceive);
downloadFile.DownloadCompleted += (_, __) => downloadDialog.Close();
downloadDialog.UpdateFilename(destination);
downloadDialog.Show();
await downloadFile.PerformDownloadFileAsync(url, destination);
new System.Threading.Thread(() => {
var downloadFile = new DownloadFile();
downloadFile.DownloadProgressChanged += (_, progress) => downloadDialog.UIThread(() =>
downloadDialog.DownloadProgressChanged(progress.BytesReceived, progress.TotalBytesToReceive)
);
downloadFile.DownloadCompleted += (_, __) => downloadDialog.UIThread(() =>
{
downloadDialog.Close();
if (showDownloadCompletedDialog)
MessageBox.Show("File downloaded");
});
downloadFile.PerformDownloadFileAsync(url, destination).GetAwaiter().GetResult();
}).Start();
}
// subscribed to Begin event because a new form should be created+processed+closed on each iteration
@@ -508,7 +515,7 @@ An error occurred while trying to process this book
if (!AutomatedBackupsForm.KeepGoing)
{
if (AutomatedBackupsForm.KeepGoingVisible && !AutomatedBackupsForm.KeepGoingChecked)
if (!AutomatedBackupsForm.KeepGoingChecked)
LogMe.Info("'Keep going' is unchecked");
return;
}

View File

@@ -94,7 +94,11 @@ namespace LibationWinForms.Dialogs
}
}
private void cancelBtn_Click(object sender, EventArgs e) => this.Close();
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
class AccountDto
{

View File

@@ -0,0 +1,113 @@

namespace LibationWinForms.Dialogs
{
partial class DirectoryOrCustomSelectControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.knownDirectoryRb = new System.Windows.Forms.RadioButton();
this.customDirectoryRb = new System.Windows.Forms.RadioButton();
this.customTb = new System.Windows.Forms.TextBox();
this.customBtn = new System.Windows.Forms.Button();
this.directorySelectControl = new LibationWinForms.Dialogs.DirectorySelectControl();
this.SuspendLayout();
//
// knownDirectoryRb
//
this.knownDirectoryRb.AutoSize = true;
this.knownDirectoryRb.Location = new System.Drawing.Point(3, 3);
this.knownDirectoryRb.Name = "knownDirectoryRb";
this.knownDirectoryRb.Size = new System.Drawing.Size(14, 13);
this.knownDirectoryRb.TabIndex = 0;
this.knownDirectoryRb.UseVisualStyleBackColor = true;
this.knownDirectoryRb.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged);
//
// customDirectoryRb
//
this.customDirectoryRb.AutoSize = true;
this.customDirectoryRb.Location = new System.Drawing.Point(2, 56);
this.customDirectoryRb.Name = "customDirectoryRb";
this.customDirectoryRb.Size = new System.Drawing.Size(14, 13);
this.customDirectoryRb.TabIndex = 2;
this.customDirectoryRb.UseVisualStyleBackColor = true;
this.customDirectoryRb.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged);
//
// customTb
//
this.customTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.customTb.Location = new System.Drawing.Point(22, 52);
this.customTb.Name = "customTb";
this.customTb.Size = new System.Drawing.Size(588, 23);
this.customTb.TabIndex = 3;
//
// customBtn
//
this.customBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.customBtn.Location = new System.Drawing.Point(616, 52);
this.customBtn.Name = "customBtn";
this.customBtn.Size = new System.Drawing.Size(41, 27);
this.customBtn.TabIndex = 4;
this.customBtn.Text = "...";
this.customBtn.UseVisualStyleBackColor = true;
this.customBtn.Click += new System.EventHandler(this.customBtn_Click);
//
// directorySelectControl
//
this.directorySelectControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.directorySelectControl.Location = new System.Drawing.Point(23, 0);
this.directorySelectControl.Name = "directorySelectControl";
this.directorySelectControl.Size = new System.Drawing.Size(635, 46);
this.directorySelectControl.TabIndex = 5;
//
// DirectoryOrCustomSelectControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.directorySelectControl);
this.Controls.Add(this.customBtn);
this.Controls.Add(this.customTb);
this.Controls.Add(this.customDirectoryRb);
this.Controls.Add(this.knownDirectoryRb);
this.Name = "DirectoryOrCustomSelectControl";
this.Size = new System.Drawing.Size(660, 81);
this.Load += new System.EventHandler(this.DirectoryOrCustomSelectControl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.RadioButton knownDirectoryRb;
private System.Windows.Forms.RadioButton customDirectoryRb;
private System.Windows.Forms.TextBox customTb;
private System.Windows.Forms.Button customBtn;
private DirectorySelectControl directorySelectControl;
}
}

View File

@@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Dinah.Core;
using FileManager;
namespace LibationWinForms.Dialogs
{
public partial class DirectoryOrCustomSelectControl : UserControl
{
public string SelectedDirectory
=> customDirectoryRb.Checked ? customTb.Text.Trim()
: knownDirectoryRb.Checked ? directorySelectControl.SelectedDirectory
: null;
public DirectoryOrCustomSelectControl()
{
InitializeComponent();
// doing this after InitializeComponent will fire event
this.knownDirectoryRb.Checked = true;
}
/// <summary>Set items for combobox</summary>
/// <param name="knownDirectories">List rather than IEnumerable so that client can determine display order</param>
/// <param name="defaultDirectory"></param>
public void SetDirectoryItems(List<Configuration.KnownDirectories> knownDirectories, Configuration.KnownDirectories? defaultDirectory = Configuration.KnownDirectories.UserProfile)
=> this.directorySelectControl.SetDirectoryItems(knownDirectories, defaultDirectory);
/// <summary>set selection</summary>
/// <param name="directory"></param>
public void SelectDirectory(Configuration.KnownDirectories directory)
{
// if None: take no action
if (directory != Configuration.KnownDirectories.None)
selectDir(directory, null);
}
/// <summary>set selection</summary>
public void SelectDirectory(string directory)
{
directory = directory?.Trim() ?? "";
selectDir(Configuration.GetKnownDirectory(directory), directory);
}
private void selectDir(Configuration.KnownDirectories knownDir, string customDir)
{
var isKnown
= knownDir != Configuration.KnownDirectories.None
// this could be a well known dir which isn't an option in this particular dropdown. This will always be true of LibationFiles
&& this.directorySelectControl.SelectDirectory(knownDir);
customDirectoryRb.Checked = !isKnown;
knownDirectoryRb.Checked = isKnown;
this.customTb.Text = isKnown ? "" : customDir;
}
private string dirSearchTitle;
public void SetSearchTitle(string dirSearchTitle) => this.dirSearchTitle = dirSearchTitle?.Trim();
private void customBtn_Click(object sender, EventArgs e)
{
using var dialog = new FolderBrowserDialog
{
Description = string.IsNullOrWhiteSpace(dirSearchTitle) ? "Search" : $"Search for {dirSearchTitle}",
SelectedPath = this.customTb.Text
};
dialog.ShowDialog();
if (!string.IsNullOrWhiteSpace(dialog.SelectedPath))
this.customTb.Text = dialog.SelectedPath;
}
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
var isCustom = this.customDirectoryRb.Checked;
customTb.Enabled = isCustom;
customBtn.Enabled = isCustom;
directorySelectControl.Enabled = !isCustom;
}
private void DirectoryOrCustomSelectControl_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,76 @@

namespace LibationWinForms.Dialogs
{
partial class DirectorySelectControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.directoryComboBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// directoryComboBox
//
this.directoryComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.directoryComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.directoryComboBox.FormattingEnabled = true;
this.directoryComboBox.Location = new System.Drawing.Point(0, 0);
this.directoryComboBox.Name = "directoryComboBox";
this.directoryComboBox.Size = new System.Drawing.Size(647, 23);
this.directoryComboBox.TabIndex = 0;
this.directoryComboBox.SelectedIndexChanged += new System.EventHandler(this.directoryComboBox_SelectedIndexChanged);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(0, 26);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(97, 15);
this.label1.TabIndex = 1;
this.label1.Text = "Select a directory";
//
// DirectorySelectControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label1);
this.Controls.Add(this.directoryComboBox);
this.Name = "DirectorySelectControl";
this.Size = new System.Drawing.Size(647, 46);
this.Load += new System.EventHandler(this.DirectorySelectControl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.ComboBox directoryComboBox;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Dinah.Core;
using FileManager;
namespace LibationWinForms.Dialogs
{
public partial class DirectorySelectControl : UserControl
{
private class DirectoryComboBoxItem
{
public string Description { get; }
public Configuration.KnownDirectories Value { get; }
public string FullPath => Configuration.GetKnownDirectoryPath(Value);
/// <summary>Displaying relative paths is confusing. UI should display absolute equivalent</summary>
public string UiDisplayPath => Value == Configuration.KnownDirectories.AppDir ? Configuration.AppDir_Absolute : FullPath;
public DirectoryComboBoxItem(Configuration.KnownDirectories knownDirectory)
{
Value = knownDirectory;
Description = Value.GetDescription();
}
public override string ToString() => Description;
}
private DirectoryComboBoxItem selectedItem => (DirectoryComboBoxItem)this.directoryComboBox.SelectedItem;
public string SelectedDirectory => selectedItem?.FullPath;
public DirectorySelectControl() => InitializeComponent();
/// <summary>Set items for combobox</summary>
/// <param name="knownDirectories">List rather than IEnumerable so that client can determine display order</param>
/// <param name="defaultDirectory">Optional default item to select</param>
public void SetDirectoryItems(List<Configuration.KnownDirectories> knownDirectories, Configuration.KnownDirectories? defaultDirectory = null)
{
this.directoryComboBox.Items.Clear();
foreach (var dir in knownDirectories.Where(d => d != Configuration.KnownDirectories.None).Distinct())
this.directoryComboBox.Items.Add(new DirectoryComboBoxItem(dir));
SelectDirectory(defaultDirectory);
}
/// <summary>set selection</summary>
/// <param name="directory"></param>
/// <returns>True is there was a matching entry</returns>
public bool SelectDirectory(string directory) => SelectDirectory(Configuration.GetKnownDirectory(directory));
/// <summary>set selection</summary>
/// <param name="directory"></param>
/// <returns>True is there was a matching entry</returns>
public bool SelectDirectory(Configuration.KnownDirectories? directory)
{
if (directory is null || directory == Configuration.KnownDirectories.None)
return false;
// set default
var item = this.directoryComboBox.Items.Cast<DirectoryComboBoxItem>().SingleOrDefault(item => item.Value == directory.Value);
if (item is null)
return false;
this.directoryComboBox.SelectedItem = item;
return true;
}
private void DirectorySelectControl_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
}
private void directoryComboBox_SelectedIndexChanged(object sender, EventArgs e) => this.label1.Text = selectedItem.UiDisplayPath;
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -59,7 +59,11 @@ namespace LibationWinForms.Dialogs
this.Close();
}
private void cancelBtn_Click(object sender, EventArgs e) => this.Close();
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{

View File

@@ -29,85 +29,29 @@
private void InitializeComponent()
{
this.libationFilesDescLbl = new System.Windows.Forms.Label();
this.libationFilesCustomBtn = new System.Windows.Forms.Button();
this.libationFilesCustomTb = new System.Windows.Forms.TextBox();
this.libationFilesCustomRb = new System.Windows.Forms.RadioButton();
this.libationFilesMyDocsRb = new System.Windows.Forms.RadioButton();
this.libationFilesRootRb = new System.Windows.Forms.RadioButton();
this.cancelBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button();
this.directoryOrCustomSelectControl = new LibationWinForms.Dialogs.DirectoryOrCustomSelectControl();
this.SuspendLayout();
//
// libationFilesDescLbl
//
this.libationFilesDescLbl.AutoSize = true;
this.libationFilesDescLbl.Location = new System.Drawing.Point(12, 9);
this.libationFilesDescLbl.Location = new System.Drawing.Point(14, 10);
this.libationFilesDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.libationFilesDescLbl.Name = "libationFilesDescLbl";
this.libationFilesDescLbl.Size = new System.Drawing.Size(36, 13);
this.libationFilesDescLbl.Size = new System.Drawing.Size(39, 15);
this.libationFilesDescLbl.TabIndex = 0;
this.libationFilesDescLbl.Text = "[desc]";
//
// libationFilesCustomBtn
//
this.libationFilesCustomBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.libationFilesCustomBtn.Location = new System.Drawing.Point(753, 95);
this.libationFilesCustomBtn.Name = "libationFilesCustomBtn";
this.libationFilesCustomBtn.Size = new System.Drawing.Size(35, 23);
this.libationFilesCustomBtn.TabIndex = 5;
this.libationFilesCustomBtn.Text = "...";
this.libationFilesCustomBtn.UseVisualStyleBackColor = true;
this.libationFilesCustomBtn.Click += new System.EventHandler(this.libationFilesCustomBtn_Click);
//
// libationFilesCustomTb
//
this.libationFilesCustomTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.libationFilesCustomTb.Location = new System.Drawing.Point(35, 97);
this.libationFilesCustomTb.Name = "libationFilesCustomTb";
this.libationFilesCustomTb.Size = new System.Drawing.Size(712, 20);
this.libationFilesCustomTb.TabIndex = 4;
//
// libationFilesCustomRb
//
this.libationFilesCustomRb.AutoSize = true;
this.libationFilesCustomRb.Location = new System.Drawing.Point(15, 100);
this.libationFilesCustomRb.Name = "libationFilesCustomRb";
this.libationFilesCustomRb.Size = new System.Drawing.Size(14, 13);
this.libationFilesCustomRb.TabIndex = 3;
this.libationFilesCustomRb.TabStop = true;
this.libationFilesCustomRb.UseVisualStyleBackColor = true;
//
// libationFilesMyDocsRb
//
this.libationFilesMyDocsRb.AutoSize = true;
this.libationFilesMyDocsRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.libationFilesMyDocsRb.Location = new System.Drawing.Point(15, 61);
this.libationFilesMyDocsRb.Name = "libationFilesMyDocsRb";
this.libationFilesMyDocsRb.Size = new System.Drawing.Size(111, 30);
this.libationFilesMyDocsRb.TabIndex = 2;
this.libationFilesMyDocsRb.TabStop = true;
this.libationFilesMyDocsRb.Text = "[desc]\r\n[myDocs\\Libation]";
this.libationFilesMyDocsRb.UseVisualStyleBackColor = true;
//
// libationFilesRootRb
//
this.libationFilesRootRb.AutoSize = true;
this.libationFilesRootRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.libationFilesRootRb.Location = new System.Drawing.Point(15, 25);
this.libationFilesRootRb.Name = "libationFilesRootRb";
this.libationFilesRootRb.Size = new System.Drawing.Size(113, 30);
this.libationFilesRootRb.TabIndex = 1;
this.libationFilesRootRb.TabStop = true;
this.libationFilesRootRb.Text = "[desc]\r\n[appDir\\Libation]";
this.libationFilesRootRb.UseVisualStyleBackColor = true;
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(713, 124);
this.cancelBtn.Location = new System.Drawing.Point(832, 118);
this.cancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(75, 23);
this.cancelBtn.Size = new System.Drawing.Size(88, 27);
this.cancelBtn.TabIndex = 10;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
@@ -116,28 +60,35 @@
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(612, 124);
this.saveBtn.Location = new System.Drawing.Point(714, 118);
this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(75, 23);
this.saveBtn.Size = new System.Drawing.Size(88, 27);
this.saveBtn.TabIndex = 9;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
//
// directoryOrCustomSelectControl
//
this.directoryOrCustomSelectControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.directoryOrCustomSelectControl.Location = new System.Drawing.Point(14, 28);
this.directoryOrCustomSelectControl.Name = "directoryOrCustomSelectControl";
this.directoryOrCustomSelectControl.Size = new System.Drawing.Size(909, 81);
this.directoryOrCustomSelectControl.TabIndex = 11;
//
// LibationFilesDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 159);
this.ClientSize = new System.Drawing.Size(933, 158);
this.Controls.Add(this.directoryOrCustomSelectControl);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.saveBtn);
this.Controls.Add(this.libationFilesDescLbl);
this.Controls.Add(this.libationFilesCustomBtn);
this.Controls.Add(this.libationFilesCustomTb);
this.Controls.Add(this.libationFilesRootRb);
this.Controls.Add(this.libationFilesCustomRb);
this.Controls.Add(this.libationFilesMyDocsRb);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "LibationFilesDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Libation Files location";
@@ -150,12 +101,8 @@
#endregion
private System.Windows.Forms.Label libationFilesDescLbl;
private System.Windows.Forms.Button libationFilesCustomBtn;
private System.Windows.Forms.TextBox libationFilesCustomTb;
private System.Windows.Forms.RadioButton libationFilesCustomRb;
private System.Windows.Forms.RadioButton libationFilesMyDocsRb;
private System.Windows.Forms.RadioButton libationFilesRootRb;
private System.Windows.Forms.Button cancelBtn;
private System.Windows.Forms.Button saveBtn;
private DirectoryOrCustomSelectControl directoryOrCustomSelectControl;
}
}

View File

@@ -6,52 +6,31 @@ namespace LibationWinForms.Dialogs
{
public partial class LibationFilesDialog : Form
{
Configuration config { get; } = Configuration.Instance;
Func<string, string> desc { get; } = Configuration.GetDescription;
private Configuration config { get; } = Configuration.Instance;
private Func<string, string> desc { get; } = Configuration.GetDescription;
public LibationFilesDialog()
{
InitializeComponent();
this.libationFilesCustomTb.TextChanged += (_, __) =>
{
if (!string.IsNullOrWhiteSpace(libationFilesCustomTb.Text))
this.libationFilesCustomRb.Checked = true;
};
}
public LibationFilesDialog() => InitializeComponent();
private void LibationFilesDialog_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
libationFilesDescLbl.Text = desc(nameof(config.LibationFiles));
this.libationFilesRootRb.Text = "In the same folder that Libation is running from\r\n" + Configuration.AppDir;
this.libationFilesMyDocsRb.Text = "In My Documents\r\n" + Configuration.MyDocs;
if (config.LibationFiles == Configuration.AppDir)
libationFilesRootRb.Checked = true;
else if (config.LibationFiles == Configuration.MyDocs)
libationFilesMyDocsRb.Checked = true;
else
directoryOrCustomSelectControl.SetSearchTitle("Libation Files");
directoryOrCustomSelectControl.SetDirectoryItems(new()
{
libationFilesCustomRb.Checked = true;
libationFilesCustomTb.Text = config.LibationFiles;
}
}
private void libationFilesCustomBtn_Click(object sender, EventArgs e) => selectFolder("Search for Libation Files location", this.libationFilesCustomTb);
private static void selectFolder(string desc, TextBox textbox)
{
using var dialog = new FolderBrowserDialog { Description = desc, SelectedPath = "" };
dialog.ShowDialog();
if (!string.IsNullOrWhiteSpace(dialog.SelectedPath))
textbox.Text = dialog.SelectedPath;
Configuration.KnownDirectories.UserProfile,
Configuration.KnownDirectories.AppDir,
Configuration.KnownDirectories.MyDocs
}, Configuration.KnownDirectories.UserProfile);
directoryOrCustomSelectControl.SelectDirectory(config.LibationFiles);
}
private void saveBtn_Click(object sender, EventArgs e)
{
var libationDir
= libationFilesRootRb.Checked ? Configuration.AppDir
: libationFilesMyDocsRb.Checked ? Configuration.MyDocs
: libationFilesCustomTb.Text;
var libationDir = directoryOrCustomSelectControl.SelectedDirectory;
if (!config.TrySetLibationFiles(libationDir))
{
MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + libationDir);
@@ -62,6 +41,10 @@ namespace LibationWinForms.Dialogs
this.Close();
}
private void cancelBtn_Click(object sender, EventArgs e) => this.Close();
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View File

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

View File

@@ -34,9 +34,11 @@
//
// approvedBtn
//
this.approvedBtn.Location = new System.Drawing.Point(15, 25);
this.approvedBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.approvedBtn.Location = new System.Drawing.Point(18, 75);
this.approvedBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.approvedBtn.Name = "approvedBtn";
this.approvedBtn.Size = new System.Drawing.Size(79, 23);
this.approvedBtn.Size = new System.Drawing.Size(92, 27);
this.approvedBtn.TabIndex = 1;
this.approvedBtn.Text = "Approved";
this.approvedBtn.UseVisualStyleBackColor = true;
@@ -45,27 +47,30 @@
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Location = new System.Drawing.Point(14, 10);
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(104, 13);
this.label1.Size = new System.Drawing.Size(314, 45);
this.label1.TabIndex = 0;
this.label1.Text = "Click after approving";
this.label1.Text = "Amazon is sending you an email.\r\n\r\nPlease press this button after you approve the" +
" notification.";
//
// ApprovalNeededDialog
//
this.AcceptButton = this.approvedBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(149, 60);
this.ClientSize = new System.Drawing.Size(345, 115);
this.Controls.Add(this.label1);
this.Controls.Add(this.approvedBtn);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ApprovalNeededDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Approval Needed";
this.Text = "Approval Alert Detected";
this.ResumeLayout(false);
this.PerformLayout();

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,113 @@

namespace LibationWinForms.Dialogs.Login
{
partial class MfaDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.submitBtn = new System.Windows.Forms.Button();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.radioButton3 = new System.Windows.Forms.RadioButton();
this.SuspendLayout();
//
// submitBtn
//
this.submitBtn.Location = new System.Drawing.Point(14, 93);
this.submitBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.submitBtn.Name = "submitBtn";
this.submitBtn.Size = new System.Drawing.Size(88, 27);
this.submitBtn.TabIndex = 3;
this.submitBtn.Text = "Submit";
this.submitBtn.UseVisualStyleBackColor = true;
this.submitBtn.Click += new System.EventHandler(this.submitBtn_Click);
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.Checked = true;
this.radioButton1.Location = new System.Drawing.Point(14, 14);
this.radioButton1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(242, 19);
this.radioButton1.TabIndex = 0;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "Enter the OTP from the authenticator app";
this.radioButton1.UseVisualStyleBackColor = true;
//
// radioButton2
//
this.radioButton2.AutoSize = true;
this.radioButton2.Location = new System.Drawing.Point(14, 40);
this.radioButton2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.radioButton2.Name = "radioButton2";
this.radioButton2.Size = new System.Drawing.Size(172, 19);
this.radioButton2.TabIndex = 1;
this.radioButton2.Text = "Send an SMS to my number";
this.radioButton2.UseVisualStyleBackColor = true;
//
// radioButton3
//
this.radioButton3.AutoSize = true;
this.radioButton3.Location = new System.Drawing.Point(14, 67);
this.radioButton3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.radioButton3.Name = "radioButton3";
this.radioButton3.Size = new System.Drawing.Size(147, 19);
this.radioButton3.TabIndex = 2;
this.radioButton3.Text = "Call me on my number";
this.radioButton3.UseVisualStyleBackColor = true;
//
// MfaDialog
//
this.AcceptButton = this.submitBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(398, 129);
this.Controls.Add(this.radioButton3);
this.Controls.Add(this.radioButton2);
this.Controls.Add(this.radioButton1);
this.Controls.Add(this.submitBtn);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "MfaDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Two-step verification";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button submitBtn;
private System.Windows.Forms.RadioButton radioButton1;
private System.Windows.Forms.RadioButton radioButton2;
private System.Windows.Forms.RadioButton radioButton3;
}
}

View File

@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LibationWinForms.Dialogs.Login
{
public partial class MfaDialog : Form
{
private RadioButton[] radioButtons { get; }
public MfaDialog(AudibleApi.MfaConfig mfaConfig)
{
InitializeComponent();
radioButtons = new[] { this.radioButton1, this.radioButton2, this.radioButton3 };
// optional string settings
if (!string.IsNullOrWhiteSpace(mfaConfig.Title))
this.Text = mfaConfig.Title;
setOptional(this.radioButton1, mfaConfig.Button1Text);
setOptional(this.radioButton2, mfaConfig.Button2Text);
setOptional(this.radioButton3, mfaConfig.Button3Text);
// mandatory values
radioButton1.Name = mfaConfig.Button1Name;
radioButton1.Tag = mfaConfig.Button1Value;
radioButton2.Name = mfaConfig.Button2Name;
radioButton2.Tag = mfaConfig.Button2Value;
radioButton3.Name = mfaConfig.Button3Name;
radioButton3.Tag = mfaConfig.Button3Value;
}
private static void setOptional(RadioButton radioButton, string text)
{
if (!string.IsNullOrWhiteSpace(text))
radioButton.Text = text;
}
public string SelectedName { get; private set; }
public string SelectedValue { get; private set; }
private void submitBtn_Click(object sender, EventArgs e)
{
Serilog.Log.Logger.Debug("RadioButton states: {@DebugInfo}", new {
rb1_checked = radioButton1.Checked,
r21_checked = radioButton2.Checked,
rb3_checked = radioButton3.Checked
});
var selected = radioButtons.Single(rb => rb.Checked);
Serilog.Log.Logger.Debug("Selected: {@DebugInfo}", new { isSelected = selected is not null, name = selected?.Name, value = selected?.Tag });
SelectedName = selected.Name;
SelectedValue = (string)selected.Tag;
DialogResult = DialogResult.OK;
// Close() not needed for AcceptButton
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -30,6 +30,14 @@ namespace LibationWinForms.Login
return null;
}
public (string name, string value) GetMfaChoice(MfaConfig mfaConfig)
{
using var dialog = new MfaDialog(mfaConfig);
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
return (dialog.SelectedName, dialog.SelectedValue);
return (null, null);
}
public (string email, string password) GetLogin()
{
using var dialog = new AudibleLoginDialog(_account);

View File

@@ -64,6 +64,10 @@ namespace LibationWinForms.Dialogs
this.Close();
}
private void cancelBtn_Click(object sender, EventArgs e) => this.Close();
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View File

@@ -28,243 +28,243 @@
/// </summary>
private void InitializeComponent()
{
this.booksLocationLbl = new System.Windows.Forms.Label();
this.booksLocationTb = new System.Windows.Forms.TextBox();
this.booksLocationSearchBtn = new System.Windows.Forms.Button();
this.booksLocationDescLbl = new System.Windows.Forms.Label();
this.downloadsInProgressGb = new System.Windows.Forms.GroupBox();
this.downloadsInProgressLibationFilesRb = new System.Windows.Forms.RadioButton();
this.downloadsInProgressWinTempRb = new System.Windows.Forms.RadioButton();
this.downloadsInProgressDescLbl = new System.Windows.Forms.Label();
this.decryptInProgressGb = new System.Windows.Forms.GroupBox();
this.decryptInProgressLibationFilesRb = new System.Windows.Forms.RadioButton();
this.decryptInProgressWinTempRb = new System.Windows.Forms.RadioButton();
this.decryptInProgressDescLbl = new System.Windows.Forms.Label();
this.saveBtn = new System.Windows.Forms.Button();
this.cancelBtn = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.allowLibationFixupCbox = new System.Windows.Forms.CheckBox();
this.downloadsInProgressGb.SuspendLayout();
this.decryptInProgressGb.SuspendLayout();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// booksLocationLbl
//
this.booksLocationLbl.AutoSize = true;
this.booksLocationLbl.Location = new System.Drawing.Point(14, 20);
this.booksLocationLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.booksLocationLbl.Name = "booksLocationLbl";
this.booksLocationLbl.Size = new System.Drawing.Size(85, 15);
this.booksLocationLbl.TabIndex = 0;
this.booksLocationLbl.Text = "Books location";
//
// booksLocationTb
//
this.booksLocationTb.Location = new System.Drawing.Point(111, 16);
this.booksLocationTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.booksLocationTb.Name = "booksLocationTb";
this.booksLocationTb.Size = new System.Drawing.Size(760, 23);
this.booksLocationTb.TabIndex = 1;
//
// booksLocationSearchBtn
//
this.booksLocationSearchBtn.Location = new System.Drawing.Point(878, 14);
this.booksLocationSearchBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.booksLocationSearchBtn.Name = "booksLocationSearchBtn";
this.booksLocationSearchBtn.Size = new System.Drawing.Size(41, 27);
this.booksLocationSearchBtn.TabIndex = 2;
this.booksLocationSearchBtn.Text = "...";
this.booksLocationSearchBtn.UseVisualStyleBackColor = true;
this.booksLocationSearchBtn.Click += new System.EventHandler(this.booksLocationSearchBtn_Click);
//
// booksLocationDescLbl
//
this.booksLocationDescLbl.AutoSize = true;
this.booksLocationDescLbl.Location = new System.Drawing.Point(107, 43);
this.booksLocationDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.booksLocationDescLbl.Name = "booksLocationDescLbl";
this.booksLocationDescLbl.Size = new System.Drawing.Size(39, 15);
this.booksLocationDescLbl.TabIndex = 3;
this.booksLocationDescLbl.Text = "[desc]";
//
// downloadsInProgressGb
//
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressLibationFilesRb);
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressWinTempRb);
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressDescLbl);
this.downloadsInProgressGb.Location = new System.Drawing.Point(10, 49);
this.downloadsInProgressGb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressGb.Name = "downloadsInProgressGb";
this.downloadsInProgressGb.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressGb.Size = new System.Drawing.Size(884, 135);
this.downloadsInProgressGb.TabIndex = 4;
this.downloadsInProgressGb.TabStop = false;
this.downloadsInProgressGb.Text = "Downloads in progress";
//
// downloadsInProgressLibationFilesRb
//
this.downloadsInProgressLibationFilesRb.AutoSize = true;
this.downloadsInProgressLibationFilesRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.downloadsInProgressLibationFilesRb.Location = new System.Drawing.Point(10, 93);
this.downloadsInProgressLibationFilesRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressLibationFilesRb.Name = "downloadsInProgressLibationFilesRb";
this.downloadsInProgressLibationFilesRb.Size = new System.Drawing.Size(215, 34);
this.downloadsInProgressLibationFilesRb.TabIndex = 2;
this.downloadsInProgressLibationFilesRb.TabStop = true;
this.downloadsInProgressLibationFilesRb.Text = "[desc]\r\n[libationFiles\\DownloadsInProgress]";
this.downloadsInProgressLibationFilesRb.UseVisualStyleBackColor = true;
//
// downloadsInProgressWinTempRb
//
this.downloadsInProgressWinTempRb.AutoSize = true;
this.downloadsInProgressWinTempRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.downloadsInProgressWinTempRb.Location = new System.Drawing.Point(10, 52);
this.downloadsInProgressWinTempRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressWinTempRb.Name = "downloadsInProgressWinTempRb";
this.downloadsInProgressWinTempRb.Size = new System.Drawing.Size(200, 34);
this.downloadsInProgressWinTempRb.TabIndex = 1;
this.downloadsInProgressWinTempRb.TabStop = true;
this.downloadsInProgressWinTempRb.Text = "[desc]\r\n[winTemp\\DownloadsInProgress]";
this.downloadsInProgressWinTempRb.UseVisualStyleBackColor = true;
//
// downloadsInProgressDescLbl
//
this.downloadsInProgressDescLbl.AutoSize = true;
this.downloadsInProgressDescLbl.Location = new System.Drawing.Point(7, 18);
this.downloadsInProgressDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.downloadsInProgressDescLbl.Name = "downloadsInProgressDescLbl";
this.downloadsInProgressDescLbl.Size = new System.Drawing.Size(43, 30);
this.downloadsInProgressDescLbl.TabIndex = 0;
this.downloadsInProgressDescLbl.Text = "[desc]\r\n[line 2]";
//
// decryptInProgressGb
//
this.decryptInProgressGb.Controls.Add(this.decryptInProgressLibationFilesRb);
this.decryptInProgressGb.Controls.Add(this.decryptInProgressWinTempRb);
this.decryptInProgressGb.Controls.Add(this.decryptInProgressDescLbl);
this.decryptInProgressGb.Location = new System.Drawing.Point(10, 193);
this.decryptInProgressGb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressGb.Name = "decryptInProgressGb";
this.decryptInProgressGb.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressGb.Size = new System.Drawing.Size(884, 135);
this.decryptInProgressGb.TabIndex = 5;
this.decryptInProgressGb.TabStop = false;
this.decryptInProgressGb.Text = "Decrypt in progress";
//
// decryptInProgressLibationFilesRb
//
this.decryptInProgressLibationFilesRb.AutoSize = true;
this.decryptInProgressLibationFilesRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.decryptInProgressLibationFilesRb.Location = new System.Drawing.Point(7, 93);
this.decryptInProgressLibationFilesRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressLibationFilesRb.Name = "decryptInProgressLibationFilesRb";
this.decryptInProgressLibationFilesRb.Size = new System.Drawing.Size(197, 34);
this.decryptInProgressLibationFilesRb.TabIndex = 2;
this.decryptInProgressLibationFilesRb.TabStop = true;
this.decryptInProgressLibationFilesRb.Text = "[desc]\r\n[libationFiles\\DecryptInProgress]";
this.decryptInProgressLibationFilesRb.UseVisualStyleBackColor = true;
//
// decryptInProgressWinTempRb
//
this.decryptInProgressWinTempRb.AutoSize = true;
this.decryptInProgressWinTempRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.decryptInProgressWinTempRb.Location = new System.Drawing.Point(7, 52);
this.decryptInProgressWinTempRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressWinTempRb.Name = "decryptInProgressWinTempRb";
this.decryptInProgressWinTempRb.Size = new System.Drawing.Size(182, 34);
this.decryptInProgressWinTempRb.TabIndex = 1;
this.decryptInProgressWinTempRb.TabStop = true;
this.decryptInProgressWinTempRb.Text = "[desc]\r\n[winTemp\\DecryptInProgress]";
this.decryptInProgressWinTempRb.UseVisualStyleBackColor = true;
//
// decryptInProgressDescLbl
//
this.decryptInProgressDescLbl.AutoSize = true;
this.decryptInProgressDescLbl.Location = new System.Drawing.Point(7, 18);
this.decryptInProgressDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.decryptInProgressDescLbl.Name = "decryptInProgressDescLbl";
this.decryptInProgressDescLbl.Size = new System.Drawing.Size(43, 30);
this.decryptInProgressDescLbl.TabIndex = 0;
this.decryptInProgressDescLbl.Text = "[desc]\r\n[line 2]";
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(714, 401);
this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(88, 27);
this.saveBtn.TabIndex = 7;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(832, 401);
this.cancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(88, 27);
this.cancelBtn.TabIndex = 8;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.allowLibationFixupCbox);
this.groupBox1.Controls.Add(this.downloadsInProgressGb);
this.groupBox1.Controls.Add(this.decryptInProgressGb);
this.groupBox1.Location = new System.Drawing.Point(18, 61);
this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.groupBox1.Size = new System.Drawing.Size(902, 334);
this.groupBox1.TabIndex = 6;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Advanced settings for control freaks";
//
// downloadChaptersCbox
//
this.allowLibationFixupCbox.AutoSize = true;
this.allowLibationFixupCbox.Location = new System.Drawing.Point(10, 24);
this.allowLibationFixupCbox.Name = "downloadChaptersCbox";
this.allowLibationFixupCbox.Size = new System.Drawing.Size(262, 19);
this.allowLibationFixupCbox.TabIndex = 6;
this.allowLibationFixupCbox.Text = "Allow Libation to fix up audiobook metadata";
this.allowLibationFixupCbox.UseVisualStyleBackColor = true;
//
// SettingsDialog
//
this.AcceptButton = this.saveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelBtn;
this.ClientSize = new System.Drawing.Size(933, 442);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.saveBtn);
this.Controls.Add(this.booksLocationDescLbl);
this.Controls.Add(this.booksLocationSearchBtn);
this.Controls.Add(this.booksLocationTb);
this.Controls.Add(this.booksLocationLbl);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "SettingsDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Edit Settings";
this.Load += new System.EventHandler(this.SettingsDialog_Load);
this.downloadsInProgressGb.ResumeLayout(false);
this.downloadsInProgressGb.PerformLayout();
this.decryptInProgressGb.ResumeLayout(false);
this.decryptInProgressGb.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
this.booksLocationLbl = new System.Windows.Forms.Label();
this.booksLocationTb = new System.Windows.Forms.TextBox();
this.booksLocationSearchBtn = new System.Windows.Forms.Button();
this.booksLocationDescLbl = new System.Windows.Forms.Label();
this.downloadsInProgressGb = new System.Windows.Forms.GroupBox();
this.downloadsInProgressLibationFilesRb = new System.Windows.Forms.RadioButton();
this.downloadsInProgressWinTempRb = new System.Windows.Forms.RadioButton();
this.downloadsInProgressDescLbl = new System.Windows.Forms.Label();
this.decryptInProgressGb = new System.Windows.Forms.GroupBox();
this.decryptInProgressLibationFilesRb = new System.Windows.Forms.RadioButton();
this.decryptInProgressWinTempRb = new System.Windows.Forms.RadioButton();
this.decryptInProgressDescLbl = new System.Windows.Forms.Label();
this.saveBtn = new System.Windows.Forms.Button();
this.cancelBtn = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.allowLibationFixupCbox = new System.Windows.Forms.CheckBox();
this.downloadsInProgressGb.SuspendLayout();
this.decryptInProgressGb.SuspendLayout();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// booksLocationLbl
//
this.booksLocationLbl.AutoSize = true;
this.booksLocationLbl.Location = new System.Drawing.Point(14, 20);
this.booksLocationLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.booksLocationLbl.Name = "booksLocationLbl";
this.booksLocationLbl.Size = new System.Drawing.Size(85, 15);
this.booksLocationLbl.TabIndex = 0;
this.booksLocationLbl.Text = "Books location";
//
// booksLocationTb
//
this.booksLocationTb.Location = new System.Drawing.Point(111, 16);
this.booksLocationTb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.booksLocationTb.Name = "booksLocationTb";
this.booksLocationTb.Size = new System.Drawing.Size(760, 23);
this.booksLocationTb.TabIndex = 1;
//
// booksLocationSearchBtn
//
this.booksLocationSearchBtn.Location = new System.Drawing.Point(878, 14);
this.booksLocationSearchBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.booksLocationSearchBtn.Name = "booksLocationSearchBtn";
this.booksLocationSearchBtn.Size = new System.Drawing.Size(41, 27);
this.booksLocationSearchBtn.TabIndex = 2;
this.booksLocationSearchBtn.Text = "...";
this.booksLocationSearchBtn.UseVisualStyleBackColor = true;
this.booksLocationSearchBtn.Click += new System.EventHandler(this.booksLocationSearchBtn_Click);
//
// booksLocationDescLbl
//
this.booksLocationDescLbl.AutoSize = true;
this.booksLocationDescLbl.Location = new System.Drawing.Point(107, 43);
this.booksLocationDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.booksLocationDescLbl.Name = "booksLocationDescLbl";
this.booksLocationDescLbl.Size = new System.Drawing.Size(39, 15);
this.booksLocationDescLbl.TabIndex = 3;
this.booksLocationDescLbl.Text = "[desc]";
//
// downloadsInProgressGb
//
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressLibationFilesRb);
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressWinTempRb);
this.downloadsInProgressGb.Controls.Add(this.downloadsInProgressDescLbl);
this.downloadsInProgressGb.Location = new System.Drawing.Point(10, 49);
this.downloadsInProgressGb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressGb.Name = "downloadsInProgressGb";
this.downloadsInProgressGb.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressGb.Size = new System.Drawing.Size(884, 135);
this.downloadsInProgressGb.TabIndex = 4;
this.downloadsInProgressGb.TabStop = false;
this.downloadsInProgressGb.Text = "Downloads in progress";
//
// downloadsInProgressLibationFilesRb
//
this.downloadsInProgressLibationFilesRb.AutoSize = true;
this.downloadsInProgressLibationFilesRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.downloadsInProgressLibationFilesRb.Location = new System.Drawing.Point(10, 93);
this.downloadsInProgressLibationFilesRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressLibationFilesRb.Name = "downloadsInProgressLibationFilesRb";
this.downloadsInProgressLibationFilesRb.Size = new System.Drawing.Size(215, 34);
this.downloadsInProgressLibationFilesRb.TabIndex = 2;
this.downloadsInProgressLibationFilesRb.TabStop = true;
this.downloadsInProgressLibationFilesRb.Text = "[desc]\r\n[libationFiles\\DownloadsInProgress]";
this.downloadsInProgressLibationFilesRb.UseVisualStyleBackColor = true;
//
// downloadsInProgressWinTempRb
//
this.downloadsInProgressWinTempRb.AutoSize = true;
this.downloadsInProgressWinTempRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.downloadsInProgressWinTempRb.Location = new System.Drawing.Point(10, 52);
this.downloadsInProgressWinTempRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.downloadsInProgressWinTempRb.Name = "downloadsInProgressWinTempRb";
this.downloadsInProgressWinTempRb.Size = new System.Drawing.Size(200, 34);
this.downloadsInProgressWinTempRb.TabIndex = 1;
this.downloadsInProgressWinTempRb.TabStop = true;
this.downloadsInProgressWinTempRb.Text = "[desc]\r\n[winTemp\\DownloadsInProgress]";
this.downloadsInProgressWinTempRb.UseVisualStyleBackColor = true;
//
// downloadsInProgressDescLbl
//
this.downloadsInProgressDescLbl.AutoSize = true;
this.downloadsInProgressDescLbl.Location = new System.Drawing.Point(7, 18);
this.downloadsInProgressDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.downloadsInProgressDescLbl.Name = "downloadsInProgressDescLbl";
this.downloadsInProgressDescLbl.Size = new System.Drawing.Size(43, 30);
this.downloadsInProgressDescLbl.TabIndex = 0;
this.downloadsInProgressDescLbl.Text = "[desc]\r\n[line 2]";
//
// decryptInProgressGb
//
this.decryptInProgressGb.Controls.Add(this.decryptInProgressLibationFilesRb);
this.decryptInProgressGb.Controls.Add(this.decryptInProgressWinTempRb);
this.decryptInProgressGb.Controls.Add(this.decryptInProgressDescLbl);
this.decryptInProgressGb.Location = new System.Drawing.Point(10, 193);
this.decryptInProgressGb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressGb.Name = "decryptInProgressGb";
this.decryptInProgressGb.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressGb.Size = new System.Drawing.Size(884, 135);
this.decryptInProgressGb.TabIndex = 5;
this.decryptInProgressGb.TabStop = false;
this.decryptInProgressGb.Text = "Decrypt in progress";
//
// decryptInProgressLibationFilesRb
//
this.decryptInProgressLibationFilesRb.AutoSize = true;
this.decryptInProgressLibationFilesRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.decryptInProgressLibationFilesRb.Location = new System.Drawing.Point(7, 93);
this.decryptInProgressLibationFilesRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressLibationFilesRb.Name = "decryptInProgressLibationFilesRb";
this.decryptInProgressLibationFilesRb.Size = new System.Drawing.Size(197, 34);
this.decryptInProgressLibationFilesRb.TabIndex = 2;
this.decryptInProgressLibationFilesRb.TabStop = true;
this.decryptInProgressLibationFilesRb.Text = "[desc]\r\n[libationFiles\\DecryptInProgress]";
this.decryptInProgressLibationFilesRb.UseVisualStyleBackColor = true;
//
// decryptInProgressWinTempRb
//
this.decryptInProgressWinTempRb.AutoSize = true;
this.decryptInProgressWinTempRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.decryptInProgressWinTempRb.Location = new System.Drawing.Point(7, 52);
this.decryptInProgressWinTempRb.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.decryptInProgressWinTempRb.Name = "decryptInProgressWinTempRb";
this.decryptInProgressWinTempRb.Size = new System.Drawing.Size(182, 34);
this.decryptInProgressWinTempRb.TabIndex = 1;
this.decryptInProgressWinTempRb.TabStop = true;
this.decryptInProgressWinTempRb.Text = "[desc]\r\n[winTemp\\DecryptInProgress]";
this.decryptInProgressWinTempRb.UseVisualStyleBackColor = true;
//
// decryptInProgressDescLbl
//
this.decryptInProgressDescLbl.AutoSize = true;
this.decryptInProgressDescLbl.Location = new System.Drawing.Point(7, 18);
this.decryptInProgressDescLbl.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.decryptInProgressDescLbl.Name = "decryptInProgressDescLbl";
this.decryptInProgressDescLbl.Size = new System.Drawing.Size(43, 30);
this.decryptInProgressDescLbl.TabIndex = 0;
this.decryptInProgressDescLbl.Text = "[desc]\r\n[line 2]";
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(714, 401);
this.saveBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(88, 27);
this.saveBtn.TabIndex = 7;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(832, 401);
this.cancelBtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(88, 27);
this.cancelBtn.TabIndex = 8;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.allowLibationFixupCbox);
this.groupBox1.Controls.Add(this.downloadsInProgressGb);
this.groupBox1.Controls.Add(this.decryptInProgressGb);
this.groupBox1.Location = new System.Drawing.Point(18, 61);
this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.groupBox1.Size = new System.Drawing.Size(902, 334);
this.groupBox1.TabIndex = 6;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Advanced settings for control freaks";
//
// allowLibationFixupCbox
//
this.allowLibationFixupCbox.AutoSize = true;
this.allowLibationFixupCbox.Location = new System.Drawing.Point(10, 24);
this.allowLibationFixupCbox.Name = "allowLibationFixupCbox";
this.allowLibationFixupCbox.Size = new System.Drawing.Size(262, 19);
this.allowLibationFixupCbox.TabIndex = 6;
this.allowLibationFixupCbox.Text = "Allow Libation to fix up audiobook metadata";
this.allowLibationFixupCbox.UseVisualStyleBackColor = true;
//
// SettingsDialog
//
this.AcceptButton = this.saveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelBtn;
this.ClientSize = new System.Drawing.Size(933, 442);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.saveBtn);
this.Controls.Add(this.booksLocationDescLbl);
this.Controls.Add(this.booksLocationSearchBtn);
this.Controls.Add(this.booksLocationTb);
this.Controls.Add(this.booksLocationLbl);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
this.Name = "SettingsDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Edit Settings";
this.Load += new System.EventHandler(this.SettingsDialog_Load);
this.downloadsInProgressGb.ResumeLayout(false);
this.downloadsInProgressGb.PerformLayout();
this.decryptInProgressGb.ResumeLayout(false);
this.decryptInProgressGb.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}

View File

@@ -3,7 +3,6 @@ using System.IO;
using System.Windows.Forms;
using Dinah.Core;
using FileManager;
using InternalUtilities;
namespace LibationWinForms.Dialogs
{
@@ -12,13 +11,13 @@ namespace LibationWinForms.Dialogs
Configuration config { get; } = Configuration.Instance;
Func<string, string> desc { get; } = Configuration.GetDescription;
public SettingsDialog()
{
InitializeComponent();
}
public SettingsDialog() => InitializeComponent();
private void SettingsDialog_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
this.booksLocationDescLbl.Text = desc(nameof(config.Books));
this.downloadsInProgressDescLbl.Text = desc(nameof(config.DownloadsInProgressEnum));
this.decryptInProgressDescLbl.Text = desc(nameof(config.DecryptInProgressEnum));
@@ -40,10 +39,10 @@ namespace LibationWinForms.Dialogs
switch (config.DownloadsInProgressEnum)
{
case "LibationFiles":
case Configuration.LIBATION_FILES_LABEL:
downloadsInProgressLibationFilesRb.Checked = true;
break;
case "WinTemp":
case Configuration.WIN_TEMP_LABEL:
default:
downloadsInProgressWinTempRb.Checked = true;
break;
@@ -51,10 +50,10 @@ namespace LibationWinForms.Dialogs
switch (config.DecryptInProgressEnum)
{
case "LibationFiles":
case Configuration.LIBATION_FILES_LABEL:
decryptInProgressLibationFilesRb.Checked = true;
break;
case "WinTemp":
case Configuration.WIN_TEMP_LABEL:
default:
decryptInProgressWinTempRb.Checked = true;
break;
@@ -74,8 +73,8 @@ namespace LibationWinForms.Dialogs
private void saveBtn_Click(object sender, EventArgs e)
{
config.AllowLibationFixup = allowLibationFixupCbox.Checked;
config.DownloadsInProgressEnum = downloadsInProgressLibationFilesRb.Checked ? "LibationFiles" : "WinTemp";
config.DecryptInProgressEnum = decryptInProgressLibationFilesRb.Checked ? "LibationFiles" : "WinTemp";
config.DownloadsInProgressEnum = downloadsInProgressLibationFilesRb.Checked ? Configuration.LIBATION_FILES_LABEL : Configuration.WIN_TEMP_LABEL;
config.DecryptInProgressEnum = decryptInProgressLibationFilesRb.Checked ? Configuration.LIBATION_FILES_LABEL : Configuration.WIN_TEMP_LABEL;
var newBooks = this.booksLocationTb.Text;
if (!Directory.Exists(newBooks))
@@ -90,6 +89,10 @@ namespace LibationWinForms.Dialogs
this.Close();
}
private void cancelBtn_Click(object sender, EventArgs e) => this.Close();
private void cancelBtn_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}

View File

@@ -81,6 +81,15 @@
<metadata name="downloadsInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadsInProgressLibationFilesRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadsInProgressWinTempRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadsInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressGb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
@@ -93,6 +102,15 @@
<metadata name="decryptInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressLibationFilesRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressWinTempRb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="decryptInProgressDescLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="saveBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
@@ -102,10 +120,4 @@
<metadata name="groupBox1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="downloadChaptersCbox.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

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

View File

@@ -0,0 +1,81 @@

namespace LibationWinForms.Dialogs
{
partial class TEMP_TestNewControls
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.directorySelectControl1 = new LibationWinForms.Dialogs.DirectorySelectControl();
this.directoryOrCustomSelectControl1 = new LibationWinForms.Dialogs.DirectoryOrCustomSelectControl();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(438, 375);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 2;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// directorySelectControl1
//
this.directorySelectControl1.Location = new System.Drawing.Point(30, 54);
this.directorySelectControl1.Name = "directorySelectControl1";
this.directorySelectControl1.Size = new System.Drawing.Size(758, 46);
this.directorySelectControl1.TabIndex = 4;
//
// directoryOrCustomSelectControl1
//
this.directoryOrCustomSelectControl1.Location = new System.Drawing.Point(128, 199);
this.directoryOrCustomSelectControl1.Name = "directoryOrCustomSelectControl1";
this.directoryOrCustomSelectControl1.Size = new System.Drawing.Size(660, 81);
this.directoryOrCustomSelectControl1.TabIndex = 5;
//
// TEMP_TestNewControls
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.directoryOrCustomSelectControl1);
this.Controls.Add(this.directorySelectControl1);
this.Controls.Add(this.button1);
this.Name = "TEMP_TestNewControls";
this.Text = "TEMP_TestNewControls";
this.Load += new System.EventHandler(this.TEMP_TestNewControls_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
private DirectorySelectControl directorySelectControl1;
private DirectoryOrCustomSelectControl directoryOrCustomSelectControl1;
}
}

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace LibationWinForms.Dialogs
{
public partial class TEMP_TestNewControls : Form
{
public TEMP_TestNewControls()
{
InitializeComponent();
}
private void TEMP_TestNewControls_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
{
var dirCtrl = this.directorySelectControl1;
dirCtrl.SetDirectoryItems(new()
{
FileManager.Configuration.KnownDirectories.AppDir,
FileManager.Configuration.KnownDirectories.MyDocs,
FileManager.Configuration.KnownDirectories.LibationFiles,
FileManager.Configuration.KnownDirectories.MyDocs,
FileManager.Configuration.KnownDirectories.None,
FileManager.Configuration.KnownDirectories.WinTemp,
FileManager.Configuration.KnownDirectories.UserProfile
}
,
FileManager.Configuration.KnownDirectories.MyDocs
);
}
{
var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
dirOrCustCtrl.SetSearchTitle("Libation Files");
dirOrCustCtrl.SetDirectoryItems(new()
{
FileManager.Configuration.KnownDirectories.AppDir,
FileManager.Configuration.KnownDirectories.MyDocs,
FileManager.Configuration.KnownDirectories.LibationFiles,
FileManager.Configuration.KnownDirectories.MyDocs,
FileManager.Configuration.KnownDirectories.None,
FileManager.Configuration.KnownDirectories.WinTemp,
FileManager.Configuration.KnownDirectories.UserProfile
}
,
FileManager.Configuration.KnownDirectories.MyDocs
);
}
}
private void button1_Click(object sender, EventArgs e)
{
var dirCtrl = this.directorySelectControl1;
var x = dirCtrl.SelectedDirectory;
dirCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile);
var dirOrCustCtrl = this.directoryOrCustomSelectControl1;
var y = dirOrCustCtrl.SelectedDirectory;
dirOrCustCtrl.SelectDirectory(FileManager.Configuration.KnownDirectories.UserProfile);
}
}
}

View File

@@ -0,0 +1,60 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -37,6 +37,9 @@ namespace LibationWinForms
private void Form1_Load(object sender, EventArgs e)
{
if (this.DesignMode)
return;
// load default/missing cover images. this will also initiate the background image downloader
var format = System.Drawing.Imaging.ImageFormat.Jpeg;
PictureStorage.SetDefaultImage(PictureSize._80x80, Properties.Resources.default_cover_80x80.ToBytes(format));

View File

@@ -22,30 +22,6 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Dialogs\LibationFilesDialog.cs" />
<Compile Update="Dialogs\LibationFilesDialog.Designer.cs">
<DependentUpon>LibationFilesDialog.cs</DependentUpon>
</Compile>
<Compile Update="Dialogs\Login\ApprovalNeededDialog.cs" />
<Compile Update="Dialogs\Login\ApprovalNeededDialog.Designer.cs">
<DependentUpon>ApprovalNeededDialog.cs</DependentUpon>
</Compile>
<Compile Update="Dialogs\ScanAccountsDialog.cs" />
<Compile Update="Dialogs\ScanAccountsDialog.Designer.cs">
<DependentUpon>ScanAccountsDialog.cs</DependentUpon>
</Compile>
<Compile Update="Dialogs\SettingsDialog.cs" />
<Compile Update="Dialogs\SettingsDialog.Designer.cs">
<DependentUpon>SettingsDialog.cs</DependentUpon>
</Compile>
<Compile Update="Dialogs\IndexLibraryDialog.cs" />
<Compile Update="Dialogs\IndexLibraryDialog.Designer.cs">
<DependentUpon>IndexLibraryDialog.cs</DependentUpon>
</Compile>
<Compile Update="Dialogs\SetupDialog.cs" />
<Compile Update="Dialogs\SetupDialog.Designer.cs">
<DependentUpon>SetupDialog.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
@@ -53,18 +29,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Dialogs\LibationFilesDialog.resx">
<DependentUpon>LibationFilesDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Update="Dialogs\ScanAccountsDialog.resx">
<DependentUpon>ScanAccountsDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Update="Dialogs\SettingsDialog.resx">
<DependentUpon>SettingsDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Update="Dialogs\SetupDialog.resx">
<DependentUpon>SetupDialog.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -1,92 +0,0 @@
namespace WinFormsDesigner.BookLiberation
{
partial class AutomatedBackupsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.keepGoingCb = new System.Windows.Forms.CheckBox();
this.logTb = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// keepGoingCb
//
this.keepGoingCb.AutoSize = true;
this.keepGoingCb.Checked = true;
this.keepGoingCb.CheckState = System.Windows.Forms.CheckState.Checked;
this.keepGoingCb.Location = new System.Drawing.Point(12, 12);
this.keepGoingCb.Name = "keepGoingCb";
this.keepGoingCb.Size = new System.Drawing.Size(325, 17);
this.keepGoingCb.TabIndex = 0;
this.keepGoingCb.Text = "Keep going. Uncheck to stop when current backup is complete";
this.keepGoingCb.UseVisualStyleBackColor = true;
//
// logTb
//
this.logTb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.logTb.Location = new System.Drawing.Point(12, 48);
this.logTb.Multiline = true;
this.logTb.Name = "logTb";
this.logTb.ReadOnly = true;
this.logTb.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.logTb.Size = new System.Drawing.Size(960, 202);
this.logTb.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(9, 32);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(501, 13);
this.label1.TabIndex = 2;
this.label1.Text = "NOTE: if the working directories are inside of Dropbox, some book liberation acti" +
"ons may hang indefinitely";
//
// AutomatedBackupsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(984, 262);
this.Controls.Add(this.label1);
this.Controls.Add(this.logTb);
this.Controls.Add(this.keepGoingCb);
this.Name = "AutomatedBackupsForm";
this.Text = "Automated Backups";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.CheckBox keepGoingCb;
private System.Windows.Forms.TextBox logTb;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.BookLiberation
{
public partial class AutomatedBackupsForm : Form
{
public AutomatedBackupsForm()
{
InitializeComponent();
}
}
}

View File

@@ -1,101 +0,0 @@
namespace WinFormsDesigner.BookLiberation
{
partial class DecryptForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.bookInfoLbl = new System.Windows.Forms.Label();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.rtbLog = new System.Windows.Forms.RichTextBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(12, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(100, 100);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// bookInfoLbl
//
this.bookInfoLbl.AutoSize = true;
this.bookInfoLbl.Location = new System.Drawing.Point(118, 12);
this.bookInfoLbl.Name = "bookInfoLbl";
this.bookInfoLbl.Size = new System.Drawing.Size(100, 13);
this.bookInfoLbl.TabIndex = 0;
this.bookInfoLbl.Text = "[multi-line book info]";
//
// progressBar1
//
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(12, 526);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(582, 23);
this.progressBar1.TabIndex = 2;
//
// rtbLog
//
this.rtbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.rtbLog.Location = new System.Drawing.Point(12, 118);
this.rtbLog.Name = "rtbLog";
this.rtbLog.Size = new System.Drawing.Size(582, 402);
this.rtbLog.TabIndex = 1;
this.rtbLog.Text = "";
//
// DecryptForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(606, 561);
this.Controls.Add(this.rtbLog);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.bookInfoLbl);
this.Controls.Add(this.pictureBox1);
this.Name = "DecryptForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "DecryptForm";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label bookInfoLbl;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.RichTextBox rtbLog;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.BookLiberation
{
public partial class DecryptForm : Form
{
public DecryptForm()
{
InitializeComponent();
}
}
}

View File

@@ -1,103 +0,0 @@
namespace WinFormsDesigner.BookLiberation
{
partial class DownloadForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.filenameLbl = new System.Windows.Forms.Label();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.progressLbl = new System.Windows.Forms.Label();
this.lastUpdateLbl = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// filenameLbl
//
this.filenameLbl.AutoSize = true;
this.filenameLbl.Location = new System.Drawing.Point(12, 9);
this.filenameLbl.Name = "filenameLbl";
this.filenameLbl.Size = new System.Drawing.Size(52, 13);
this.filenameLbl.TabIndex = 0;
this.filenameLbl.Text = "[filename]";
//
// progressBar1
//
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(15, 67);
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(877, 23);
this.progressBar1.TabIndex = 4;
//
// progressLbl
//
this.progressLbl.Location = new System.Drawing.Point(12, 36);
this.progressLbl.Name = "progressLbl";
this.progressLbl.Size = new System.Drawing.Size(173, 13);
this.progressLbl.TabIndex = 5;
this.progressLbl.Text = "[2,999,999,999] of [2,999,999,999]";
this.progressLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
//
// lastUpdateLbl
//
this.lastUpdateLbl.AutoSize = true;
this.lastUpdateLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lastUpdateLbl.ForeColor = System.Drawing.Color.DarkRed;
this.lastUpdateLbl.Location = new System.Drawing.Point(361, 36);
this.lastUpdateLbl.Name = "lastUpdateLbl";
this.lastUpdateLbl.Size = new System.Drawing.Size(81, 13);
this.lastUpdateLbl.TabIndex = 6;
this.lastUpdateLbl.Text = "Last updated";
this.lastUpdateLbl.Visible = false;
//
// DownloadForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(904, 102);
this.Controls.Add(this.lastUpdateLbl);
this.Controls.Add(this.progressLbl);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.filenameLbl);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "DownloadForm";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Downloading";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label filenameLbl;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.Label progressLbl;
private System.Windows.Forms.Label lastUpdateLbl;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.BookLiberation
{
public partial class DownloadForm : Form
{
public DownloadForm()
{
InitializeComponent();
}
}
}

View File

@@ -1,142 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class AccountsDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cancelBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.DeleteAccount = new System.Windows.Forms.DataGridViewButtonColumn();
this.LibraryScan = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.AccountId = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Locale = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.AccountName = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(713, 415);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(75, 23);
this.cancelBtn.TabIndex = 2;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(612, 415);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(75, 23);
this.saveBtn.TabIndex = 1;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
//
// dataGridView1
//
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.DeleteAccount,
this.LibraryScan,
this.AccountId,
this.Locale,
this.AccountName});
this.dataGridView1.Location = new System.Drawing.Point(12, 12);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(776, 397);
this.dataGridView1.TabIndex = 0;
//
// DeleteAccount
//
this.DeleteAccount.HeaderText = "Delete";
this.DeleteAccount.Name = "DeleteAccount";
this.DeleteAccount.ReadOnly = true;
this.DeleteAccount.Text = "x";
this.DeleteAccount.Width = 44;
//
// LibraryScan
//
this.LibraryScan.HeaderText = "Include in library scan?";
this.LibraryScan.Name = "LibraryScan";
this.LibraryScan.Width = 83;
//
// AccountId
//
this.AccountId.HeaderText = "Audible email/login";
this.AccountId.Name = "AccountId";
this.AccountId.Width = 111;
//
// Locale
//
this.Locale.HeaderText = "Locale";
this.Locale.Name = "Locale";
this.Locale.Width = 45;
//
// AccountName
//
this.AccountName.HeaderText = "Account nickname (optional)";
this.AccountName.Name = "AccountName";
this.AccountName.Width = 152;
//
// AccountsDialog
//
this.AcceptButton = this.saveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelBtn;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.saveBtn);
this.Controls.Add(this.cancelBtn);
this.Name = "AccountsDialog";
this.Text = "Audible Accounts";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button cancelBtn;
private System.Windows.Forms.Button saveBtn;
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewButtonColumn DeleteAccount;
private System.Windows.Forms.DataGridViewCheckBoxColumn LibraryScan;
private System.Windows.Forms.DataGridViewTextBoxColumn AccountId;
private System.Windows.Forms.DataGridViewComboBoxColumn Locale;
private System.Windows.Forms.DataGridViewTextBoxColumn AccountName;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs
{
public partial class AccountsDialog : Form
{
public AccountsDialog(Form1 parent)
{
InitializeComponent();
}
}
}

View File

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

View File

@@ -1,149 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class EditQuickFilters
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.cancelBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button();
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.Original = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.Delete = new System.Windows.Forms.DataGridViewButtonColumn();
this.Filter = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.MoveUp = new System.Windows.Forms.DataGridViewButtonColumn();
this.MoveDown = new System.Windows.Forms.DataGridViewButtonColumn();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(713, 415);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(75, 23);
this.cancelBtn.TabIndex = 2;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(612, 415);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(75, 23);
this.saveBtn.TabIndex = 1;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
//
// dataGridView1
//
this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.Original,
this.Delete,
this.Filter,
this.MoveUp,
this.MoveDown});
this.dataGridView1.Location = new System.Drawing.Point(12, 12);
this.dataGridView1.MultiSelect = false;
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(776, 397);
this.dataGridView1.TabIndex = 0;
//
// Original
//
this.Original.HeaderText = "Original";
this.Original.Name = "Original";
this.Original.ReadOnly = true;
this.Original.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Original.Visible = false;
this.Original.Width = 48;
//
// Delete
//
this.Delete.HeaderText = "Delete";
this.Delete.Name = "Delete";
this.Delete.ReadOnly = true;
this.Delete.Text = "x";
this.Delete.Width = 44;
//
// Filter
//
this.Filter.HeaderText = "Filter";
this.Filter.Name = "Filter";
this.Filter.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.Filter.Width = 35;
//
// MoveUp
//
this.MoveUp.HeaderText = "Move Up";
this.MoveUp.Name = "MoveUp";
this.MoveUp.ReadOnly = true;
this.MoveUp.Text = "^";
this.MoveUp.Width = 57;
//
// MoveDown
//
this.MoveDown.HeaderText = "Move Down";
this.MoveDown.Name = "MoveDown";
this.MoveDown.ReadOnly = true;
this.MoveDown.Text = "v";
this.MoveDown.Width = 71;
//
// EditQuickFilters
//
this.AcceptButton = this.saveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelBtn;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.dataGridView1);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.saveBtn);
this.Name = "EditQuickFilters";
this.Text = "Edit Quick Filters";
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button cancelBtn;
private System.Windows.Forms.Button saveBtn;
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.DataGridViewTextBoxColumn Original;
private System.Windows.Forms.DataGridViewButtonColumn Delete;
private System.Windows.Forms.DataGridViewTextBoxColumn Filter;
private System.Windows.Forms.DataGridViewButtonColumn MoveUp;
private System.Windows.Forms.DataGridViewButtonColumn MoveDown;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs
{
public partial class EditQuickFilters : Form
{
public EditQuickFilters(Form1 parent)
{
InitializeComponent();
}
}
}

View File

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

View File

@@ -1,90 +0,0 @@
namespace WinFormsDesigner
{
partial class EditTagsDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SaveBtn = new System.Windows.Forms.Button();
this.newTagsTb = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// SaveBtn
//
this.SaveBtn.Location = new System.Drawing.Point(396, 25);
this.SaveBtn.Name = "SaveBtn";
this.SaveBtn.Size = new System.Drawing.Size(75, 23);
this.SaveBtn.TabIndex = 1;
this.SaveBtn.Text = "Save";
this.SaveBtn.UseVisualStyleBackColor = true;
//
// newTagsTb
//
this.newTagsTb.Location = new System.Drawing.Point(12, 27);
this.newTagsTb.Name = "newTagsTb";
this.newTagsTb.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.newTagsTb.Size = new System.Drawing.Size(375, 20);
this.newTagsTb.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(424, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Tags are separated by a space. Each tag can contain letters, numbers, and undersc" +
"ores";
//
// EditTagsDialog
//
this.AcceptButton = this.SaveBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(483, 60);
this.Controls.Add(this.label1);
this.Controls.Add(this.newTagsTb);
this.Controls.Add(this.SaveBtn);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "EditTagsDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Edit Tags";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button SaveBtn;
private System.Windows.Forms.TextBox newTagsTb;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -1,15 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner
{
public partial class EditTagsDialog : Form
{
public string NewTags { get; private set; }
public EditTagsDialog()
{
InitializeComponent();
}
}
}

View File

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

View File

@@ -1,65 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class IndexLibraryDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(28, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(263, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Scanning Audible library. This may take a few minutes.";
//
// IndexLibraryDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(440, 63);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "IndexLibraryDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Scan Library";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs
{
public partial class IndexLibraryDialog : Form
{
public IndexLibraryDialog()
{
InitializeComponent();
}
}
}

View File

@@ -1,156 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class LibationFilesDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.libationFilesDescLbl = new System.Windows.Forms.Label();
this.libationFilesCustomBtn = new System.Windows.Forms.Button();
this.libationFilesCustomTb = new System.Windows.Forms.TextBox();
this.libationFilesCustomRb = new System.Windows.Forms.RadioButton();
this.libationFilesMyDocsRb = new System.Windows.Forms.RadioButton();
this.libationFilesRootRb = new System.Windows.Forms.RadioButton();
this.cancelBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// libationFilesDescLbl
//
this.libationFilesDescLbl.AutoSize = true;
this.libationFilesDescLbl.Location = new System.Drawing.Point(12, 9);
this.libationFilesDescLbl.Name = "libationFilesDescLbl";
this.libationFilesDescLbl.Size = new System.Drawing.Size(36, 13);
this.libationFilesDescLbl.TabIndex = 0;
this.libationFilesDescLbl.Text = "[desc]";
//
// libationFilesCustomBtn
//
this.libationFilesCustomBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.libationFilesCustomBtn.Location = new System.Drawing.Point(753, 95);
this.libationFilesCustomBtn.Name = "libationFilesCustomBtn";
this.libationFilesCustomBtn.Size = new System.Drawing.Size(35, 23);
this.libationFilesCustomBtn.TabIndex = 5;
this.libationFilesCustomBtn.Text = "...";
this.libationFilesCustomBtn.UseVisualStyleBackColor = true;
//
// libationFilesCustomTb
//
this.libationFilesCustomTb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.libationFilesCustomTb.Location = new System.Drawing.Point(35, 97);
this.libationFilesCustomTb.Name = "libationFilesCustomTb";
this.libationFilesCustomTb.Size = new System.Drawing.Size(712, 20);
this.libationFilesCustomTb.TabIndex = 4;
//
// libationFilesCustomRb
//
this.libationFilesCustomRb.AutoSize = true;
this.libationFilesCustomRb.Location = new System.Drawing.Point(15, 100);
this.libationFilesCustomRb.Name = "libationFilesCustomRb";
this.libationFilesCustomRb.Size = new System.Drawing.Size(14, 13);
this.libationFilesCustomRb.TabIndex = 3;
this.libationFilesCustomRb.TabStop = true;
this.libationFilesCustomRb.UseVisualStyleBackColor = true;
//
// libationFilesMyDocsRb
//
this.libationFilesMyDocsRb.AutoSize = true;
this.libationFilesMyDocsRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.libationFilesMyDocsRb.Location = new System.Drawing.Point(15, 61);
this.libationFilesMyDocsRb.Name = "libationFilesMyDocsRb";
this.libationFilesMyDocsRb.Size = new System.Drawing.Size(111, 30);
this.libationFilesMyDocsRb.TabIndex = 2;
this.libationFilesMyDocsRb.TabStop = true;
this.libationFilesMyDocsRb.Text = "[desc]\r\n[myDocs\\Libation]";
this.libationFilesMyDocsRb.UseVisualStyleBackColor = true;
//
// libationFilesRootRb
//
this.libationFilesRootRb.AutoSize = true;
this.libationFilesRootRb.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.libationFilesRootRb.Location = new System.Drawing.Point(15, 25);
this.libationFilesRootRb.Name = "libationFilesRootRb";
this.libationFilesRootRb.Size = new System.Drawing.Size(113, 30);
this.libationFilesRootRb.TabIndex = 1;
this.libationFilesRootRb.TabStop = true;
this.libationFilesRootRb.Text = "[desc]\r\n[appDir\\Libation]";
this.libationFilesRootRb.UseVisualStyleBackColor = true;
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(713, 124);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(75, 23);
this.cancelBtn.TabIndex = 10;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Location = new System.Drawing.Point(612, 124);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(75, 23);
this.saveBtn.TabIndex = 9;
this.saveBtn.Text = "Save";
this.saveBtn.UseVisualStyleBackColor = true;
//
// LibationFilesDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 159);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.saveBtn);
this.Controls.Add(this.libationFilesDescLbl);
this.Controls.Add(this.libationFilesCustomBtn);
this.Controls.Add(this.libationFilesCustomTb);
this.Controls.Add(this.libationFilesRootRb);
this.Controls.Add(this.libationFilesCustomRb);
this.Controls.Add(this.libationFilesMyDocsRb);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "LibationFilesDialog";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Libation Files location";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label libationFilesDescLbl;
private System.Windows.Forms.Button libationFilesCustomBtn;
private System.Windows.Forms.TextBox libationFilesCustomTb;
private System.Windows.Forms.RadioButton libationFilesCustomRb;
private System.Windows.Forms.RadioButton libationFilesMyDocsRb;
private System.Windows.Forms.RadioButton libationFilesRootRb;
private System.Windows.Forms.Button cancelBtn;
private System.Windows.Forms.Button saveBtn;
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs
{
public partial class LibationFilesDialog : Form
{
public LibationFilesDialog()
{
InitializeComponent();
}
}
}

View File

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

View File

@@ -1,77 +0,0 @@
namespace WinFormsDesigner.Dialogs.Login
{
partial class ApprovalNeededDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.approvedBtn = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// approvedBtn
//
this.approvedBtn.Location = new System.Drawing.Point(15, 25);
this.approvedBtn.Name = "approvedBtn";
this.approvedBtn.Size = new System.Drawing.Size(79, 23);
this.approvedBtn.TabIndex = 1;
this.approvedBtn.Text = "Approved";
this.approvedBtn.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(104, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Click after approving";
//
// ApprovalNeededDialog
//
this.AcceptButton = this.approvedBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(149, 60);
this.Controls.Add(this.label1);
this.Controls.Add(this.approvedBtn);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ApprovalNeededDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Approval Needed";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button approvedBtn;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs.Login
{
public partial class ApprovalNeededDialog : Form
{
public ApprovalNeededDialog()
{
InitializeComponent();
}
}
}

View File

@@ -1,113 +0,0 @@
namespace WinFormsDesigner.Dialogs.Login
{
partial class AudibleLoginDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.passwordLbl = new System.Windows.Forms.Label();
this.passwordTb = new System.Windows.Forms.TextBox();
this.submitBtn = new System.Windows.Forms.Button();
this.localeLbl = new System.Windows.Forms.Label();
this.usernameLbl = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// passwordLbl
//
this.passwordLbl.AutoSize = true;
this.passwordLbl.Location = new System.Drawing.Point(12, 41);
this.passwordLbl.Name = "passwordLbl";
this.passwordLbl.Size = new System.Drawing.Size(53, 13);
this.passwordLbl.TabIndex = 2;
this.passwordLbl.Text = "Password";
//
// passwordTb
//
this.passwordTb.Location = new System.Drawing.Point(71, 38);
this.passwordTb.Name = "passwordTb";
this.passwordTb.PasswordChar = '*';
this.passwordTb.Size = new System.Drawing.Size(200, 20);
this.passwordTb.TabIndex = 3;
//
// submitBtn
//
this.submitBtn.Location = new System.Drawing.Point(196, 64);
this.submitBtn.Name = "submitBtn";
this.submitBtn.Size = new System.Drawing.Size(75, 23);
this.submitBtn.TabIndex = 4;
this.submitBtn.Text = "Submit";
this.submitBtn.UseVisualStyleBackColor = true;
//
// localeLbl
//
this.localeLbl.AutoSize = true;
this.localeLbl.Location = new System.Drawing.Point(12, 9);
this.localeLbl.Name = "localeLbl";
this.localeLbl.Size = new System.Drawing.Size(59, 13);
this.localeLbl.TabIndex = 0;
this.localeLbl.Text = "Locale: {0}";
//
// usernameLbl
//
this.usernameLbl.AutoSize = true;
this.usernameLbl.Location = new System.Drawing.Point(12, 22);
this.usernameLbl.Name = "usernameLbl";
this.usernameLbl.Size = new System.Drawing.Size(75, 13);
this.usernameLbl.TabIndex = 1;
this.usernameLbl.Text = "Username: {0}";
//
// AudibleLoginDialog
//
this.AcceptButton = this.submitBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(283, 99);
this.Controls.Add(this.usernameLbl);
this.Controls.Add(this.localeLbl);
this.Controls.Add(this.submitBtn);
this.Controls.Add(this.passwordLbl);
this.Controls.Add(this.passwordTb);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AudibleLoginDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Audible Login";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label passwordLbl;
private System.Windows.Forms.TextBox passwordTb;
private System.Windows.Forms.Button submitBtn;
private System.Windows.Forms.Label localeLbl;
private System.Windows.Forms.Label usernameLbl;
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs.Login
{
public partial class AudibleLoginDialog : Form
{
public AudibleLoginDialog()
{
InitializeComponent();
}
}
}

View File

@@ -1,101 +0,0 @@
namespace WinFormsDesigner.Dialogs.Login
{
partial class CaptchaDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.captchaPb = new System.Windows.Forms.PictureBox();
this.answerTb = new System.Windows.Forms.TextBox();
this.submitBtn = new System.Windows.Forms.Button();
this.answerLbl = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.captchaPb)).BeginInit();
this.SuspendLayout();
//
// captchaPb
//
this.captchaPb.Location = new System.Drawing.Point(12, 12);
this.captchaPb.Name = "captchaPb";
this.captchaPb.Size = new System.Drawing.Size(200, 70);
this.captchaPb.TabIndex = 0;
this.captchaPb.TabStop = false;
//
// answerTb
//
this.answerTb.Location = new System.Drawing.Point(118, 88);
this.answerTb.Name = "answerTb";
this.answerTb.Size = new System.Drawing.Size(94, 20);
this.answerTb.TabIndex = 1;
//
// submitBtn
//
this.submitBtn.Location = new System.Drawing.Point(137, 114);
this.submitBtn.Name = "submitBtn";
this.submitBtn.Size = new System.Drawing.Size(75, 23);
this.submitBtn.TabIndex = 2;
this.submitBtn.Text = "Submit";
this.submitBtn.UseVisualStyleBackColor = true;
//
// answerLbl
//
this.answerLbl.AutoSize = true;
this.answerLbl.Location = new System.Drawing.Point(12, 91);
this.answerLbl.Name = "answerLbl";
this.answerLbl.Size = new System.Drawing.Size(100, 13);
this.answerLbl.TabIndex = 0;
this.answerLbl.Text = "CAPTCHA answer: ";
//
// CaptchaDialog
//
this.AcceptButton = this.submitBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(224, 149);
this.Controls.Add(this.answerLbl);
this.Controls.Add(this.submitBtn);
this.Controls.Add(this.answerTb);
this.Controls.Add(this.captchaPb);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "CaptchaDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "CAPTCHA";
((System.ComponentModel.ISupportInitialize)(this.captchaPb)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox captchaPb;
private System.Windows.Forms.TextBox answerTb;
private System.Windows.Forms.Button submitBtn;
private System.Windows.Forms.Label answerLbl;
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs.Login
{
public partial class CaptchaDialog : Form
{
public CaptchaDialog()
{
InitializeComponent();
}
}
}

View File

@@ -1,88 +0,0 @@
namespace WinFormsDesigner.Dialogs.Login
{
partial class _2faCodeDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.submitBtn = new System.Windows.Forms.Button();
this.codeTb = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// submitBtn
//
this.submitBtn.Location = new System.Drawing.Point(15, 51);
this.submitBtn.Name = "submitBtn";
this.submitBtn.Size = new System.Drawing.Size(79, 23);
this.submitBtn.TabIndex = 1;
this.submitBtn.Text = "Submit";
this.submitBtn.UseVisualStyleBackColor = true;
//
// codeTb
//
this.codeTb.Location = new System.Drawing.Point(15, 25);
this.codeTb.Name = "codeTb";
this.codeTb.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.codeTb.Size = new System.Drawing.Size(79, 20);
this.codeTb.TabIndex = 0;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(82, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Enter 2FA Code";
//
// _2faCodeDialog
//
this.AcceptButton = this.submitBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(106, 86);
this.Controls.Add(this.label1);
this.Controls.Add(this.codeTb);
this.Controls.Add(this.submitBtn);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "_2faCodeDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "2FA Code";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button submitBtn;
private System.Windows.Forms.TextBox codeTb;
private System.Windows.Forms.Label label1;
}
}

View File

@@ -1,13 +0,0 @@
using System;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs.Login
{
public partial class _2faCodeDialog : Form
{
public _2faCodeDialog()
{
InitializeComponent();
}
}
}

View File

@@ -1,117 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class ScanAccountsDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.accountsLbl = new System.Windows.Forms.Label();
this.accountsClb = new System.Windows.Forms.CheckedListBox();
this.importBtn = new System.Windows.Forms.Button();
this.cancelBtn = new System.Windows.Forms.Button();
this.editBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// accountsLbl
//
this.accountsLbl.AutoSize = true;
this.accountsLbl.Location = new System.Drawing.Point(12, 9);
this.accountsLbl.Name = "accountsLbl";
this.accountsLbl.Size = new System.Drawing.Size(467, 13);
this.accountsLbl.TabIndex = 0;
this.accountsLbl.Text = "Check the accounts to scan and import. To change default selections, go to: Setti" +
"ngs > Accounts";
//
// accountsClb
//
this.accountsClb.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.accountsClb.FormattingEnabled = true;
this.accountsClb.Location = new System.Drawing.Point(12, 25);
this.accountsClb.Name = "accountsClb";
this.accountsClb.Size = new System.Drawing.Size(560, 94);
this.accountsClb.TabIndex = 1;
//
// importBtn
//
this.importBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.importBtn.Location = new System.Drawing.Point(396, 125);
this.importBtn.Name = "importBtn";
this.importBtn.Size = new System.Drawing.Size(75, 23);
this.importBtn.TabIndex = 3;
this.importBtn.Text = "Import";
this.importBtn.UseVisualStyleBackColor = true;
//
// cancelBtn
//
this.cancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelBtn.Location = new System.Drawing.Point(497, 125);
this.cancelBtn.Name = "cancelBtn";
this.cancelBtn.Size = new System.Drawing.Size(75, 23);
this.cancelBtn.TabIndex = 4;
this.cancelBtn.Text = "Cancel";
this.cancelBtn.UseVisualStyleBackColor = true;
//
// editBtn
//
this.editBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.editBtn.Location = new System.Drawing.Point(12, 125);
this.editBtn.Name = "editBtn";
this.editBtn.Size = new System.Drawing.Size(90, 23);
this.editBtn.TabIndex = 2;
this.editBtn.Text = "Edit accounts";
this.editBtn.UseVisualStyleBackColor = true;
//
// ScanAccountsDialog
//
this.AcceptButton = this.importBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelBtn;
this.ClientSize = new System.Drawing.Size(584, 160);
this.Controls.Add(this.editBtn);
this.Controls.Add(this.cancelBtn);
this.Controls.Add(this.importBtn);
this.Controls.Add(this.accountsClb);
this.Controls.Add(this.accountsLbl);
this.Name = "ScanAccountsDialog";
this.Text = "Which accounts?";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label accountsLbl;
private System.Windows.Forms.CheckedListBox accountsClb;
private System.Windows.Forms.Button importBtn;
private System.Windows.Forms.Button cancelBtn;
private System.Windows.Forms.Button editBtn;
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsDesigner.Dialogs
{
public partial class ScanAccountsDialog : Form
{
public ScanAccountsDialog(Form1 parent)
{
InitializeComponent();
}
}
}

View File

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

View File

@@ -1,132 +0,0 @@
namespace WinFormsDesigner.Dialogs
{
partial class SearchSyntaxDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.closeBtn = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(358, 52);
this.label1.TabIndex = 0;
this.label1.Text = "Full Lucene query syntax is supported\r\nFields with similar names are synomyns (eg" +
": Author, Authors, AuthorNames)\r\n\r\nTAG FORMAT: [tagName]";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 71);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(118, 65);
this.label2.TabIndex = 1;
this.label2.Text = "STRING FIELDS\r\n\r\nSearch for wizard of oz:\r\n title:oz\r\n title:\"wizard of o" +
"z\"";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(233, 71);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(195, 78);
this.label3.TabIndex = 2;
this.label3.Text = "NUMBER FIELDS\r\n\r\nFind books between 1-100 minutes long\r\n length:[1 TO 100]\r\nF" +
"ind books exactly 1 hr long\r\n length:60";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(454, 71);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(168, 52);
this.label4.TabIndex = 3;
this.label4.Text = "BOOL FIELDS\r\n\r\nFind books that you haven\'t rated:\r\n -IsRated";
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(673, 71);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(257, 78);
this.label5.TabIndex = 4;
this.label5.Text = "ID FIELDS\r\n\r\nAlice\'s Adventures in Wonderland (ID: B015D78L0U)\r\n id:B015D78L0" +
"U\r\n\r\nAll of these are synonyms for the ID field";
//
// closeBtn
//
this.closeBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.closeBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.closeBtn.Location = new System.Drawing.Point(890, 465);
this.closeBtn.Name = "closeBtn";
this.closeBtn.Size = new System.Drawing.Size(75, 23);
this.closeBtn.TabIndex = 5;
this.closeBtn.Text = "Close";
this.closeBtn.UseVisualStyleBackColor = true;
//
// SearchSyntaxDialog
//
this.AcceptButton = this.closeBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.closeBtn;
this.ClientSize = new System.Drawing.Size(977, 500);
this.Controls.Add(this.closeBtn);
this.Controls.Add(this.label5);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SearchSyntaxDialog";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Filter options";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Button closeBtn;
}
}

Some files were not shown because too many files have changed in this diff Show More