diff --git a/QobuzDownloaderX.sln b/QobuzDownloaderX.sln index 0a4c3d6..f212835 100644 --- a/QobuzDownloaderX.sln +++ b/QobuzDownloaderX.sln @@ -1,9 +1,9 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33502.453 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QobuzDownloaderX", "QobuzDownloaderX\QobuzDownloaderX.csproj", "{4CEB979A-035A-4D36-9607-D554BBECABE0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QobuzDownloaderX", "QobuzDownloaderX\QobuzDownloaderX.csproj", "{4CEB979A-035A-4D36-9607-D554BBECABE0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/QobuzDownloaderX/Properties/AssemblyInfo.cs b/QobuzDownloaderX/Properties/AssemblyInfo.cs deleted file mode 100644 index 04899cd..0000000 --- a/QobuzDownloaderX/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.InteropServices; - -// General Information Globals.AboutForm an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("QobuzDownloaderX")] -[assembly: AssemblyDescription("Qobuz music downloader")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("DJDoubleD")] -[assembly: AssemblyProduct("QobuzDownloaderX")] -[assembly: AssemblyCopyright("Copyright © 2024")] -[assembly: AssemblyTrademark("DJDoubleD")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4ceb979a-035a-4d36-9607-d554bbecabe0")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.7.0")] -[assembly: AssemblyFileVersion("1.2.7.0")] -[assembly: NeutralResourcesLanguage("")] diff --git a/QobuzDownloaderX/QobuzDownloaderX.csproj b/QobuzDownloaderX/QobuzDownloaderX.csproj index 87b789a..52ff541 100644 --- a/QobuzDownloaderX/QobuzDownloaderX.csproj +++ b/QobuzDownloaderX/QobuzDownloaderX.csproj @@ -1,270 +1,75 @@ - - - - - Debug - AnyCPU - {4CEB979A-035A-4D36-9607-D554BBECABE0} - WinExe - Properties - QobuzDownloaderX - QobuzDownloaderX - v4.8.1 - 512 - true - - false - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - ..\README.md - - - AnyCPU - true - embedded - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - Auto - - - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - - - Resources\qbdlx_icon.ico - - - QobuzDownloaderX.Program - - - app.manifest - - - app.manifest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Form - - - HeadlessForm.cs - - - Form - - - MainForm.cs - - - Form - - - AboutForm.cs - - - Form - - - LoginForm.cs - - - - Form - - - SearchForm.cs - - - - - - Form - - - SettingsForm.cs - - - MainForm.cs - Designer - - - AboutForm.cs - - - LoginForm.cs - - - SearchForm.cs - Designer - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsForm.cs - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.8 %28x86 and x64%29 - true - - - - - - - - - - - 13.0.3 - - - 1.4.1 - - - 0.2.2 - - - 0.0.8 - - - - - - - - - - - - - - - - - - - - + + + net8.0-windows + WinExe + 1.2.7.0 + 1.2.7.0 + 1.2.7.0 + 1.2.7.%0a + true + true + app.manifest + Resources\qbdlx_icon.ico + QobuzDownloaderX.Program + + + + embedded + Auto + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.4.1 + + + 0.2.2 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/QobuzDownloaderX/Shared/DownloadLogger.cs b/QobuzDownloaderX/Shared/DownloadLogger.cs index b1121f4..389e73f 100644 --- a/QobuzDownloaderX/Shared/DownloadLogger.cs +++ b/QobuzDownloaderX/Shared/DownloadLogger.cs @@ -3,24 +3,19 @@ using System.IO; using System.Windows.Forms; using System.Linq; +using System.Threading; namespace QobuzDownloaderX.Shared { - public class DownloadLogger + public class DownloadLogger(TextBox outputTextBox, string specifier) { + public readonly string logPath = Path.Combine(Globals.LoggingDir, $"{specifier}.log"); public readonly string downloadErrorLogPath = Path.Combine(Globals.LoggingDir, "Download_Errors.log"); - public delegate void DownloadEnded(); - private readonly DownloadEnded updateUiOnDownloadEnd; - private TextBox ScreenOutputTextBox { get; } + private static readonly SemaphoreSlim _fileSemaphore = new(1, 1); + private TextBox ScreenOutputTextBox { get; } = outputTextBox; public string DownloadLogPath { get; set; } - public DownloadLogger(TextBox outputTextBox, DownloadEnded updateUiOnDownloadEnd) - { - ScreenOutputTextBox = outputTextBox; - this.updateUiOnDownloadEnd = updateUiOnDownloadEnd; - } - public void RemovePreviousErrorLog() { // Remove previous download error log @@ -43,25 +38,20 @@ public void AddDownloadLogLine(string logEntry, bool logToFile, bool logToScreen { if (string.IsNullOrEmpty(logEntry)) return; + _fileSemaphore.Wait(); if (logToScreen) ScreenOutputTextBox?.Invoke(new Action(() => ScreenOutputTextBox.AppendText(logEntry))); if (logToFile) { - var logEntries = logEntry.Split(new[] { Environment.NewLine }, StringSplitOptions.None) - .Select(logLine => string.IsNullOrWhiteSpace(logLine) ? logLine : $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} : {logLine}"); - - // Filter out all empty lines exept if the logEntry started with an empty line to avoid blank lines for each newline in UI - var filteredLogEntries = logEntries.Aggregate(new List(), (accumulator, current) => + try { - if (accumulator.Count == 0 || !string.IsNullOrWhiteSpace(current)) - { - accumulator.Add(current); - } + var logEntries = logEntry.Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .Select(logLine => string.IsNullOrWhiteSpace(logLine) ? logLine : $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} : {logLine}") + .Where(logLine => !string.IsNullOrWhiteSpace(logLine)); - return accumulator; - }); - - System.IO.File.AppendAllLines(DownloadLogPath, filteredLogEntries); + File.AppendAllLines(logPath, logEntries); + } + finally { _fileSemaphore.Release(); } } } @@ -89,8 +79,9 @@ public void AddEmptyDownloadLogLine(bool logToFile, bool logToScreen = false) public void AddDownloadErrorLogLines(IEnumerable logEntries) { if (logEntries == null && !logEntries.Any()) return; - - System.IO.File.AppendAllLines(downloadErrorLogPath, logEntries); + _fileSemaphore.Wait(); + try { System.IO.File.AppendAllLines(downloadErrorLogPath, logEntries);} + finally{ _fileSemaphore.Release(); } } public void AddDownloadErrorLogLine(string logEntry) @@ -107,13 +98,12 @@ public void AddDownloadErrorLogLine(string logEntry) public void LogDownloadTaskException(string downloadTaskType, Exception downloadEx) { // If there is an issue trying to, or during the download, show error info. - ClearUiLogComponent(); + // ClearUiLogComponent(); AddDownloadLogErrorLine($"{downloadTaskType} Download Task ERROR. Details saved to error log.{Environment.NewLine}", true, true); AddDownloadErrorLogLine($"{downloadTaskType} Download Task ERROR."); AddDownloadErrorLogLine(downloadEx.ToString()); AddDownloadErrorLogLine(Environment.NewLine); - updateUiOnDownloadEnd?.Invoke(); } public void LogFinishedDownloadJob(bool noErrorsOccured) @@ -123,14 +113,12 @@ public void LogFinishedDownloadJob(bool noErrorsOccured) // Say that downloading is completed. if (noErrorsOccured) { - AddDownloadLogLine("Download job completed! All downloaded files will be located in your chosen path.", true, true); + AddDownloadLogLine($"Download job completed! All downloaded files will be located in your chosen path..{Environment.NewLine}", true, true); } else { - AddDownloadLogLine("Download job completed with warnings and/or errors! Some or all files could be missing!", true, true); + AddDownloadLogLine($"Download job completed with warnings and/or errors! Some or all files could be missing!.{Environment.NewLine}", true, true); } - - updateUiOnDownloadEnd?.Invoke(); } public void ClearUiLogComponent() diff --git a/QobuzDownloaderX/Shared/DownloadManager.cs b/QobuzDownloaderX/Shared/DownloadManager.cs deleted file mode 100644 index f2f528a..0000000 --- a/QobuzDownloaderX/Shared/DownloadManager.cs +++ /dev/null @@ -1,1136 +0,0 @@ -using PlaylistsNET.Content; -using PlaylistsNET.Models; -using QobuzApiSharp.Exceptions; -using QobuzApiSharp.Models.Content; -using QobuzApiSharp.Service; -using QobuzDownloaderX.Models; -using QobuzDownloaderX.Models.Content; -using QobuzDownloaderX.Properties; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; - -namespace QobuzDownloaderX.Shared -{ - public class DownloadManager - { - private readonly DownloadLogger logger; - private CancellationTokenSource cancellationTokenSource; - - public delegate void DownloadTaskStatusChanged(); - public delegate void UpdateAlbumTagsUi(DownloadItemInfo downloadInfo); - private readonly UpdateAlbumTagsUi UpdateAlbumUiTags; - public delegate void UpdateDownloadSpeed(string speed); - private readonly UpdateDownloadSpeed UpdateUiDownloadSpeed; - - public DownloadItemInfo DownloadInfo { get; private set; } - - public DownloadItemPaths DownloadPaths { get; private set; } - - public bool IsBuzy { get; private set; } - - public bool CheckIfStreamable { get; set; } - - public DownloadManager(DownloadLogger logger, UpdateAlbumTagsUi updateAlbumTagsUi, UpdateDownloadSpeed updateUiDownloadSpeed) - { - IsBuzy = false; - CheckIfStreamable = true; - this.logger = logger; - UpdateUiDownloadSpeed = updateUiDownloadSpeed; - UpdateAlbumUiTags = updateAlbumTagsUi; - } - - private T ExecuteApiCall(Func apiCall) - { - try - { - return apiCall(QobuzApiServiceManager.GetApiService()); - } - catch (Exception ex) - { - // If connection to API fails, or something is incorrect, show error info + log details. - List errorLines = new List(); - - logger.AddEmptyDownloadLogLine(false, true); - logger.AddDownloadLogErrorLine($"Communication problem with Qobuz API. Details saved to error log{Environment.NewLine}", true, true); - - switch (ex) - { - case ApiErrorResponseException erEx: - errorLines.Add("Failed API request:"); - errorLines.Add(erEx.RequestContent); - errorLines.Add($"Api response code: {erEx.ResponseStatusCode}"); - errorLines.Add($"Api response status: {erEx.ResponseStatus}"); - errorLines.Add($"Api response reason: {erEx.ResponseReason}"); - break; - case ApiResponseParseErrorException pEx: - errorLines.Add("Error parsing API response"); - errorLines.Add($"Api response content: {pEx.ResponseContent}"); - break; - default: - errorLines.Add("Unknown error trying API request:"); - errorLines.Add($"{ex}"); - break; - } - - // Write detailed info to error log - logger.AddDownloadErrorLogLines(errorLines); - } - - return default; - } - - public void StopDownloadTask() - { - this.cancellationTokenSource?.Cancel(); - } - - public bool IsStreamable(Track qobuzTrack, bool inPlaylist = false) - { - if (qobuzTrack.Streamable != false) return true; - - bool tryToStream = true; - - switch (CheckIfStreamable) - { - case true: - string trackReference; - - if (inPlaylist) - { - trackReference = $"{qobuzTrack.Performer?.Name} - {qobuzTrack.Title}"; - } - else - { - trackReference = $"{qobuzTrack.TrackNumber.GetValueOrDefault()} {StringTools.DecodeEncodedNonAsciiCharacters(qobuzTrack.Title.Trim())}"; - } - - logger.AddDownloadLogLine($"Track {trackReference} is not available for streaming. Unable to download.\r\n", true, true); - tryToStream = false; - break; - - default: - logger.AddDownloadLogLine("Track is not available for streaming. But streamable check is being ignored for debugging, or messed up releases. Attempting to download...\r\n", tryToStream, tryToStream); - break; - } - - return tryToStream; - } - - public async Task DownloadFileAsync(HttpClient httpClient, string downloadUrl, string filePath) - { - using (Stream streamToReadFrom = await httpClient.GetStreamAsync(downloadUrl)) - { - using (FileStream streamToWriteTo = System.IO.File.Create(filePath)) - { - long totalBytesRead = 0; - Stopwatch stopwatch = Stopwatch.StartNew(); - byte[] buffer = new byte[32768]; // Use a 32KB buffer size for copying data - bool firstBufferRead = false; - - int bytesRead; - while ((bytesRead = await streamToReadFrom.ReadAsync(buffer, 0, buffer.Length)) > 0) - { - // Write only the minimum of buffer.Length and bytesRead bytes to the file - await streamToWriteTo.WriteAsync(buffer, 0, Math.Min(buffer.Length, bytesRead)); - - // Calculate download speed - totalBytesRead += bytesRead; - double speed = totalBytesRead / 1024d / 1024d / stopwatch.Elapsed.TotalSeconds; - - // Update the downloadSpeedLabel with the current speed at download start and then max. every 100 ms, with 3 decimal places - if (!firstBufferRead || stopwatch.ElapsedMilliseconds >= 200) - { - UpdateUiDownloadSpeed.Invoke($"Downloading... {speed:F3} MB/s"); - } - - firstBufferRead = true; - } - } - } - - // After download completes successfully - UpdateUiDownloadSpeed.Invoke("Idle"); - } - - private async Task DownloadTrackAsync(CancellationToken cancellationToken, Track qobuzTrack, string basePath, bool isPartOfTracklist, bool isPartOfAlbum, bool removeTagArtFileAfterDownload = false, string albumPathSuffix = "") - { - // Just for good measure... - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - string trackIdString = qobuzTrack.Id.GetValueOrDefault().ToString(); - - DownloadInfo.SetTrackTaggingInfo(qobuzTrack); - - // If track is downloaded as part of Album, Album related processings should already be done. - // Only handle Album related processing when downloading a single track. - if (!isPartOfAlbum) - { - // Get all album information and update UI fields via callback - DownloadInfo.SetAlbumDownloadInfo(qobuzTrack.Album); - UpdateAlbumUiTags.Invoke(DownloadInfo); - } - - // Check if available for streaming. - if (!IsStreamable(qobuzTrack)) return false; - - // Create directories if they don't exist yet - // Add Album ID to Album Path if requested (to avoid conflicts for similar albums with trimmed long names) - CreateTrackDirectories(basePath, DownloadPaths.QualityPath, albumPathSuffix, isPartOfTracklist); - - // Set trackPath to the created directories - string trackPath = DownloadInfo.CurrentDownloadPaths.Path4Full; - - // Create padded track number string with minimum of 2 integer positions based on number of total tracks - string paddedTrackNumber = DownloadInfo.TrackNumber.ToString().PadLeft(Math.Max(2, (int)Math.Floor(Math.Log10(DownloadInfo.TrackTotal) + 1)), '0'); - - // Create full track filename - if (isPartOfTracklist) - { - DownloadPaths.FinalTrackNamePath = string.Concat(DownloadPaths.PerformerNamePath, Globals.FileNameTemplateString, DownloadPaths.TrackNamePath).TrimEnd(); - } - else - { - DownloadPaths.FinalTrackNamePath = string.Concat(paddedTrackNumber, Globals.FileNameTemplateString, DownloadPaths.TrackNamePath).TrimEnd(); - } - - // Shorten full filename if over MaxLength to avoid errors with file names being too long - DownloadPaths.FinalTrackNamePath = StringTools.TrimToMaxLength(DownloadPaths.FinalTrackNamePath, Globals.MaxLength); - - // Construct Full filename & file path - DownloadPaths.FullTrackFileName = DownloadPaths.FinalTrackNamePath + Globals.AudioFileType; - DownloadPaths.FullTrackFilePath = Path.Combine(trackPath, DownloadPaths.FullTrackFileName); - - // Check if the file already exists - if (System.IO.File.Exists(DownloadPaths.FullTrackFilePath)) - { - string message = $"File for \"{DownloadPaths.FinalTrackNamePath}\" already exists. Skipping.\r\n"; - logger.AddDownloadLogLine(message, true, true); - return false; - } - - // Notify UI of starting track download. - logger.AddDownloadLogLine($"Downloading - {DownloadPaths.FinalTrackNamePath} ...... ", true, true); - - // Get track streaming URL, abort if failed. - string streamUrl = ExecuteApiCall(apiService => apiService.GetTrackFileUrl(trackIdString, Globals.FormatIdString))?.Url; - - if (string.IsNullOrEmpty(streamUrl)) - { - // Can happen with free accounts trying to download non-previewable tracks (or if API call failed). - logger.AddDownloadLogLine($"Couldn't get streaming URL for Track \"{DownloadPaths.FinalTrackNamePath}\". Skipping.\r\n", true, true); - return false; - } - - try - { - // Create file path strings - string coverArtFilePath = Path.Combine(DownloadPaths.Path3Full, "Cover.jpg"); - string coverArtTagFilePath = Path.Combine(DownloadPaths.Path3Full, Globals.TaggingOptions.ArtSize + ".jpg"); - - using (HttpClient httpClient = new HttpClient()) - { - httpClient.DefaultRequestHeaders.Add("User-Agent", Globals.USER_AGENT); - - // Save streamed file from link - await DownloadFileAsync(httpClient, streamUrl, DownloadPaths.FullTrackFilePath); - - // Download selected cover art size for tagging files (if not exists) - if (!System.IO.File.Exists(coverArtTagFilePath)) - { - try - { - await DownloadFileAsync(httpClient, DownloadInfo.FrontCoverImgTagUrl, coverArtTagFilePath); - } - catch (Exception ex) - { - // Qobuz servers throw a 404 as if the image doesn't exist. - logger.AddDownloadErrorLogLines(new string[] { "Error downloading image file for tagging.", ex.Message, Environment.NewLine }); - } - } - - // Download max quality Cover Art to "Cover.jpg" file in chosen path (if not exists & not part of playlist). - if (!isPartOfTracklist && !System.IO.File.Exists(coverArtFilePath)) - { - try - { - await DownloadFileAsync(httpClient, DownloadInfo.FrontCoverImgUrl, coverArtFilePath); - } - catch (Exception ex) - { - // Qobuz servers throw a 404 as if the image doesn't exist. - logger.AddDownloadErrorLogLines(new string[] { "Error downloading full size cover image file.", ex.Message, Environment.NewLine }); - } - } - } - - // Tag metadata to downloaded track. - AudioFileTagger.AddMetaDataTags(DownloadInfo, DownloadPaths.FullTrackFilePath, coverArtTagFilePath, logger); - - // Remove temp tagging art file if requested and exists. - if (removeTagArtFileAfterDownload && System.IO.File.Exists(coverArtTagFilePath)) - { - System.IO.File.Delete(coverArtTagFilePath); - } - - logger.AddDownloadLogLine("Track Download Done!\r\n", true, true); - System.Threading.Thread.Sleep(100); - } - catch (AggregateException ae) - { - // When a Task fails, an AggregateException is thrown. Could be a HttpClient timeout or network error. - logger.AddDownloadLogErrorLine($"Track Download canceled, probably due to network error or request timeout. Details saved to error log.{Environment.NewLine}", true, true); - - logger.AddDownloadErrorLogLine("Track Download canceled, probably due to network error or request timeout."); - logger.AddDownloadErrorLogLine(ae.ToString()); - logger.AddDownloadErrorLogLine(Environment.NewLine); - return false; - } - catch (Exception downloadEx) - { - // If there is an unknown issue trying to, or during the download, show and log error info. - logger.AddDownloadLogErrorLine($"Unknown error during Track Download. Details saved to error log.{Environment.NewLine}", true, true); - - logger.AddDownloadErrorLogLine("Unknown error during Track Download."); - logger.AddDownloadErrorLogLine(downloadEx.ToString()); - logger.AddDownloadErrorLogLine(Environment.NewLine); - return false; - } - - return true; - } - - private async Task DownloadAlbumAsync(CancellationToken cancellationToken, Album qobuzAlbum, string basePath, string albumPathSuffix = "") - { - bool noErrorsOccured = true; - - // Get Album model object with first batch of tracks - const int tracksLimit = 50; - qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzAlbum.Id, true, null, tracksLimit, 0)); - - // If API call failed, abort Album Download - if (string.IsNullOrEmpty(qobuzAlbum.Id)) { return false; } - - // Get all album information and update UI fields via callback - DownloadInfo.SetAlbumDownloadInfo(qobuzAlbum); - UpdateAlbumUiTags.Invoke(DownloadInfo); - - // Download all tracks of the Album in batches of {tracksLimit}, clean albumArt tag file after last track - int tracksTotal = qobuzAlbum.Tracks.Total ?? 0; - int tracksPageOffset = qobuzAlbum.Tracks.Offset ?? 0; - int tracksLoaded = qobuzAlbum.Tracks.Items?.Count ?? 0; - - int i = 0; - while (i < tracksLoaded) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - bool isLastTrackOfAlbum = (i + tracksPageOffset) == (tracksTotal - 1); - Track qobuzTrack = qobuzAlbum.Tracks.Items[i]; - - // Nested Album objects in Tracks are not always fully populated, inject current qobuzAlbum in Track to be downloaded - qobuzTrack.Album = qobuzAlbum; - - if (!await DownloadTrackAsync(cancellationToken, qobuzTrack, basePath, false, true, isLastTrackOfAlbum, albumPathSuffix)) noErrorsOccured = false; - - i++; - - if (i == tracksLoaded && tracksTotal > (i + tracksPageOffset)) - { - // load next page of tracks - tracksPageOffset += tracksLimit; - qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzAlbum.Id, true, null, tracksLimit, tracksPageOffset)); - - // If API call failed, abort Album Download - if (string.IsNullOrEmpty(qobuzAlbum.Id)) { return false; } - - // If Album Track Items is empty, Qobuz max API offset might be reached - if (qobuzAlbum.Tracks?.Items?.Any() != true) break; - - // Reset counter for looping next batch of tracks - i = 0; - tracksLoaded = qobuzAlbum.Tracks.Items?.Count ?? 0; - } - } - - // Look for digital booklet(s) in "Goodies" - // Don't fail on failed "Goodies" downloads, just log... - if (!await DownloadBookletsAsync(qobuzAlbum, DownloadPaths.Path3Full)) noErrorsOccured = false; - - return noErrorsOccured; - } - - private async Task DownloadBookletsAsync(Album qobuzAlbum, string basePath) - { - bool noErrorsOccured = true; - - List booklets = qobuzAlbum.Goodies?.Where(g => g.FileFormatId == (int)GoodiesFileType.BOOKLET).ToList(); - - if (booklets == null || !booklets.Any()) - { - // No booklets found, just return - return noErrorsOccured; - } - - logger.AddDownloadLogLine($"Goodies found, downloading...{Environment.NewLine}", true, true); - - using (HttpClient httpClient = new HttpClient()) - { - int counter = 1; - - foreach (Goody booklet in booklets) - { - string bookletFileName = counter == 1 ? "Digital Booklet.pdf" : $"Digital Booklet {counter}.pdf"; - string bookletFilePath = Path.Combine(basePath, bookletFileName); - - // Download booklet if file doesn't exist yet - if (System.IO.File.Exists(bookletFilePath)) - { - logger.AddDownloadLogLine($"Booklet file for \"{bookletFileName}\" already exists. Skipping.{Environment.NewLine}", true, true); - } - else - { - // When a booklet download fails, mark error occured but continue downloading others if they exist - if (!await DownloadBookletAsync(booklet, httpClient, bookletFileName, bookletFilePath)) noErrorsOccured = false; - } - - counter++; - } - } - - return noErrorsOccured; - } - - private async Task DownloadBookletAsync(Goody booklet, HttpClient httpClient, string fileName, string filePath) - { - bool noErrorsOccured = true; - - try - { - // Download booklet - await DownloadFileAsync(httpClient, booklet.Url, filePath); - - logger.AddDownloadLogLine($"Booklet \"{fileName}\" download complete!{Environment.NewLine}", true, true); - } - catch (AggregateException ae) - { - // When a Task fails, an AggregateException is thrown. Could be a HttpClient timeout or network error. - logger.AddDownloadLogErrorLine($"Goodies Download canceled, probably due to network error or request timeout. Details saved to error log.{Environment.NewLine}", true, true); - - logger.AddDownloadErrorLogLine("Goodies Download canceled, probably due to network error or request timeout."); - logger.AddDownloadErrorLogLine(ae.ToString()); - logger.AddDownloadErrorLogLine(Environment.NewLine); - noErrorsOccured = false; - } - catch (Exception downloadEx) - { - // If there is an unknown issue trying to, or during the download, show and log error info. - logger.AddDownloadLogErrorLine($"Unknown error during Goodies Download. Details saved to error log.{Environment.NewLine}", true, true); - - logger.AddDownloadErrorLogLine("Unknown error during Goodies Download."); - logger.AddDownloadErrorLogLine(downloadEx.ToString()); - logger.AddDownloadErrorLogLine(Environment.NewLine); - noErrorsOccured = false; - } - - return noErrorsOccured; - } - - private async Task DownloadAlbumsAsync(CancellationToken cancellationToken, string basePath, List albums, bool isEndOfDownloadJob) - { - bool noAlbumErrorsOccured = true; - - foreach (Album qobuzAlbum in albums) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - // Empty output, then say Starting Downloads. - logger.ClearUiLogComponent(); - logger.AddEmptyDownloadLogLine(true, false); - logger.AddDownloadLogLine($"Starting Downloads for album \"{qobuzAlbum.Title}\" with ID: <{qobuzAlbum.Id}>...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - bool albumDownloadOK = await DownloadAlbumAsync(cancellationToken, qobuzAlbum, basePath, $" [{qobuzAlbum.Id}]"); - - // If album download failed, mark error occured and continue - if (!albumDownloadOK) noAlbumErrorsOccured = false; - } - - if (isEndOfDownloadJob) - { - logger.LogFinishedDownloadJob(noAlbumErrorsOccured); - } - - return noAlbumErrorsOccured; - } - - // Convert Release to Album for download. - private async Task DownloadReleasesAsync(CancellationToken cancellationToken, string basePath, List releases) - { - bool noAlbumErrorsOccured = true; - - foreach (Release qobuzRelease in releases) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - // Fetch Album object corresponding to release - Album qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzRelease.Id, true, null, 0, 0)); - - // If API call failed, mark error occured and continue with next album - if (string.IsNullOrEmpty(qobuzAlbum.Id)) { noAlbumErrorsOccured = false; continue; } - - // Empty output, then say Starting Downloads. - logger.ClearUiLogComponent(); - logger.AddEmptyDownloadLogLine(true, false); - logger.AddDownloadLogLine($"Starting Downloads for album \"{qobuzAlbum.Title}\" with ID: <{qobuzAlbum.Id}>...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - bool albumDownloadOK = await DownloadAlbumAsync(cancellationToken, qobuzAlbum, basePath, $" [{qobuzAlbum.Id}]"); - - // If album download failed, mark error occured and continue - if (!albumDownloadOK) noAlbumErrorsOccured = false; - } - - return noAlbumErrorsOccured; - } - - private async Task DownloadArtistReleasesAsync(CancellationToken cancellationToken, Artist qobuzArtist, string basePath, string releaseType, bool isEndOfDownloadJob) - { - bool noErrorsOccured = true; - - // Get ReleasesList model object with first batch of releases - const int releasesLimit = 100; - int releasesOffset = 0; - ReleasesList releasesList = ExecuteApiCall(apiService => apiService.GetReleaseList(qobuzArtist.Id.ToString(), true, releaseType, "release_date", "desc", 0, releasesLimit, releasesOffset)); - - // If API call failed, abort Artist Download - if (releasesList == null) { return false; } - - bool continueDownload = true; - - while (continueDownload) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - // If releases download failed, mark artist error occured and continue with next artist - if (!await DownloadReleasesAsync(cancellationToken, basePath, releasesList.Items)) noErrorsOccured = false; - - if (releasesList.HasMore) - { - // Fetch next batch of releases - releasesOffset += releasesLimit; - releasesList = ExecuteApiCall(apiService => apiService.GetReleaseList(qobuzArtist.Id.ToString(), true, releaseType, "release_date", "desc", 0, releasesLimit, releasesOffset)); - } - else - { - continueDownload = false; - } - } - - if (isEndOfDownloadJob) - { - logger.LogFinishedDownloadJob(noErrorsOccured); - } - - return noErrorsOccured; - } - - public async Task StartDownloadItemTaskAsync(DownloadItem downloadItem, DownloadTaskStatusChanged downloadStartedCallback, DownloadTaskStatusChanged downloadStoppedCallback) - { - // Create new cancellation token source. - using (this.cancellationTokenSource = new CancellationTokenSource()) - { - IsBuzy = true; - - try - { - downloadStartedCallback?.Invoke(); - - // Link should be valid here, start new download log - logger.DownloadLogPath = Path.Combine(Globals.LoggingDir, $"Download_Log_{DateTime.Now:yyyy-MM-dd_HH.mm.ss.fff}.log"); - - string logLine = $"Downloading <{CultureInfo.CurrentCulture.TextInfo.ToTitleCase(downloadItem.Type)}> from {downloadItem.Url}"; - logger.AddDownloadLogLine(new string('=', logLine.Length).PadRight(logLine.Length), true); - logger.AddDownloadLogLine(logLine, true); - logger.AddDownloadLogLine(new string('=', logLine.Length).PadRight(logLine.Length), true); - logger.AddEmptyDownloadLogLine(true); - - DownloadInfo = new DownloadItemInfo - { - DownloadItemID = downloadItem.Id - }; - DownloadPaths = DownloadInfo.CurrentDownloadPaths; - - switch (downloadItem.Type) - { - case "track": - await StartDownloadTrackTaskAsync(cancellationTokenSource.Token); - break; - case "album": - await StartDownloadAlbumTaskAsync(cancellationTokenSource.Token); - break; - - case "artist": - await StartDownloadArtistDiscogTaskAsync(cancellationTokenSource.Token); - break; - - case "label": - await StartDownloadLabelTaskAsync(cancellationTokenSource.Token); - break; - - case "user": - if (DownloadInfo.DownloadItemID == @"library/favorites/albums") - { - await StartDownloadFaveAlbumsTaskAsync(cancellationTokenSource.Token); - } - else if (DownloadInfo.DownloadItemID == @"library/favorites/artists") - { - await StartDownloadFaveArtistsTaskAsync(cancellationTokenSource.Token); - } - else if (DownloadInfo.DownloadItemID == @"library/favorites/tracks") - { - await StartDownloadFaveTracksTaskAsync(cancellationTokenSource.Token); - } - else - { - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine($"You entered an invalid user favorites link.{Environment.NewLine}", true, true); - logger.AddDownloadLogLine($"Favorite Tracks, Albums & Artists are supported with the following links:{Environment.NewLine}", true, true); - logger.AddDownloadLogLine($"Tracks - https://play.qobuz.com/user/library/favorites/tracks{Environment.NewLine}", true, true); - logger.AddDownloadLogLine($"Albums - https://play.qobuz.com/user/library/favorites/albums{Environment.NewLine}", true, true); - logger.AddDownloadLogLine($"Artists - https://play.qobuz.com/user/library/favorites/artists{Environment.NewLine}", true, true); - } - break; - - case "playlist": - await StartDownloadPlaylistTaskAsync(cancellationTokenSource.Token); - break; - default: - // We shouldn't get here?!? I'll leave this here just in case... - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("URL not understood. Is there a typo?", true, true); - break; - } - } - catch (OperationCanceledException) - { - // Handle cancellation. - logger.AddEmptyDownloadLogLine(true, true); - logger.AddDownloadLogLine("Download stopped by user!", true, true); - } - finally - { - downloadStoppedCallback?.Invoke(); - IsBuzy = false; - } - } - } - - // For downloading "track" links - private async Task StartDownloadTrackTaskAsync(CancellationToken cancellationToken) - { - // Empty screen output, then say Grabbing info. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine($"Grabbing Track info...{Environment.NewLine}", true, true); - - // Set "basePath" as the selected path. - string downloadBasePath = Settings.Default.savedFolder; - - try - { - Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(DownloadInfo.DownloadItemID, true)); - - // If API call failed, abort - if (qobuzTrack == null) { return; } - - logger.AddDownloadLogLine($"Track \"{qobuzTrack.Title}\" found. Starting Download...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - bool fileDownloaded = await DownloadTrackAsync(cancellationToken, qobuzTrack, downloadBasePath, true, false, true); - - // If download failed, abort - if (!fileDownloaded) { return; } - - // Say that downloading is completed. - logger.AddEmptyDownloadLogLine(true, true); - logger.AddDownloadLogLine("Download job completed! All downloaded files will be located in your chosen path.", true, true); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.LogDownloadTaskException("Track", downloadEx); - } - } - - // For downloading "album" links - private async Task StartDownloadAlbumTaskAsync(CancellationToken cancellationToken) - { - // Empty screen output, then say Grabbing info. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine($"Grabbing Album info...{Environment.NewLine}", true, true); - - // Set "basePath" as the selected path. - String downloadBasePath = Settings.Default.savedFolder; - - try - { - // Get Album model object without tracks (tracks are loaded in batches later) - Album qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(DownloadInfo.DownloadItemID, true, null, 0)); - - // If API call failed, abort - if (qobuzAlbum == null) { return; } - - logger.AddDownloadLogLine($"Album \"{qobuzAlbum.Title}\" found. Starting Downloads...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - logger.LogFinishedDownloadJob(await DownloadAlbumAsync(cancellationToken, qobuzAlbum, downloadBasePath)); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.LogDownloadTaskException("Album", downloadEx); - } - } - - // For downloading "artist" links - private async Task StartDownloadArtistDiscogTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path. - String artistBasePath = Settings.Default.savedFolder; - - // Empty output, then say Grabbing IDs. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Artist info...", true, true); - - try - { - // Get Artist model object - Artist qobuzArtist = ExecuteApiCall(apiService => apiService.GetArtist(DownloadInfo.DownloadItemID, true)); - - // If API call failed, abort - if (qobuzArtist == null) { return; } - - logger.AddDownloadLogLine($"Starting Downloads for artist \"{qobuzArtist.Name}\" with ID: <{qobuzArtist.Id}>...", true, true); - - await DownloadArtistReleasesAsync(cancellationToken, qobuzArtist, artistBasePath, "all", true); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Artist", downloadEx); - } - } - - // For downloading "label" links - private async Task StartDownloadLabelTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path + "/- Labels". - string labelBasePath = Path.Combine(Settings.Default.savedFolder, "- Labels"); - - // Empty output, then say Grabbing IDs. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Label albums...", true, true); - - try - { - // Initialise full Album list - QobuzApiSharp.Models.Content.Label qobuzLabel = null; - List labelAlbums = new List(); - const int albumLimit = 500; - int albumsOffset = 0; - - while (true) - { - // Get Label model object with albums - qobuzLabel = ExecuteApiCall(apiService => apiService.GetLabel(DownloadInfo.DownloadItemID, true, "albums", albumLimit, albumsOffset)); - - // If API call failed, abort - if (qobuzLabel == null) { return; } - - // If resulting Label has no Album Items, Qobuz API maximum offset is reached - if (qobuzLabel.Albums?.Items?.Any() != true) break; - - labelAlbums.AddRange(qobuzLabel.Albums.Items); - - // Exit loop when all albums are loaded or the Qobuz imposed limit of 10000 is reached - if ((qobuzLabel.Albums?.Total ?? 0) == labelAlbums.Count) break; - - albumsOffset += albumLimit; - } - - // If label has no albums, log and abort - if (!labelAlbums.Any()) - { - logger.AddDownloadLogLine($"No albums found for label \"{qobuzLabel.Name}\" with ID: <{qobuzLabel.Id}>, nothing to download.", true, true); - return; - } - - logger.AddDownloadLogLine($"Starting Downloads for label \"{qobuzLabel.Name}\" with ID: <{qobuzLabel.Id}>...", true, true); - - // Add Label name to basePath - string safeLabelName = StringTools.GetSafeFilename(StringTools.DecodeEncodedNonAsciiCharacters(qobuzLabel.Name)); - labelBasePath = Path.Combine(labelBasePath, safeLabelName); - - await DownloadAlbumsAsync(cancellationToken, labelBasePath, labelAlbums, true); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Label", downloadEx); - } - } - - // For downloading "favorites" - - // Favorite Albums - private async Task StartDownloadFaveAlbumsTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path + "/- Favorites". - string favoritesBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); - - // Empty output, then say Grabbing IDs. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Favorite Albums...", true, true); - - try - { - // Initialise full Album list - List favoriteAlbums = new List(); - const int albumLimit = 500; - int albumsOffset = 0; - - while (true) - { - // Get UserFavorites model object with albums - UserFavorites qobuzUserFavorites = ExecuteApiCall(apiService => apiService.GetUserFavorites(DownloadInfo.DownloadItemID, "albums", albumLimit, albumsOffset)); - - // If API call failed, abort - if (qobuzUserFavorites == null) { return; } - - // If resulting UserFavorites has no Album Items, Qobuz API maximum offset is reached - if (qobuzUserFavorites.Albums?.Items?.Any() != true) break; - - favoriteAlbums.AddRange(qobuzUserFavorites.Albums.Items); - - // Exit loop when all albums are loaded - if ((qobuzUserFavorites.Albums?.Total ?? 0) == favoriteAlbums.Count) break; - - albumsOffset += albumLimit; - } - - // If user has no favorite albums, log and abort - if (!favoriteAlbums.Any()) - { - logger.AddDownloadLogLine("No favorite albums found, nothing to download.", true, true); - return; - } - - // Download all favorite albums - await DownloadAlbumsAsync(cancellationToken, favoritesBasePath, favoriteAlbums, true); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Favorite Albums", downloadEx); - } - } - - // Favorite Artists - private async Task StartDownloadFaveArtistsTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path + "/- Favorites". - string favoritesBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); - - // Empty output, then say Grabbing IDs. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Favorite Artists...", true, true); - - try - { - bool noArtistErrorsOccured = true; - - // Get UserFavoritesIds model object, getting Id's allows all results at once. - UserFavoritesIds qobuzUserFavoritesIds = ExecuteApiCall(apiService => apiService.GetUserFavoriteIds(DownloadInfo.DownloadItemID)); - - // If API call failed, abort - if (qobuzUserFavoritesIds == null) { return; } - - // If user has no favorite artists, log and abort - if (qobuzUserFavoritesIds.Artists?.Any() != true) - { - logger.AddDownloadLogLine("No favorite artists found, nothing to download.", true, true); - return; - } - - // Download favorite artists - foreach (int favoriteArtistId in qobuzUserFavoritesIds.Artists) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - // Get Artist model object - Artist qobuzArtist = ExecuteApiCall(apiService => apiService.GetArtist(favoriteArtistId.ToString(), true)); - - // If API call failed, mark artist error occured and continue with next artist - if (qobuzArtist == null) { noArtistErrorsOccured = false; continue; } - - logger.AddEmptyDownloadLogLine(true, true); - logger.AddDownloadLogLine($"Starting Downloads for artist \"{qobuzArtist.Name}\" with ID: <{qobuzArtist.Id}>...", true, true); - - // If albums download failed, mark artist error occured and continue with next artist - if (!await DownloadArtistReleasesAsync(cancellationToken, qobuzArtist, favoritesBasePath, "all", false)) noArtistErrorsOccured = false; - } - - logger.LogFinishedDownloadJob(noArtistErrorsOccured); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Favorite Albums", downloadEx); - } - } - - // Favorite Tracks - private async Task StartDownloadFaveTracksTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path + "/- Favorites". - string favoriteTracksBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); - - // Empty screen output, then say Grabbing info. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Favorite Tracks...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - try - { - bool noTrackErrorsOccured = true; - - // Get UserFavoritesIds model object, getting Id's allows all results at once. - UserFavoritesIds qobuzUserFavoritesIds = ExecuteApiCall(apiService => apiService.GetUserFavoriteIds(DownloadInfo.DownloadItemID)); - - // If API call failed, abort - if (qobuzUserFavoritesIds == null) { return; } - - // If user has no favorite tracks, log and abort - if (qobuzUserFavoritesIds.Tracks?.Any() != true) - { - logger.AddDownloadLogLine("No favorite tracks found, nothing to download.", true, true); - return; - } - - logger.AddDownloadLogLine("Favorite tracks found. Starting Downloads...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - // Download favorite tracks - foreach (int favoriteTrackId in qobuzUserFavoritesIds.Tracks) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(favoriteTrackId.ToString(), true)); - - // If API call failed, log and continue with next track - if (qobuzTrack == null) { noTrackErrorsOccured = false; continue; } - - if (!await DownloadTrackAsync(cancellationToken, qobuzTrack, favoriteTracksBasePath, true, false, true)) noTrackErrorsOccured = false; - } - - logger.LogFinishedDownloadJob(noTrackErrorsOccured); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Playlist", downloadEx); - } - } - - // For downloading "playlist" links - private async Task StartDownloadPlaylistTaskAsync(CancellationToken cancellationToken) - { - // Set "basePath" as the selected path. - String playlistBasePath = Settings.Default.savedFolder; - - // Empty screen output, then say Grabbing info. - logger.ClearUiLogComponent(); - logger.AddDownloadLogLine("Grabbing Playlist tracks...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - try - { - // Get Playlist model object with all track_ids - Playlist qobuzPlaylist = ExecuteApiCall(apiService => apiService.GetPlaylist(DownloadInfo.DownloadItemID, true, "track_ids", 10000)); - - // If API call failed, abort - if (qobuzPlaylist == null) { return; } - - // If playlist empty, log and abort - if (qobuzPlaylist.TrackIds?.Any() != true) - { - logger.AddDownloadLogLine($"Playlist \"{qobuzPlaylist.Name}\" is empty, nothing to download.", true, true); - return; - } - - logger.AddDownloadLogLine($"Playlist \"{qobuzPlaylist.Name}\" found. Starting Downloads...", true, true); - logger.AddEmptyDownloadLogLine(true, true); - - // Create Playlist root directory. - string playlistSafeName = StringTools.GetSafeFilename(StringTools.DecodeEncodedNonAsciiCharacters(qobuzPlaylist.Name)); - string playlistNamePath = StringTools.TrimToMaxLength(playlistSafeName, Globals.MaxLength); - playlistBasePath = Path.Combine(playlistBasePath, "- Playlists", playlistNamePath); - System.IO.Directory.CreateDirectory(playlistBasePath); - - // Download Playlist cover art to "Playlist.jpg" in root directory (if not exists) - string coverArtFilePath = Path.Combine(playlistBasePath, "Playlist.jpg"); - - if (!System.IO.File.Exists(coverArtFilePath)) - { - try - { - using (WebClient imgClient = new WebClient()) - { - imgClient.DownloadFile(new Uri(qobuzPlaylist.ImageRectangle.FirstOrDefault()), coverArtFilePath); - } - } - catch (Exception ex) - { - // Qobuz servers throw a 404 as if the image doesn't exist. - logger.AddDownloadErrorLogLines(new string[] { "Error downloading full size playlist cover image file.", ex.Message, "\r\n" }); - } - } - - bool noTrackErrorsOccured = true; - - // Start new m3u Playlist file. - M3uPlaylist m3uPlaylist = new M3uPlaylist(); - m3uPlaylist.IsExtended = true; - - // Download Playlist tracks - foreach (long trackId in qobuzPlaylist.TrackIds) - { - // User requested task cancellation! - cancellationToken.ThrowIfCancellationRequested(); - - // Fetch full Track info - Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(trackId.ToString(), true)); - - // If API call failed, log and continue with next track - if (qobuzTrack == null) { noTrackErrorsOccured = false; continue; } - - if (!IsStreamable(qobuzTrack, true)) continue; - - if (!await DownloadTrackAsync(cancellationToken, qobuzTrack, playlistBasePath, true, false, true)) noTrackErrorsOccured = false; - - AddTrackToPlaylistFile(m3uPlaylist, DownloadInfo, DownloadPaths); - } - - // Write m3u playlist to file, override if exists - string m3uPlaylistFile = Path.Combine(playlistBasePath, $"{playlistSafeName}.m3u8"); - System.IO.File.WriteAllText(m3uPlaylistFile, PlaylistToTextHelper.ToText(m3uPlaylist), System.Text.Encoding.UTF8); - - logger.LogFinishedDownloadJob(noTrackErrorsOccured); - - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // Rethrow when cancellation requested by user. - throw; - } - catch (Exception downloadEx) - { - logger.ClearUiLogComponent(); - logger.LogDownloadTaskException("Playlist", downloadEx); - } - } - - public void AddTrackToPlaylistFile(M3uPlaylist m3uPlaylist, DownloadItemInfo downloadInfo, DownloadItemPaths downloadPaths) - { - // If the TrackFile doesn't exist, skip. - if (!System.IO.File.Exists(downloadPaths.FullTrackFilePath)) return; - - // Add successfully downloaded file to m3u playlist - m3uPlaylist.PlaylistEntries.Add(new M3uPlaylistEntry() - { - Path = downloadPaths.FullTrackFilePath, - Duration = TimeSpan.FromSeconds(DownloadInfo.Duration), - Title = $"{downloadInfo.PerformerName} - {downloadInfo.TrackName}" - }); - } - - public void CreateTrackDirectories(string basePath, string qualityPath, string albumPathSuffix = "", bool forTracklist = false) - { - if (forTracklist) - { - DownloadPaths.Path1Full = basePath; - DownloadPaths.Path2Full = DownloadPaths.Path1Full; - DownloadPaths.Path3Full = Path.Combine(basePath, qualityPath); - DownloadPaths.Path4Full = DownloadPaths.Path3Full; - } - else - { - DownloadPaths.Path1Full = Path.Combine(basePath, DownloadPaths.AlbumArtistPath); - DownloadPaths.Path2Full = Path.Combine(basePath, DownloadPaths.AlbumArtistPath, DownloadPaths.AlbumNamePath + albumPathSuffix); - DownloadPaths.Path3Full = Path.Combine(basePath, DownloadPaths.AlbumArtistPath, DownloadPaths.AlbumNamePath + albumPathSuffix, qualityPath); - - // If more than 1 disc, create folders for discs. Otherwise, strings will remain null - // Pad discnumber with minimum of 2 integer positions based on total number of disks - if (DownloadInfo.DiscTotal > 1) - { - // Create strings for disc folders - string discFolder = "CD " + DownloadInfo.DiscNumber.ToString().PadLeft(Math.Max(2, (int)Math.Floor(Math.Log10(DownloadInfo.DiscTotal) + 1)), '0'); - DownloadPaths.Path4Full = Path.Combine(basePath, DownloadPaths.AlbumArtistPath, DownloadPaths.AlbumNamePath + albumPathSuffix, qualityPath, discFolder); - } - else - { - DownloadPaths.Path4Full = DownloadPaths.Path3Full; - } - } - - System.IO.Directory.CreateDirectory(DownloadPaths.Path4Full); - } - } -} \ No newline at end of file diff --git a/QobuzDownloaderX/Shared/DownloadRequest.cs b/QobuzDownloaderX/Shared/DownloadRequest.cs new file mode 100644 index 0000000..16d093b --- /dev/null +++ b/QobuzDownloaderX/Shared/DownloadRequest.cs @@ -0,0 +1,818 @@ +using DownloadAssistant.Options; +using DownloadAssistant.Requests; +using PlaylistsNET.Content; +using PlaylistsNET.Models; +using QobuzApiSharp.Exceptions; +using QobuzApiSharp.Models.Content; +using QobuzApiSharp.Service; +using QobuzDownloaderX.Models; +using QobuzDownloaderX.Models.Content; +using QobuzDownloaderX.Properties; +using Requests; +using Requests.Options; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace QobuzDownloaderX.Shared +{ + internal class DownloadRequest : Request, ISpeedReportable + { + private readonly DownloadLogger _logger; + private readonly DownloadItem _downloadItem; + private readonly ConcurrentDictionary _downloadInfoDict = new(); + private readonly ConcurrentDictionary _downloadPathsDict = new(); + private bool _isAlbum = false; + private readonly ExtendedContainer _requestContainer = []; + private bool _isRequestContainerFilled = false; + private readonly HashSet _IdContainer = []; + + public bool IsAlbum => _isAlbum; + + public SpeedReporter SpeedReporter => _requestContainer.SpeedReporter; + + public DownloadRequest(DownloadRequestOptions options) + : base(options) + { + _logger = options.Logger; + _downloadItem = options.DownloadItem; + AutoStart(); + } + + protected override async Task RunRequestAsync() + { + RequestReturn requestReturn = new(); + try + { + requestReturn.Successful = await StartDownloadItemTaskAsync(); + } + catch (Exception ex) + { + requestReturn.Successful = false; + AddException(ex); + } + return requestReturn; + } + + private async Task StartDownloadItemTaskAsync() + { + string logLine = $"Downloading <{CultureInfo.CurrentCulture.TextInfo.ToTitleCase(_downloadItem.Type)}> from {_downloadItem.Url}"; + _logger.AddDownloadLogLine(new string('=', logLine.Length), true); + _logger.AddDownloadLogLine(logLine, true); + _logger.AddDownloadLogLine(new string('=', logLine.Length), true); + _logger.AddEmptyDownloadLogLine(true); + if (_isRequestContainerFilled == true) + return await WaitOnCompletion(); + + string key = _downloadItem.Id.ToString(); + _downloadInfoDict[key] = new DownloadItemInfo { DownloadItemID = _downloadItem.Id }; + _downloadPathsDict[key] = _downloadInfoDict[key].CurrentDownloadPaths; + return _downloadItem.Type switch + { + "track" => await StartDownloadTrackTaskAsync(), + "album" => await StartDownloadAlbumTaskAsync(), + "artist" => await StartDownloadArtistDiscogTaskAsync(), + "label" => await StartDownloadLabelTaskAsync(), + "user" => _downloadInfoDict[key].DownloadItemID switch + { + @"library/favorites/albums" => await StartDownloadFaveAlbumsTaskAsync(), + @"library/favorites/artists" => await StartDownloadFaveArtistsTaskAsync(), + @"library/favorites/tracks" => await StartDownloadFaveTracksTaskAsync(), + _ => InvalidUserFavoritesLink(), + }, + "playlist" => await StartDownloadPlaylistTaskAsync(), + _ => InvalidUrl(), + }; + bool InvalidUserFavoritesLink() + { + _logger.AddDownloadLogLine("Invalid user favorites link.", true, true); + _logger.AddDownloadLogLine("Supported links: Tracks, Albums & Artists.", true, true); + return ReturnFail(); + } + + bool InvalidUrl() + { + _logger.AddDownloadLogLine($"URL >{_downloadItem.Url}< not understood. Is there a typo?", true, true); + return ReturnFail(); + } + } + + private async Task WaitOnCompletion() + { + if (State != RequestState.Running) + return false; + _isRequestContainerFilled = true; + await _requestContainer.Task; + await Task.Delay(1000); + _logger.LogFinishedDownloadJob(true); + return true; + } + + private T ExecuteApiCall(Func apiCall) + { + try { return apiCall(QobuzApiServiceManager.GetApiService()); } + catch (Exception ex) + { + AddException(ex); + _logger.AddEmptyDownloadLogLine(false, true); + _logger.AddDownloadLogErrorLine("Communication problem with Qobuz API. Details saved to error log", true, true); + _logger.AddDownloadErrorLogLines(GetErrorLines(ex)); + return default; + } + } + + private static string[] GetErrorLines(Exception ex) + { + return ex switch + { + ApiErrorResponseException erEx => ["Failed API request:", erEx.RequestContent, $"Api response code: {erEx.ResponseStatusCode}", $"Api response status: {erEx.ResponseStatus}", $"Api response reason: {erEx.ResponseReason}"], + ApiResponseParseErrorException pEx => ["Error parsing API response", $"Api response content: {pEx.ResponseContent}"], + _ => ["Unknown error trying API request:", ex.ToString()], + }; + } + + public bool IsStreamable(Track qobuzTrack, bool inPlaylist = false) + { + if (qobuzTrack.Streamable != false) + return true; + + string trackReference = inPlaylist ? $"{qobuzTrack.Performer?.Name} - {qobuzTrack.Title}" : $"{qobuzTrack.TrackNumber.GetValueOrDefault()} {StringTools.DecodeEncodedNonAsciiCharacters(qobuzTrack.Title.Trim())}"; + + _logger.AddDownloadLogLine($"Track {trackReference} is not available for streaming. Unable to download.\r\n", true, true); + return Options.CheckIfStreamable; + } + + private bool DownloadTrack(Track qobuzTrack, string basePath, bool isPartOfTracklist, bool removeTagArtFileAfterDownload = false, string albumPathSuffix = "") + { + if (_IdContainer.Contains(qobuzTrack.Id.ToString())) + return true; + if (State != RequestState.Running && State != RequestState.Idle) + return false; + + string key = qobuzTrack.Id.ToString(); + _downloadInfoDict[key] = new DownloadItemInfo { DownloadItemID = qobuzTrack.Id.ToString() }; + _downloadInfoDict[key].SetAlbumDownloadInfo(qobuzTrack.Album); + _downloadInfoDict[key].SetTrackTaggingInfo(qobuzTrack); + + _downloadPathsDict[key] = _downloadInfoDict[key].CurrentDownloadPaths; + + if (!_isAlbum) + Options.UpdateAlbumTagsUi.Invoke(_downloadInfoDict[key]); + if (!IsStreamable(qobuzTrack, isPartOfTracklist)) + return ReturnFail(); + + CreateTrackDirectories(basePath, _downloadPathsDict[key].QualityPath, key, albumPathSuffix, isPartOfTracklist); + string trackPath = _downloadInfoDict[key].CurrentDownloadPaths.Path4Full; + + if (!PrepareTrackFile(trackPath, isPartOfTracklist, key)) + return true; + + string streamUrl = ExecuteApiCall(apiService => apiService.GetTrackFileUrl(qobuzTrack.Id.ToString(), Globals.FormatIdString))?.Url; + + if (string.IsNullOrEmpty(streamUrl)) + { + _logger.AddDownloadLogLine($"Couldn't get streaming URL for Track \"{_downloadPathsDict[key].FinalTrackNamePath}\". Skipping.\r\n", true, true); + return ReturnFail(); + } + Task.Delay(50).Wait(); //Issue with the library! Too fast populated! + if (DownloadCoverArt(isPartOfTracklist, key) is GetRequest getReq) + _requestContainer.Add(getReq); + + _requestContainer.Add(DownloadTrackFile(streamUrl, trackPath, key)); + _IdContainer.Add(qobuzTrack.Id.ToString()); + + if (removeTagArtFileAfterDownload) + { + Notify x = (_, _) => RemoveTempTaggingArtFile(key); + Options.RequestCompleated = (Notify)Delegate.Combine(Options.RequestCompleated, x); + } + return true; + } + + private bool PrepareTrackFile(string trackPath, bool isPartOfTracklist, string key) + { + string paddedTrackNumber = _downloadInfoDict[key].TrackNumber.ToString().PadLeft(Math.Max(2, (int)Math.Floor(Math.Log10(_downloadInfoDict[key].TrackTotal) + 1)), '0'); + _downloadPathsDict[key].FinalTrackNamePath = isPartOfTracklist ? string.Concat(_downloadPathsDict[key].PerformerNamePath, Globals.FileNameTemplateString, _downloadPathsDict[key].TrackNamePath).TrimEnd() : string.Concat(paddedTrackNumber, Globals.FileNameTemplateString, _downloadPathsDict[key].TrackNamePath).TrimEnd(); + _downloadPathsDict[key].FinalTrackNamePath = StringTools.TrimToMaxLength(_downloadPathsDict[key].FinalTrackNamePath, Globals.MaxLength); + _downloadPathsDict[key].FullTrackFileName = _downloadPathsDict[key].FinalTrackNamePath + Globals.AudioFileType; + _downloadPathsDict[key].FullTrackFilePath = Path.Combine(trackPath, _downloadPathsDict[key].FullTrackFileName); + + if (File.Exists(_downloadPathsDict[key].FullTrackFilePath)) + { + _logger.AddDownloadLogLine($"File for \"{_downloadPathsDict[key].FinalTrackNamePath}\" already exists. Skipping.\r\n", true, true); + return false; + } + return true; + } + + private GetRequest DownloadTrackFile(string streamUrl, string trackPath, string key) => new(streamUrl, new() + { + IsDownload = true, + DirectoryPath = trackPath, + Filename = _downloadPathsDict[key].FullTrackFileName, + NumberOfAttempts = 3, + SpeedReporter = new SpeedReporter(), + RequestStarted = (req) => _logger.AddDownloadLogLine($"Start Downloading - {((GetRequest)req).Filename} ...... \r\n", true, true), + RequestCompleated = (req, _) => + { + string coverArtTagFilePath = Path.Combine(trackPath, Globals.TaggingOptions.ArtSize + ".jpg"); + AudioFileTagger.AddMetaDataTags(_downloadInfoDict[key], (req as GetRequest).FilePath, File.Exists(coverArtTagFilePath) ? coverArtTagFilePath : Path.Combine(trackPath, "Cover.jpg"), _logger); + _logger.AddDownloadLogLine($"Track {(req as GetRequest).Filename} Download Done!\r\n", true, true); + }, + RequestCancelled = req => HandleDownloadException(req.Exception, "Track Download canceled, probably due to network error or request timeout."), + RequestFailed = (req, _) => HandleDownloadException(req.Exception, "Unknown error during Track Download.") + }); + + private GetRequest DownloadCoverArt(bool isPartOfTracklist, string key) + { + string coverArtTagFilePath = Path.Combine(_downloadPathsDict[key].Path3Full, Globals.TaggingOptions.ArtSize + ".jpg"); + if (!File.Exists(coverArtTagFilePath)) + return new(_downloadInfoDict[key].FrontCoverImgTagUrl, new GetRequestOptions + { + IsDownload = true, + Priority = RequestPriority.High, + SpeedReporter = new SpeedReporter(), + DirectoryPath = _downloadPathsDict[key].Path3Full, + Filename = Globals.TaggingOptions.ArtSize + ".jpg", + NumberOfAttempts = 2, + RequestFailed = (req, _) => _logger.AddDownloadErrorLogLines(["Error downloading image file for tagging.", req.Exception.Message, Environment.NewLine]) + }); + + string coverArtFilePath = Path.Combine(_downloadPathsDict[key].Path3Full, "Cover.jpg"); + + if (!isPartOfTracklist && !File.Exists(coverArtFilePath)) + return new(_downloadInfoDict[key].FrontCoverImgUrl, new() + { + IsDownload = true, + SpeedReporter = new SpeedReporter(), + DirectoryPath = _downloadPathsDict[key].Path3Full, + Filename = "Cover.jpg", + Priority = RequestPriority.High, + NumberOfAttempts = 1, + RequestFailed = (req, _) => _logger.AddDownloadErrorLogLines(["Error downloading full size cover image file.", req.Exception.Message, Environment.NewLine]) + }); + return null; + } + + private void RemoveTempTaggingArtFile(string key) + { + try + { + string coverArtTagFilePath = Path.Combine(_downloadPathsDict[key].Path3Full, Globals.TaggingOptions.ArtSize + ".jpg"); + if (File.Exists(coverArtTagFilePath)) + File.Delete(coverArtTagFilePath); + } + catch + { + } + } + + private void HandleDownloadException(Exception ex, string message) + { + _logger.AddDownloadLogErrorLine($"{message} Details saved to error log.{Environment.NewLine}", true, true); + _logger.AddDownloadErrorLogLine(message); + _logger.AddDownloadErrorLogLine(ex?.ToString()); + _logger.AddDownloadErrorLogLine(Environment.NewLine); + } + + private bool DownloadAlbum(Album qobuzAlbum, string basePath, string albumPathSuffix = "") + { + bool noErrorsOccured = true; + const int tracksLimit = 50; + qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzAlbum.Id, true, null, tracksLimit, 0)); + + if (string.IsNullOrEmpty(qobuzAlbum.Id)) + return ReturnFail(); + + string albumKey = qobuzAlbum.Id.ToString(); + _downloadInfoDict[albumKey] = new DownloadItemInfo { DownloadItemID = albumKey }; + _downloadInfoDict[albumKey].SetAlbumDownloadInfo(qobuzAlbum); + _downloadPathsDict[albumKey] = _downloadInfoDict[albumKey].CurrentDownloadPaths; + + Options.UpdateAlbumTagsUi.Invoke(_downloadInfoDict[albumKey]); + _isAlbum = true; + int tracksTotal = qobuzAlbum.Tracks.Total ?? 0; + int tracksPageOffset = qobuzAlbum.Tracks.Offset ?? 0; + int tracksLoaded = qobuzAlbum.Tracks.Items?.Count ?? 0; + int i = 0; + + while (i < tracksLoaded) + { + if (State != RequestState.Running && State != RequestState.Idle) + return false; + bool isLastTrackOfAlbum = i + tracksPageOffset == tracksTotal - 1; + Track qobuzTrack = qobuzAlbum.Tracks.Items[i]; + qobuzTrack.Album = qobuzAlbum; + + if (!DownloadTrack(qobuzTrack, basePath, false, isLastTrackOfAlbum, albumPathSuffix)) + noErrorsOccured = false; + + i++; + if (i == tracksLoaded && tracksTotal > i + tracksPageOffset) + { + tracksPageOffset += tracksLimit; + qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzAlbum.Id, true, null, tracksLimit, tracksPageOffset)); + + if (string.IsNullOrEmpty(qobuzAlbum.Id)) + return false; + if (qobuzAlbum.Tracks?.Items?.Any() != true) + break; + i = 0; + tracksLoaded = qobuzAlbum.Tracks.Items?.Count ?? 0; + } + } + + DownloadBooklets(qobuzAlbum, _downloadPathsDict[albumKey].Path3Full); + return noErrorsOccured; + } + + private void DownloadBooklets(Album qobuzAlbum, string basePath) + { + List booklets = qobuzAlbum.Goodies?.Where(g => g.FileFormatId == (int)GoodiesFileType.BOOKLET).ToList(); + + if (booklets == null || !booklets.Any()) + return; + + _logger.AddDownloadLogLine($"Goodies found, downloading...{Environment.NewLine}", true, true); + int counter = 1; + + foreach (Goody booklet in booklets) + { + string bookletFileName = counter == 1 ? "Digital Booklet.pdf" : $"Digital Booklet {counter}.pdf"; + string bookletFilePath = Path.Combine(basePath, bookletFileName); + if (File.Exists(bookletFilePath)) + _logger.AddDownloadLogLine($"Booklet file for \"{bookletFileName}\" already exists. Skipping.{Environment.NewLine}", true, true); + else + _requestContainer.Add(DownloadBooklet(booklet, bookletFileName, bookletFilePath)); + counter++; + } + } + + private GetRequest DownloadBooklet(Goody booklet, string fileName, string filePath) => new(booklet.Url, new() + { + IsDownload = true, + Filename = fileName, + DirectoryPath = filePath, + NumberOfAttempts = 1, + RequestCompleated = (req, _) => _logger.AddDownloadLogLine($"Booklet \"{fileName}\" download complete!{Environment.NewLine}", true, true), + RequestFailed = (req, _) => HandleBookletDownloadException(req.Exception) + }); + + private void HandleBookletDownloadException(Exception ex) + { + if (ex.InnerException is AggregateException ae) + { + _logger.AddDownloadLogErrorLine("Goodies Download canceled, probably due to network error or request timeout. Details saved to error log.", true, true); + _logger.AddDownloadErrorLogLine(ae.ToString()); + } + else + { + _logger.AddDownloadLogErrorLine("Unknown error during Goodies Download. Details saved to error log.", true, true); + _logger.AddDownloadErrorLogLine(ex.ToString()); + } + _logger.AddDownloadErrorLogLine(Environment.NewLine); + } + + private async Task DownloadAlbums(string basePath, List albums, bool isEndOfDownloadJob) + { + bool noAlbumErrorsOccured = true; + var albumContainer = new RequestContainer(); + + if (!_IdContainer.Contains("DownloadAlbums")) + { + foreach (Album qobuzAlbum in albums) + { + albumContainer.Add(new OwnRequest((token) => + { + //_logger.ClearUiLogComponent(); + + if (!DownloadAlbum(qobuzAlbum, basePath, $" [{qobuzAlbum.Id}]")) + noAlbumErrorsOccured = false; + return Task.FromResult(true); + }, new RequestOptions() + { + Priority = RequestPriority.Low, + NumberOfAttempts = 1, + RequestStarted = (req) => + { + _logger.AddEmptyDownloadLogLine(true, false); + _logger.AddDownloadLogLine($"Creating Download requests for album \"{qobuzAlbum.Title}\" with ID: <{qobuzAlbum.Id}>...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + }, + Handler = RequestHandler.MainRequestHandlers[1] + })); + } + _IdContainer.Add("DownloadAlbums"); + } + + _requestContainer.Add(albumContainer); + await albumContainer.Task; + return noAlbumErrorsOccured; + } + + private async Task DownloadReleases(string basePath, List releases) + { + bool noAlbumErrorsOccured = true; + foreach (Release qobuzRelease in releases) + { + if (State != RequestState.Running) + return false; + Album qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(qobuzRelease.Id, true, null, 0, 0)); + + if (string.IsNullOrEmpty(qobuzAlbum.Id)) + { + noAlbumErrorsOccured = false; + continue; + } + _logger.AddEmptyDownloadLogLine(true, false); + _logger.AddDownloadLogLine($"Creating Download requests for album \"{qobuzAlbum.Title}\" with ID: <{qobuzAlbum.Id}>...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + if (!DownloadAlbum(qobuzAlbum, basePath, $" [{qobuzAlbum.Id}]")) + noAlbumErrorsOccured = false; + await _requestContainer.Task; + } + return noAlbumErrorsOccured; + } + + private async Task DownloadArtistReleases(Artist qobuzArtist, string basePath, string releaseType, bool isEndOfDownloadJob) + { + bool noErrorsOccured = true; + const int releasesLimit = 100; + int releasesOffset = 0; + ReleasesList releasesList = ExecuteApiCall(apiService => apiService.GetReleaseList(qobuzArtist.Id.ToString(), true, releaseType, "release_date", "desc", 0, releasesLimit, releasesOffset)); + + if (releasesList == null) + return ReturnFail(); + bool continueDownload = true; + while (continueDownload) + { + if (State != RequestState.Running) + return false; + if (!await DownloadReleases(basePath, releasesList.Items)) + noErrorsOccured = false; + if (releasesList.HasMore) + { + releasesOffset += releasesLimit; + releasesList = ExecuteApiCall(apiService => apiService.GetReleaseList(qobuzArtist.Id.ToString(), true, releaseType, "release_date", "desc", 0, releasesLimit, releasesOffset)); + } + else + continueDownload = false; + } + return noErrorsOccured; + } + + private async Task StartDownloadTrackTaskAsync() + { + _logger.AddDownloadLogLine("Grabbing Track info...\r\n", true, true); + string downloadBasePath = Settings.Default.savedFolder; + try + { + Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, true)); + + if (qobuzTrack == null) + return ReturnFail(); + + _logger.AddDownloadLogLine($"Track \"{qobuzTrack.Title}\" found. Starting Download...\r\n", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + + if (!DownloadTrack(qobuzTrack, downloadBasePath, true, true)) + return false; + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.LogDownloadTaskException("Track", downloadEx); + return false; + } + } + + private async Task StartDownloadAlbumTaskAsync() + { + _logger.AddDownloadLogLine("Grabbing Album info...", true, true); + string downloadBasePath = Settings.Default.savedFolder; + try + { + Album qobuzAlbum = ExecuteApiCall(apiService => apiService.GetAlbum(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, true, null, 0)); + if (qobuzAlbum == null) + return ReturnFail(); + _logger.AddDownloadLogLine($"Album \"{qobuzAlbum.Title}\" found. Starting Downloads...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + + bool finished = DownloadAlbum(qobuzAlbum, downloadBasePath); + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.LogDownloadTaskException("Album", downloadEx); + return false; + } + } + + private async Task StartDownloadArtistDiscogTaskAsync() + { + string artistBasePath = Settings.Default.savedFolder; + _logger.AddDownloadLogLine("Grabbing Artist info...", true, true); + try + { + Artist qobuzArtist = ExecuteApiCall(apiService => apiService.GetArtist(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, true)); + if (qobuzArtist == null) + return ReturnFail(); + _logger.AddDownloadLogLine($"Starting Downloads for artist \"{qobuzArtist.Name}\" with ID: <{qobuzArtist.Id}>...", true, true); + await DownloadArtistReleases(qobuzArtist, artistBasePath, "all", true); + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Artist", downloadEx); + return false; + } + } + + private async Task StartDownloadLabelTaskAsync() + { + string labelBasePath = Path.Combine(Settings.Default.savedFolder, "- Labels"); + _logger.AddDownloadLogLine("Grabbing Label albums...\r\n", true, true); + try + { + Label qobuzLabel = null; + List labelAlbums = new(); + const int albumLimit = 500; + int albumsOffset = 0; + while (true) + { + qobuzLabel = ExecuteApiCall(apiService => apiService.GetLabel(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, true, "albums", albumLimit, albumsOffset)); + if (qobuzLabel == null) + return ReturnFail(); + if (qobuzLabel.Albums?.Items?.Any() != true) + break; + labelAlbums.AddRange(qobuzLabel.Albums.Items); + if ((qobuzLabel.Albums?.Total ?? 0) == labelAlbums.Count) + break; + albumsOffset += albumLimit; + } + + if (!labelAlbums.Any()) + { + _logger.AddDownloadLogLine($"No albums found for label \"{qobuzLabel.Name}\" with ID: <{qobuzLabel.Id}>, nothing to download.\r\n", true, true); + return ReturnFail(); + } + + _logger.AddDownloadLogLine($"Starting Downloads for label \"{qobuzLabel.Name}\" with ID: <{qobuzLabel.Id}>...\r\n", true, true); + string safeLabelName = StringTools.GetSafeFilename(StringTools.DecodeEncodedNonAsciiCharacters(qobuzLabel.Name)); + labelBasePath = Path.Combine(labelBasePath, safeLabelName); + await DownloadAlbums(labelBasePath, labelAlbums, true); + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Label", downloadEx); + return false; + } + } + + private async Task StartDownloadFaveAlbumsTaskAsync() + { + string favoritesBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); + _logger.AddDownloadLogLine("Grabbing Favorite Albums...\r\n", true, true); + try + { + List favoriteAlbums = new(); + const int albumLimit = 500; + int albumsOffset = 0; + while (true) + { + UserFavorites qobuzUserFavorites = ExecuteApiCall(apiService => apiService.GetUserFavorites(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, "albums", albumLimit, albumsOffset)); + if (qobuzUserFavorites == null) + return ReturnFail(); + if (qobuzUserFavorites.Albums?.Items?.Any() != true) + break; + favoriteAlbums.AddRange(qobuzUserFavorites.Albums.Items); + if ((qobuzUserFavorites.Albums?.Total ?? 0) == favoriteAlbums.Count) + break; + albumsOffset += albumLimit; + } + + if (!favoriteAlbums.Any()) + { + _logger.AddDownloadLogLine("No favorite albums found, nothing to download.", true, true); + return ReturnFail(); + } + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Favorite Albums", downloadEx); + return false; + } + } + + private async Task StartDownloadFaveArtistsTaskAsync() + { + string favoritesBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); + _logger.AddDownloadLogLine("Grabbing Favorite Artists...", true, true); + + try + { + UserFavoritesIds qobuzUserFavoritesIds = ExecuteApiCall(apiService => apiService.GetUserFavoriteIds(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID)); + if (qobuzUserFavoritesIds == null) + return ReturnFail(); + + if (qobuzUserFavoritesIds.Artists?.Any() != true) + { + _logger.AddDownloadLogLine("No favorite artists found, nothing to download.", true, true); + return ReturnFail(); + } + + foreach (int favoriteArtistId in qobuzUserFavoritesIds.Artists) + { + if (State != RequestState.Running) + return false; + Artist qobuzArtist = ExecuteApiCall(apiService => apiService.GetArtist(favoriteArtistId.ToString(), true)); + if (qobuzArtist == null) + { + continue; + } + _logger.AddEmptyDownloadLogLine(true, true); + _logger.AddDownloadLogLine($"Starting Downloads for artist \"{qobuzArtist.Name}\" with ID: <{qobuzArtist.Id}>...", true, true); + await DownloadArtistReleases(qobuzArtist, favoritesBasePath, "all", false); + } + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Favorite Albums", downloadEx); + return false; + } + } + + private async Task StartDownloadFaveTracksTaskAsync() + { + string favoriteTracksBasePath = Path.Combine(Settings.Default.savedFolder, "- Favorites"); + _logger.AddDownloadLogLine("Grabbing Favorite Tracks...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + try + { + UserFavoritesIds qobuzUserFavoritesIds = ExecuteApiCall(apiService => apiService.GetUserFavoriteIds(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID)); + if (qobuzUserFavoritesIds == null) + return ReturnFail(); + + if (qobuzUserFavoritesIds.Tracks?.Any() != true) + { + _logger.AddDownloadLogLine("No favorite tracks found, nothing to download.", true, true); + return ReturnFail(); + } + + _logger.AddDownloadLogLine("Favorite tracks found. Starting Downloads...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + + foreach (int favoriteTrackId in qobuzUserFavoritesIds.Tracks) + { + if (State != RequestState.Running) + return false; + Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(favoriteTrackId.ToString(), true)); + if (qobuzTrack == null) + continue; + DownloadTrack(qobuzTrack, favoriteTracksBasePath, true, true); + } + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Playlist", downloadEx); + return false; + } + } + + private async Task StartDownloadPlaylistTaskAsync() + { + string playlistBasePath = Settings.Default.savedFolder; + _logger.AddDownloadLogLine("Grabbing Playlist tracks...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + try + { + Playlist qobuzPlaylist = ExecuteApiCall(apiService => apiService.GetPlaylist(_downloadInfoDict[_downloadItem.Id.ToString()].DownloadItemID, true, "track_ids", 10000)); + if (qobuzPlaylist == null) + return ReturnFail(); + if (qobuzPlaylist.TrackIds?.Any() != true) + { + _logger.AddDownloadLogLine($"Playlist \"{qobuzPlaylist.Name}\" is empty, nothing to download.", true, true); + return ReturnFail(); + } + + _logger.AddDownloadLogLine($"Playlist \"{qobuzPlaylist.Name}\" found. Starting Downloads...", true, true); + _logger.AddEmptyDownloadLogLine(true, true); + + string playlistSafeName = StringTools.GetSafeFilename(StringTools.DecodeEncodedNonAsciiCharacters(qobuzPlaylist.Name)); + string playlistNamePath = StringTools.TrimToMaxLength(playlistSafeName, Globals.MaxLength); + playlistBasePath = Path.Combine(playlistBasePath, "- Playlists", playlistNamePath); + Directory.CreateDirectory(playlistBasePath); + string coverArtFilePath = Path.Combine(playlistBasePath, "Playlist.jpg"); + + if (!File.Exists(coverArtFilePath)) + { + _requestContainer.Add(new GetRequest(qobuzPlaylist.ImageRectangle.FirstOrDefault(), new() + { + DirectoryPath = playlistBasePath, + Filename = "Playlist.jpg", + SpeedReporter = new SpeedReporter(), + IsDownload = true, + RequestFailed = (req, _) => _logger.AddDownloadErrorLogLines(["Error downloading full size playlist cover image file.", req.Exception.Message, "\r\n"]) + })); + } + M3uPlaylist m3uPlaylist = new(); + m3uPlaylist.IsExtended = true; + foreach (long trackId in qobuzPlaylist.TrackIds) + { + if (State != RequestState.Running) + return false; + Track qobuzTrack = ExecuteApiCall(apiService => apiService.GetTrack(trackId.ToString(), true)); + if (qobuzTrack == null) + continue; + if (!IsStreamable(qobuzTrack, true)) + continue; + DownloadTrack(qobuzTrack, playlistBasePath, true, true); + AddTrackToPlaylistFile(m3uPlaylist, _downloadInfoDict[trackId.ToString()], _downloadPathsDict[trackId.ToString()]); + } + string m3uPlaylistFile = Path.Combine(playlistBasePath, $"{playlistSafeName}.m3u8"); + File.WriteAllText(m3uPlaylistFile, PlaylistToTextHelper.ToText(m3uPlaylist), System.Text.Encoding.UTF8); + return await WaitOnCompletion(); + } + catch (Exception downloadEx) + { + _logger.ClearUiLogComponent(); + _logger.LogDownloadTaskException("Playlist", downloadEx); + return false; + } + } + + public void AddTrackToPlaylistFile(M3uPlaylist m3uPlaylist, DownloadItemInfo downloadInfo, DownloadItemPaths downloadPaths) + { + if (!File.Exists(downloadPaths.FullTrackFilePath)) return; + m3uPlaylist.PlaylistEntries.Add(new M3uPlaylistEntry() + { + Path = downloadPaths.FullTrackFilePath, + Duration = TimeSpan.FromSeconds(downloadInfo.Duration), + Title = $"{downloadInfo.PerformerName} - {downloadInfo.TrackName}" + }); + } + + public void CreateTrackDirectories(string basePath, string qualityPath, string key, string albumPathSuffix = "", bool forTracklist = false) + { + if (forTracklist) + { + _downloadPathsDict[key].Path1Full = basePath; + _downloadPathsDict[key].Path2Full = _downloadPathsDict[key].Path1Full; + _downloadPathsDict[key].Path3Full = Path.Combine(basePath, qualityPath); + _downloadPathsDict[key].Path4Full = _downloadPathsDict[key].Path3Full; + } + else + { + _downloadPathsDict[key].Path1Full = Path.Combine(basePath, _downloadPathsDict[key].AlbumArtistPath); + _downloadPathsDict[key].Path2Full = Path.Combine(basePath, _downloadPathsDict[key].AlbumArtistPath, _downloadPathsDict[key].AlbumNamePath + albumPathSuffix); + _downloadPathsDict[key].Path3Full = Path.Combine(basePath, _downloadPathsDict[key].AlbumArtistPath, _downloadPathsDict[key].AlbumNamePath + albumPathSuffix, qualityPath); + if (_downloadInfoDict[key].DiscTotal > 1) + { + string discFolder = "CD " + _downloadInfoDict[key].DiscNumber.ToString().PadLeft(Math.Max(2, (int)Math.Floor(Math.Log10(_downloadInfoDict[key].DiscTotal) + 1)), '0'); + _downloadPathsDict[key].Path4Full = Path.Combine(basePath, _downloadPathsDict[key].AlbumArtistPath, _downloadPathsDict[key].AlbumNamePath + albumPathSuffix, qualityPath, discFolder); + } + else + { + _downloadPathsDict[key].Path4Full = _downloadPathsDict[key].Path3Full; + } + } + Directory.CreateDirectory(_downloadPathsDict[key].Path4Full); + } + + public override void Pause() + { + base.Pause(); + _requestContainer.Pause(); + } + public override void Start() + { + base.Start(); + _requestContainer.Start(); + } + + public override void Cancel() + { + base.Cancel(); + _requestContainer.Cancel(); + } + + private bool ReturnFail() + { + Options.NumberOfAttempts = 0; + return false; + } + } +} \ No newline at end of file diff --git a/QobuzDownloaderX/Shared/DownloadRequestOptions.cs b/QobuzDownloaderX/Shared/DownloadRequestOptions.cs new file mode 100644 index 0000000..d8cde9e --- /dev/null +++ b/QobuzDownloaderX/Shared/DownloadRequestOptions.cs @@ -0,0 +1,33 @@ +using QobuzDownloaderX.Models; +using Requests.Options; + +namespace QobuzDownloaderX.Shared +{ + public record DownloadRequestOptions : RequestOptions + { + public DownloadLogger Logger { get; init; } + public DownloadItem DownloadItem { get; init; } + public string DownloadPath { get; init; } + public bool CheckIfStreamable { get; init; } + public Notify UpdateAlbumTagsUi { get; set; } + + /// + /// Main Constructor + /// + public DownloadRequestOptions() + { } + + /// + /// Copy Constructor + /// + /// Copied object + protected DownloadRequestOptions(DownloadRequestOptions options) : base(options) + { + Logger = options.Logger; + DownloadItem = options.DownloadItem; + DownloadPath = options.DownloadPath; + CheckIfStreamable = options.CheckIfStreamable; + UpdateAlbumTagsUi = options.UpdateAlbumTagsUi; + } + } +} \ No newline at end of file diff --git a/QobuzDownloaderX/Shared/Tools/AudioFileTagger.cs b/QobuzDownloaderX/Shared/Tools/AudioFileTagger.cs index 82e3569..470ab55 100644 --- a/QobuzDownloaderX/Shared/Tools/AudioFileTagger.cs +++ b/QobuzDownloaderX/Shared/Tools/AudioFileTagger.cs @@ -1,5 +1,6 @@ using QobuzDownloaderX.Models; using System; +using System.IO; using TagLib; namespace QobuzDownloaderX.Shared @@ -27,6 +28,11 @@ public static void AddMetaDataTags(DownloadItemInfo fileInfo, string tagFilePath // Saving cover art to file(s) if (Globals.TaggingOptions.WriteCoverImageTag) { + int maxRetries = 2; // Define the maximum number of retries + int retryDelay = 500; // Define the delay in milliseconds between retries + int attempt = 0; + + retry: try { // Define cover art to use for MP3 file(s) @@ -42,6 +48,17 @@ public static void AddMetaDataTags(DownloadItemInfo fileInfo, string tagFilePath tfile.Tag.Pictures = new TagLib.IPicture[1] { pic }; tfile.Save(); } + catch (IOException) + { + attempt++; + if (attempt >= maxRetries) + { + logger.AddDownloadLogErrorLine($"Cover art tag failed, .jpg still exists?...{Environment.NewLine}", true, true); + break; + } + System.Threading.Thread.Sleep(retryDelay); + goto retry; + } catch { logger.AddDownloadLogErrorLine($"Cover art tag failed, .jpg still exists?...{Environment.NewLine}", true, true); @@ -155,6 +172,11 @@ public static void AddMetaDataTags(DownloadItemInfo fileInfo, string tagFilePath // Saving cover art to file(s) if (Globals.TaggingOptions.WriteCoverImageTag) { + int maxRetries = 2; // Define the maximum number of retries + int retryDelay = 500; // Define the delay in milliseconds between retries + int attempt = 0; + + retry: try { // Define cover art to use for FLAC file(s) @@ -170,6 +192,17 @@ public static void AddMetaDataTags(DownloadItemInfo fileInfo, string tagFilePath tfile.Tag.Pictures = new TagLib.IPicture[1] { pic }; tfile.Save(); } + catch (IOException) + { + attempt++; + if (attempt >= maxRetries) + { + logger.AddDownloadLogErrorLine($"Cover art tag failed, .jpg still exists?...{Environment.NewLine}", true, true); + break; + } + System.Threading.Thread.Sleep(retryDelay); + goto retry; + } catch { logger.AddDownloadLogErrorLine($"Cover art tag failed, .jpg still exists?...{Environment.NewLine}", true, true); @@ -245,7 +278,7 @@ public static void AddMetaDataTags(DownloadItemInfo fileInfo, string tagFilePath if (Globals.TaggingOptions.WriteInvolvedPeopleTag) { custom.SetField("INVOLVEDPEOPLE", fileInfo.InvolvedPeople); } // Release Year tag (The "tfile.Tag.Year" field actually writes to the DATE tag, so use custom tag) - if (Globals.TaggingOptions.WriteReleaseYearTag) { custom.SetField("YEAR", fileInfo.ReleaseDate.Substring(0, 4)); } + if (Globals.TaggingOptions.WriteReleaseYearTag) { custom.SetField("YEAR", fileInfo.ReleaseDate?[..4] ?? "0000"); } // Release Date tag if (Globals.TaggingOptions.WriteReleaseDateTag) { custom.SetField("DATE", fileInfo.ReleaseDate); } diff --git a/QobuzDownloaderX/View/MainForm.Designer.cs b/QobuzDownloaderX/View/MainForm.Designer.cs index 7c2d87b..319f100 100644 --- a/QobuzDownloaderX/View/MainForm.Designer.cs +++ b/QobuzDownloaderX/View/MainForm.Designer.cs @@ -28,1404 +28,1512 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); + components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QobuzDownloaderX)); - this.selectFolderButton = new System.Windows.Forms.Button(); - this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); - this.output = new System.Windows.Forms.TextBox(); - this.openFolderButton = new System.Windows.Forms.Button(); - this.downloadButton = new System.Windows.Forms.Button(); - this.downloadUrl = new System.Windows.Forms.TextBox(); - this.imageURLTextbox = new System.Windows.Forms.TextBox(); - this.verNumLabel = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.albumArtistTextBox = new System.Windows.Forms.TextBox(); - this.albumTextBox = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.releaseDateTextBox = new System.Windows.Forms.TextBox(); - this.label4 = new System.Windows.Forms.Label(); - this.upcTextBox = new System.Windows.Forms.TextBox(); - this.label5 = new System.Windows.Forms.Label(); - this.albumArtPicBox = new System.Windows.Forms.PictureBox(); - this.logoBox = new System.Windows.Forms.PictureBox(); - this.label6 = new System.Windows.Forms.Label(); - this.totalTracksTextbox = new System.Windows.Forms.TextBox(); - this.totalTracksLabel = new System.Windows.Forms.Label(); - this.qualityTextbox = new System.Windows.Forms.TextBox(); - this.qualityLabel = new System.Windows.Forms.Label(); - this.openSearchButton = new System.Windows.Forms.Button(); - this.tagsLabel = new System.Windows.Forms.Label(); - this.albumArtistCheckbox = new System.Windows.Forms.CheckBox(); - this.artistCheckbox = new System.Windows.Forms.CheckBox(); - this.trackTitleCheckbox = new System.Windows.Forms.CheckBox(); - this.trackNumberCheckbox = new System.Windows.Forms.CheckBox(); - this.trackTotalCheckbox = new System.Windows.Forms.CheckBox(); - this.discNumberCheckbox = new System.Windows.Forms.CheckBox(); - this.discTotalCheckbox = new System.Windows.Forms.CheckBox(); - this.albumCheckbox = new System.Windows.Forms.CheckBox(); - this.explicitCheckbox = new System.Windows.Forms.CheckBox(); - this.upcCheckbox = new System.Windows.Forms.CheckBox(); - this.isrcCheckbox = new System.Windows.Forms.CheckBox(); - this.copyrightCheckbox = new System.Windows.Forms.CheckBox(); - this.composerCheckbox = new System.Windows.Forms.CheckBox(); - this.genreCheckbox = new System.Windows.Forms.CheckBox(); - this.releasYearCheckbox = new System.Windows.Forms.CheckBox(); - this.commentCheckbox = new System.Windows.Forms.CheckBox(); - this.commentTextbox = new System.Windows.Forms.TextBox(); - this.imageCheckbox = new System.Windows.Forms.CheckBox(); - this.mp3Checkbox = new System.Windows.Forms.CheckBox(); - this.flacLowCheckbox = new System.Windows.Forms.CheckBox(); - this.flacMidCheckbox = new System.Windows.Forms.CheckBox(); - this.flacHighCheckbox = new System.Windows.Forms.CheckBox(); - this.mp3WarnLabel = new System.Windows.Forms.Label(); - this.panel1 = new System.Windows.Forms.Panel(); - this.exitLabel = new System.Windows.Forms.Label(); - this.minimizeLabel = new System.Windows.Forms.Label(); - this.panel2 = new System.Windows.Forms.Panel(); - this.panel3 = new System.Windows.Forms.Panel(); - this.panel4 = new System.Windows.Forms.Panel(); - this.panel5 = new System.Windows.Forms.Panel(); - this.panel6 = new System.Windows.Forms.Panel(); - this.panel7 = new System.Windows.Forms.Panel(); - this.panel8 = new System.Windows.Forms.Panel(); - this.streamableCheckbox = new System.Windows.Forms.CheckBox(); - this.secretTextbox = new System.Windows.Forms.TextBox(); - this.displaySecretButton = new System.Windows.Forms.Button(); - this.profilePictureBox = new System.Windows.Forms.PictureBox(); - this.logoutLabel = new System.Windows.Forms.Label(); - this.hiddenTextPanel = new System.Windows.Forms.Panel(); - this.artSizeSelect = new System.Windows.Forms.ComboBox(); - this.artSizeLabel = new System.Windows.Forms.Label(); - this.typeCheckbox = new System.Windows.Forms.CheckBox(); - this.aboutLabel = new System.Windows.Forms.Label(); - this.enableBtnsButton = new System.Windows.Forms.Button(); - this.hideDebugButton = new System.Windows.Forms.Button(); - this.maxLengthLabel = new System.Windows.Forms.Label(); - this.panel9 = new System.Windows.Forms.Panel(); - this.maxLengthTextbox = new System.Windows.Forms.TextBox(); - this.maxLengthWarnLabel = new System.Windows.Forms.Label(); - this.customFormatPanel = new System.Windows.Forms.Panel(); - this.customFormatIDTextbox = new System.Windows.Forms.TextBox(); - this.formatIDLabel = new System.Windows.Forms.Label(); - this.filenameTempSelect = new System.Windows.Forms.ComboBox(); - this.label7 = new System.Windows.Forms.Label(); - this.testURLBox = new System.Windows.Forms.TextBox(); - this.openLogFolderButton = new System.Windows.Forms.Button(); - this.downloadSpeedLabel = new System.Windows.Forms.Label(); - this.panel10 = new System.Windows.Forms.Panel(); - this.labelCheckbox = new System.Windows.Forms.CheckBox(); - this.InitialListSeparatorTextbox = new System.Windows.Forms.TextBox(); - this.involvedPeopleCheckBox = new System.Windows.Forms.CheckBox(); - this.producerCheckbox = new System.Windows.Forms.CheckBox(); - this.PrimaryListSeparatorLabel = new System.Windows.Forms.Label(); - this.ListEndSeparatorLabel = new System.Windows.Forms.Label(); - this.panel11 = new System.Windows.Forms.Panel(); - this.ListEndSeparatorTextbox = new System.Windows.Forms.TextBox(); - this.mergePerformersCheckBox = new System.Windows.Forms.CheckBox(); - this.mergeListsToolTip = new System.Windows.Forms.ToolTip(this.components); - this.releaseDateCheckbox = new System.Windows.Forms.CheckBox(); - this.urlCheckBox = new System.Windows.Forms.CheckBox(); - ((System.ComponentModel.ISupportInitialize)(this.albumArtPicBox)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.logoBox)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.profilePictureBox)).BeginInit(); - this.SuspendLayout(); + selectFolderButton = new System.Windows.Forms.Button(); + folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); + output = new System.Windows.Forms.TextBox(); + openFolderButton = new System.Windows.Forms.Button(); + downloadButton = new System.Windows.Forms.Button(); + downloadUrl = new System.Windows.Forms.TextBox(); + imageURLTextbox = new System.Windows.Forms.TextBox(); + verNumLabel = new System.Windows.Forms.Label(); + label1 = new System.Windows.Forms.Label(); + label2 = new System.Windows.Forms.Label(); + albumArtistTextBox = new System.Windows.Forms.TextBox(); + albumTextBox = new System.Windows.Forms.TextBox(); + label3 = new System.Windows.Forms.Label(); + releaseDateTextBox = new System.Windows.Forms.TextBox(); + label4 = new System.Windows.Forms.Label(); + upcTextBox = new System.Windows.Forms.TextBox(); + label5 = new System.Windows.Forms.Label(); + albumArtPicBox = new System.Windows.Forms.PictureBox(); + logoBox = new System.Windows.Forms.PictureBox(); + label6 = new System.Windows.Forms.Label(); + totalTracksTextbox = new System.Windows.Forms.TextBox(); + totalTracksLabel = new System.Windows.Forms.Label(); + qualityTextbox = new System.Windows.Forms.TextBox(); + qualityLabel = new System.Windows.Forms.Label(); + openSearchButton = new System.Windows.Forms.Button(); + tagsLabel = new System.Windows.Forms.Label(); + albumArtistCheckbox = new System.Windows.Forms.CheckBox(); + artistCheckbox = new System.Windows.Forms.CheckBox(); + trackTitleCheckbox = new System.Windows.Forms.CheckBox(); + trackNumberCheckbox = new System.Windows.Forms.CheckBox(); + trackTotalCheckbox = new System.Windows.Forms.CheckBox(); + discNumberCheckbox = new System.Windows.Forms.CheckBox(); + discTotalCheckbox = new System.Windows.Forms.CheckBox(); + albumCheckbox = new System.Windows.Forms.CheckBox(); + explicitCheckbox = new System.Windows.Forms.CheckBox(); + upcCheckbox = new System.Windows.Forms.CheckBox(); + isrcCheckbox = new System.Windows.Forms.CheckBox(); + copyrightCheckbox = new System.Windows.Forms.CheckBox(); + composerCheckbox = new System.Windows.Forms.CheckBox(); + genreCheckbox = new System.Windows.Forms.CheckBox(); + releasYearCheckbox = new System.Windows.Forms.CheckBox(); + commentCheckbox = new System.Windows.Forms.CheckBox(); + commentTextbox = new System.Windows.Forms.TextBox(); + imageCheckbox = new System.Windows.Forms.CheckBox(); + mp3Checkbox = new System.Windows.Forms.CheckBox(); + flacLowCheckbox = new System.Windows.Forms.CheckBox(); + flacMidCheckbox = new System.Windows.Forms.CheckBox(); + flacHighCheckbox = new System.Windows.Forms.CheckBox(); + mp3WarnLabel = new System.Windows.Forms.Label(); + panel1 = new System.Windows.Forms.Panel(); + exitLabel = new System.Windows.Forms.Label(); + minimizeLabel = new System.Windows.Forms.Label(); + panel2 = new System.Windows.Forms.Panel(); + panel3 = new System.Windows.Forms.Panel(); + panel4 = new System.Windows.Forms.Panel(); + panel5 = new System.Windows.Forms.Panel(); + panel6 = new System.Windows.Forms.Panel(); + panel7 = new System.Windows.Forms.Panel(); + panel8 = new System.Windows.Forms.Panel(); + streamableCheckbox = new System.Windows.Forms.CheckBox(); + secretTextbox = new System.Windows.Forms.TextBox(); + displaySecretButton = new System.Windows.Forms.Button(); + profilePictureBox = new System.Windows.Forms.PictureBox(); + logoutLabel = new System.Windows.Forms.Label(); + hiddenTextPanel = new System.Windows.Forms.Panel(); + artSizeSelect = new System.Windows.Forms.ComboBox(); + artSizeLabel = new System.Windows.Forms.Label(); + typeCheckbox = new System.Windows.Forms.CheckBox(); + aboutLabel = new System.Windows.Forms.Label(); + enableBtnsButton = new System.Windows.Forms.Button(); + hideDebugButton = new System.Windows.Forms.Button(); + maxLengthLabel = new System.Windows.Forms.Label(); + panel9 = new System.Windows.Forms.Panel(); + maxLengthTextbox = new System.Windows.Forms.TextBox(); + maxLengthWarnLabel = new System.Windows.Forms.Label(); + customFormatPanel = new System.Windows.Forms.Panel(); + customFormatIDTextbox = new System.Windows.Forms.TextBox(); + formatIDLabel = new System.Windows.Forms.Label(); + filenameTempSelect = new System.Windows.Forms.ComboBox(); + label7 = new System.Windows.Forms.Label(); + testURLBox = new System.Windows.Forms.TextBox(); + openLogFolderButton = new System.Windows.Forms.Button(); + downloadSpeedLabel = new System.Windows.Forms.Label(); + panel10 = new System.Windows.Forms.Panel(); + labelCheckbox = new System.Windows.Forms.CheckBox(); + InitialListSeparatorTextbox = new System.Windows.Forms.TextBox(); + involvedPeopleCheckBox = new System.Windows.Forms.CheckBox(); + producerCheckbox = new System.Windows.Forms.CheckBox(); + PrimaryListSeparatorLabel = new System.Windows.Forms.Label(); + ListEndSeparatorLabel = new System.Windows.Forms.Label(); + panel11 = new System.Windows.Forms.Panel(); + ListEndSeparatorTextbox = new System.Windows.Forms.TextBox(); + mergePerformersCheckBox = new System.Windows.Forms.CheckBox(); + mergeListsToolTip = new System.Windows.Forms.ToolTip(components); + releaseDateCheckbox = new System.Windows.Forms.CheckBox(); + urlCheckBox = new System.Windows.Forms.CheckBox(); + stopButton = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)albumArtPicBox).BeginInit(); + ((System.ComponentModel.ISupportInitialize)logoBox).BeginInit(); + ((System.ComponentModel.ISupportInitialize)profilePictureBox).BeginInit(); + SuspendLayout(); // // selectFolderButton // - this.selectFolderButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.selectFolderButton.FlatAppearance.BorderSize = 0; - this.selectFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.selectFolderButton.ForeColor = System.Drawing.Color.White; - this.selectFolderButton.Location = new System.Drawing.Point(12, 115); - this.selectFolderButton.Name = "selectFolderButton"; - this.selectFolderButton.Size = new System.Drawing.Size(231, 23); - this.selectFolderButton.TabIndex = 3; - this.selectFolderButton.Text = "Choose Download Folder"; - this.selectFolderButton.UseVisualStyleBackColor = false; - this.selectFolderButton.Click += new System.EventHandler(this.SelectFolder_Click); + selectFolderButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + selectFolderButton.FlatAppearance.BorderSize = 0; + selectFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + selectFolderButton.ForeColor = System.Drawing.Color.White; + selectFolderButton.Location = new System.Drawing.Point(26, 283); + selectFolderButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + selectFolderButton.Name = "selectFolderButton"; + selectFolderButton.Size = new System.Drawing.Size(374, 56); + selectFolderButton.TabIndex = 3; + selectFolderButton.Text = "Choose Download Folder"; + selectFolderButton.UseVisualStyleBackColor = false; + selectFolderButton.Click += SelectFolder_Click; // // output // - this.output.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33))))); - this.output.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.output.Cursor = System.Windows.Forms.Cursors.IBeam; - this.output.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.output.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128))))); - this.output.Location = new System.Drawing.Point(12, 144); - this.output.Multiline = true; - this.output.Name = "output"; - this.output.ReadOnly = true; - this.output.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.output.Size = new System.Drawing.Size(705, 339); - this.output.TabIndex = 20; - this.output.Text = "Test String"; + output.BackColor = System.Drawing.Color.FromArgb(33, 33, 33); + output.BorderStyle = System.Windows.Forms.BorderStyle.None; + output.Cursor = System.Windows.Forms.Cursors.IBeam; + output.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0); + output.ForeColor = System.Drawing.Color.FromArgb(255, 128, 128); + output.Location = new System.Drawing.Point(26, 355); + output.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + output.Multiline = true; + output.Name = "output"; + output.ReadOnly = true; + output.RightToLeft = System.Windows.Forms.RightToLeft.No; + output.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + output.Size = new System.Drawing.Size(1528, 835); + output.TabIndex = 20; + output.Text = "Test String"; // // openFolderButton // - this.openFolderButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.openFolderButton.FlatAppearance.BorderSize = 0; - this.openFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.openFolderButton.ForeColor = System.Drawing.Color.White; - this.openFolderButton.Location = new System.Drawing.Point(249, 115); - this.openFolderButton.Name = "openFolderButton"; - this.openFolderButton.Size = new System.Drawing.Size(231, 23); - this.openFolderButton.TabIndex = 4; - this.openFolderButton.Text = "Open Download Folder"; - this.openFolderButton.UseVisualStyleBackColor = false; - this.openFolderButton.Click += new System.EventHandler(this.OpenFolderButton_Click); + openFolderButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + openFolderButton.FlatAppearance.BorderSize = 0; + openFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + openFolderButton.ForeColor = System.Drawing.Color.White; + openFolderButton.Location = new System.Drawing.Point(442, 283); + openFolderButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + openFolderButton.Name = "openFolderButton"; + openFolderButton.Size = new System.Drawing.Size(374, 56); + openFolderButton.TabIndex = 4; + openFolderButton.Text = "Open Download Folder"; + openFolderButton.UseVisualStyleBackColor = false; + openFolderButton.Click += OpenFolderButton_Click; // // downloadButton // - this.downloadButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.downloadButton.FlatAppearance.BorderSize = 0; - this.downloadButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.downloadButton.ForeColor = System.Drawing.Color.White; - this.downloadButton.Location = new System.Drawing.Point(597, 86); - this.downloadButton.Name = "downloadButton"; - this.downloadButton.Size = new System.Drawing.Size(120, 23); - this.downloadButton.TabIndex = 2; - this.downloadButton.Text = "Download"; - this.downloadButton.UseVisualStyleBackColor = false; - this.downloadButton.Click += new System.EventHandler(this.DownloadButton_Click); + downloadButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + downloadButton.FlatAppearance.BorderSize = 0; + downloadButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + downloadButton.ForeColor = System.Drawing.Color.White; + downloadButton.Location = new System.Drawing.Point(1294, 211); + downloadButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + downloadButton.Name = "downloadButton"; + downloadButton.Size = new System.Drawing.Size(260, 56); + downloadButton.TabIndex = 2; + downloadButton.Text = "Download"; + downloadButton.UseVisualStyleBackColor = false; + downloadButton.Click += DownloadButton_Click; // // downloadUrl // - this.downloadUrl.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.downloadUrl.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.downloadUrl.ForeColor = System.Drawing.Color.White; - this.downloadUrl.Location = new System.Drawing.Point(15, 88); - this.downloadUrl.Multiline = true; - this.downloadUrl.Name = "downloadUrl"; - this.downloadUrl.Size = new System.Drawing.Size(576, 20); - this.downloadUrl.TabIndex = 1; - this.downloadUrl.WordWrap = false; - this.downloadUrl.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DownloadUrl_KeyDown); + downloadUrl.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + downloadUrl.BorderStyle = System.Windows.Forms.BorderStyle.None; + downloadUrl.ForeColor = System.Drawing.Color.White; + downloadUrl.Location = new System.Drawing.Point(32, 216); + downloadUrl.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + downloadUrl.Multiline = true; + downloadUrl.Name = "downloadUrl"; + downloadUrl.Size = new System.Drawing.Size(1248, 50); + downloadUrl.TabIndex = 1; + downloadUrl.WordWrap = false; + downloadUrl.KeyDown += DownloadUrl_KeyDown; // // imageURLTextbox // - this.imageURLTextbox.Location = new System.Drawing.Point(946, 420); - this.imageURLTextbox.Multiline = true; - this.imageURLTextbox.Name = "imageURLTextbox"; - this.imageURLTextbox.Size = new System.Drawing.Size(390, 20); - this.imageURLTextbox.TabIndex = 31; - this.imageURLTextbox.Text = "Release Cover Art URL"; - this.imageURLTextbox.Visible = false; - this.imageURLTextbox.WordWrap = false; + imageURLTextbox.Location = new System.Drawing.Point(2049, 1034); + imageURLTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + imageURLTextbox.Multiline = true; + imageURLTextbox.Name = "imageURLTextbox"; + imageURLTextbox.Size = new System.Drawing.Size(841, 44); + imageURLTextbox.TabIndex = 31; + imageURLTextbox.Text = "Release Cover Art URL"; + imageURLTextbox.Visible = false; + imageURLTextbox.WordWrap = false; // // verNumLabel // - this.verNumLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.verNumLabel.Location = new System.Drawing.Point(159, 55); - this.verNumLabel.Name = "verNumLabel"; - this.verNumLabel.Size = new System.Drawing.Size(63, 13); - this.verNumLabel.TabIndex = 38; - this.verNumLabel.Text = "#.#.#.#"; - this.verNumLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + verNumLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + verNumLabel.Location = new System.Drawing.Point(344, 136); + verNumLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + verNumLabel.Name = "verNumLabel"; + verNumLabel.Size = new System.Drawing.Size(136, 32); + verNumLabel.TabIndex = 38; + verNumLabel.Text = "#.#.#.#"; + verNumLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // label1 // - this.label1.AutoSize = true; - this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label1.Location = new System.Drawing.Point(801, 213); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(51, 13); - this.label1.TabIndex = 40; - this.label1.Text = "Cover Art"; + label1.AutoSize = true; + label1.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label1.Location = new System.Drawing.Point(1736, 525); + label1.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(114, 32); + label1.TabIndex = 40; + label1.Text = "Cover Art"; // // label2 // - this.label2.AutoSize = true; - this.label2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label2.Location = new System.Drawing.Point(751, 236); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(62, 13); - this.label2.TabIndex = 41; - this.label2.Text = "Album Artist"; + label2.AutoSize = true; + label2.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label2.Location = new System.Drawing.Point(1627, 581); + label2.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(146, 32); + label2.TabIndex = 41; + label2.Text = "Album Artist"; // // albumArtistTextBox // - this.albumArtistTextBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.albumArtistTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.albumArtistTextBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.albumArtistTextBox.Location = new System.Drawing.Point(754, 252); - this.albumArtistTextBox.Multiline = true; - this.albumArtistTextBox.Name = "albumArtistTextBox"; - this.albumArtistTextBox.ReadOnly = true; - this.albumArtistTextBox.Size = new System.Drawing.Size(150, 20); - this.albumArtistTextBox.TabIndex = 42; - this.albumArtistTextBox.TabStop = false; - this.albumArtistTextBox.WordWrap = false; + albumArtistTextBox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + albumArtistTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; + albumArtistTextBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + albumArtistTextBox.Location = new System.Drawing.Point(1633, 621); + albumArtistTextBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + albumArtistTextBox.Multiline = true; + albumArtistTextBox.Name = "albumArtistTextBox"; + albumArtistTextBox.ReadOnly = true; + albumArtistTextBox.Size = new System.Drawing.Size(325, 50); + albumArtistTextBox.TabIndex = 42; + albumArtistTextBox.TabStop = false; + albumArtistTextBox.WordWrap = false; // // albumTextBox // - this.albumTextBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.albumTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.albumTextBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.albumTextBox.Location = new System.Drawing.Point(754, 294); - this.albumTextBox.Multiline = true; - this.albumTextBox.Name = "albumTextBox"; - this.albumTextBox.ReadOnly = true; - this.albumTextBox.Size = new System.Drawing.Size(150, 20); - this.albumTextBox.TabIndex = 44; - this.albumTextBox.TabStop = false; - this.albumTextBox.WordWrap = false; + albumTextBox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + albumTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; + albumTextBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + albumTextBox.Location = new System.Drawing.Point(1633, 723); + albumTextBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + albumTextBox.Multiline = true; + albumTextBox.Name = "albumTextBox"; + albumTextBox.ReadOnly = true; + albumTextBox.Size = new System.Drawing.Size(325, 50); + albumTextBox.TabIndex = 44; + albumTextBox.TabStop = false; + albumTextBox.WordWrap = false; // // label3 // - this.label3.AutoSize = true; - this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label3.Location = new System.Drawing.Point(751, 278); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(36, 13); - this.label3.TabIndex = 43; - this.label3.Text = "Album"; + label3.AutoSize = true; + label3.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label3.Location = new System.Drawing.Point(1627, 685); + label3.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(84, 32); + label3.TabIndex = 43; + label3.Text = "Album"; // // releaseDateTextBox // - this.releaseDateTextBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.releaseDateTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.releaseDateTextBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.releaseDateTextBox.Location = new System.Drawing.Point(754, 463); - this.releaseDateTextBox.Multiline = true; - this.releaseDateTextBox.Name = "releaseDateTextBox"; - this.releaseDateTextBox.ReadOnly = true; - this.releaseDateTextBox.Size = new System.Drawing.Size(150, 20); - this.releaseDateTextBox.TabIndex = 46; - this.releaseDateTextBox.TabStop = false; - this.releaseDateTextBox.WordWrap = false; + releaseDateTextBox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + releaseDateTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; + releaseDateTextBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + releaseDateTextBox.Location = new System.Drawing.Point(1633, 1139); + releaseDateTextBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + releaseDateTextBox.Multiline = true; + releaseDateTextBox.Name = "releaseDateTextBox"; + releaseDateTextBox.ReadOnly = true; + releaseDateTextBox.Size = new System.Drawing.Size(325, 50); + releaseDateTextBox.TabIndex = 46; + releaseDateTextBox.TabStop = false; + releaseDateTextBox.WordWrap = false; // // label4 // - this.label4.AutoSize = true; - this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label4.Location = new System.Drawing.Point(751, 447); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(72, 13); - this.label4.TabIndex = 45; - this.label4.Text = "Release Date"; + label4.AutoSize = true; + label4.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label4.Location = new System.Drawing.Point(1627, 1101); + label4.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(151, 32); + label4.TabIndex = 45; + label4.Text = "Release Date"; // // upcTextBox // - this.upcTextBox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.upcTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.upcTextBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.upcTextBox.Location = new System.Drawing.Point(754, 420); - this.upcTextBox.Multiline = true; - this.upcTextBox.Name = "upcTextBox"; - this.upcTextBox.ReadOnly = true; - this.upcTextBox.Size = new System.Drawing.Size(150, 20); - this.upcTextBox.TabIndex = 48; - this.upcTextBox.TabStop = false; - this.upcTextBox.WordWrap = false; + upcTextBox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + upcTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; + upcTextBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + upcTextBox.Location = new System.Drawing.Point(1633, 1034); + upcTextBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + upcTextBox.Multiline = true; + upcTextBox.Name = "upcTextBox"; + upcTextBox.ReadOnly = true; + upcTextBox.Size = new System.Drawing.Size(325, 50); + upcTextBox.TabIndex = 48; + upcTextBox.TabStop = false; + upcTextBox.WordWrap = false; // // label5 // - this.label5.AutoSize = true; - this.label5.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label5.Location = new System.Drawing.Point(751, 404); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(29, 13); - this.label5.TabIndex = 47; - this.label5.Text = "UPC"; + label5.AutoSize = true; + label5.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label5.Location = new System.Drawing.Point(1627, 995); + label5.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label5.Name = "label5"; + label5.Size = new System.Drawing.Size(58, 32); + label5.TabIndex = 47; + label5.Text = "UPC"; // // albumArtPicBox // - this.albumArtPicBox.Location = new System.Drawing.Point(754, 57); - this.albumArtPicBox.MaximumSize = new System.Drawing.Size(150, 150); - this.albumArtPicBox.MinimumSize = new System.Drawing.Size(150, 150); - this.albumArtPicBox.Name = "albumArtPicBox"; - this.albumArtPicBox.Size = new System.Drawing.Size(150, 150); - this.albumArtPicBox.TabIndex = 39; - this.albumArtPicBox.TabStop = false; + albumArtPicBox.ErrorImage = null; + albumArtPicBox.InitialImage = null; + albumArtPicBox.Location = new System.Drawing.Point(1633, 141); + albumArtPicBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + albumArtPicBox.MaximumSize = new System.Drawing.Size(325, 370); + albumArtPicBox.MinimumSize = new System.Drawing.Size(325, 370); + albumArtPicBox.Name = "albumArtPicBox"; + albumArtPicBox.Size = new System.Drawing.Size(325, 370); + albumArtPicBox.TabIndex = 39; + albumArtPicBox.TabStop = false; // // logoBox // - this.logoBox.Image = global::QobuzDownloaderX.Properties.Resources.qbdlx_white; - this.logoBox.Location = new System.Drawing.Point(12, 12); - this.logoBox.Name = "logoBox"; - this.logoBox.Size = new System.Drawing.Size(207, 52); - this.logoBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.logoBox.TabIndex = 36; - this.logoBox.TabStop = false; - this.logoBox.Click += new System.EventHandler(this.logoBox_Click); - this.logoBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove); + logoBox.ErrorImage = null; + logoBox.Image = Properties.Resources.qbdlx_white; + logoBox.InitialImage = null; + logoBox.Location = new System.Drawing.Point(26, 29); + logoBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + logoBox.Name = "logoBox"; + logoBox.Size = new System.Drawing.Size(448, 128); + logoBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + logoBox.TabIndex = 36; + logoBox.TabStop = false; + logoBox.Click += logoBox_Click; + logoBox.MouseMove += pictureBox1_MouseMove; // // label6 // - this.label6.AutoSize = true; - this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label6.Location = new System.Drawing.Point(12, 70); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(61, 13); - this.label6.TabIndex = 49; - this.label6.Text = "Qobuz Link"; + label6.AutoSize = true; + label6.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label6.Location = new System.Drawing.Point(26, 173); + label6.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label6.Name = "label6"; + label6.Size = new System.Drawing.Size(135, 32); + label6.TabIndex = 49; + label6.Text = "Qobuz Link"; // // totalTracksTextbox // - this.totalTracksTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.totalTracksTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.totalTracksTextbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.totalTracksTextbox.Location = new System.Drawing.Point(754, 378); - this.totalTracksTextbox.Multiline = true; - this.totalTracksTextbox.Name = "totalTracksTextbox"; - this.totalTracksTextbox.ReadOnly = true; - this.totalTracksTextbox.Size = new System.Drawing.Size(150, 20); - this.totalTracksTextbox.TabIndex = 56; - this.totalTracksTextbox.TabStop = false; - this.totalTracksTextbox.WordWrap = false; + totalTracksTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + totalTracksTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + totalTracksTextbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + totalTracksTextbox.Location = new System.Drawing.Point(1633, 931); + totalTracksTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + totalTracksTextbox.Multiline = true; + totalTracksTextbox.Name = "totalTracksTextbox"; + totalTracksTextbox.ReadOnly = true; + totalTracksTextbox.Size = new System.Drawing.Size(325, 50); + totalTracksTextbox.TabIndex = 56; + totalTracksTextbox.TabStop = false; + totalTracksTextbox.WordWrap = false; // // totalTracksLabel // - this.totalTracksLabel.AutoSize = true; - this.totalTracksLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.totalTracksLabel.Location = new System.Drawing.Point(751, 362); - this.totalTracksLabel.Name = "totalTracksLabel"; - this.totalTracksLabel.Size = new System.Drawing.Size(67, 13); - this.totalTracksLabel.TabIndex = 55; - this.totalTracksLabel.Text = "Total Tracks"; + totalTracksLabel.AutoSize = true; + totalTracksLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + totalTracksLabel.Location = new System.Drawing.Point(1627, 891); + totalTracksLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + totalTracksLabel.Name = "totalTracksLabel"; + totalTracksLabel.Size = new System.Drawing.Size(136, 32); + totalTracksLabel.TabIndex = 55; + totalTracksLabel.Text = "Total Tracks"; // // qualityTextbox // - this.qualityTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.qualityTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.qualityTextbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.qualityTextbox.Location = new System.Drawing.Point(754, 336); - this.qualityTextbox.Multiline = true; - this.qualityTextbox.Name = "qualityTextbox"; - this.qualityTextbox.ReadOnly = true; - this.qualityTextbox.Size = new System.Drawing.Size(150, 20); - this.qualityTextbox.TabIndex = 59; - this.qualityTextbox.TabStop = false; - this.qualityTextbox.WordWrap = false; + qualityTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + qualityTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + qualityTextbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + qualityTextbox.Location = new System.Drawing.Point(1633, 827); + qualityTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + qualityTextbox.Multiline = true; + qualityTextbox.Name = "qualityTextbox"; + qualityTextbox.ReadOnly = true; + qualityTextbox.Size = new System.Drawing.Size(325, 50); + qualityTextbox.TabIndex = 59; + qualityTextbox.TabStop = false; + qualityTextbox.WordWrap = false; // // qualityLabel // - this.qualityLabel.AutoSize = true; - this.qualityLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.qualityLabel.Location = new System.Drawing.Point(751, 320); - this.qualityLabel.Name = "qualityLabel"; - this.qualityLabel.Size = new System.Drawing.Size(71, 13); - this.qualityLabel.TabIndex = 58; - this.qualityLabel.Text = "Album Quality"; + qualityLabel.AutoSize = true; + qualityLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + qualityLabel.Location = new System.Drawing.Point(1627, 787); + qualityLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + qualityLabel.Name = "qualityLabel"; + qualityLabel.Size = new System.Drawing.Size(167, 32); + qualityLabel.TabIndex = 58; + qualityLabel.Text = "Album Quality"; // // openSearchButton // - this.openSearchButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.openSearchButton.FlatAppearance.BorderSize = 0; - this.openSearchButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.openSearchButton.ForeColor = System.Drawing.Color.White; - this.openSearchButton.Location = new System.Drawing.Point(597, 57); - this.openSearchButton.Name = "openSearchButton"; - this.openSearchButton.Size = new System.Drawing.Size(120, 23); - this.openSearchButton.TabIndex = 6; - this.openSearchButton.Text = "Open Search"; - this.openSearchButton.UseVisualStyleBackColor = false; - this.openSearchButton.Click += new System.EventHandler(this.OpenSearch_Click); + openSearchButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + openSearchButton.FlatAppearance.BorderSize = 0; + openSearchButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + openSearchButton.ForeColor = System.Drawing.Color.White; + openSearchButton.Location = new System.Drawing.Point(1294, 141); + openSearchButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + openSearchButton.Name = "openSearchButton"; + openSearchButton.Size = new System.Drawing.Size(260, 56); + openSearchButton.TabIndex = 6; + openSearchButton.Text = "Open Search"; + openSearchButton.UseVisualStyleBackColor = false; + openSearchButton.Click += OpenSearch_Click; // // tagsLabel // - this.tagsLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.tagsLabel.Location = new System.Drawing.Point(12, 501); - this.tagsLabel.Name = "tagsLabel"; - this.tagsLabel.Size = new System.Drawing.Size(914, 23); - this.tagsLabel.TabIndex = 12; - this.tagsLabel.Text = "🠋 Choose which tags to save (click me) 🠋"; - this.tagsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.tagsLabel.Click += new System.EventHandler(this.tagsLabel_Click); + tagsLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + tagsLabel.Location = new System.Drawing.Point(26, 1234); + tagsLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + tagsLabel.Name = "tagsLabel"; + tagsLabel.Size = new System.Drawing.Size(1981, 56); + tagsLabel.TabIndex = 12; + tagsLabel.Text = "🠋 Choose which tags to save (click me) 🠋"; + tagsLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + tagsLabel.Click += tagsLabel_Click; // // albumArtistCheckbox // - this.albumArtistCheckbox.AutoSize = true; - this.albumArtistCheckbox.Checked = true; - this.albumArtistCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.albumArtistCheckbox.FlatAppearance.BorderSize = 0; - this.albumArtistCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.albumArtistCheckbox.Location = new System.Drawing.Point(12, 540); - this.albumArtistCheckbox.Name = "albumArtistCheckbox"; - this.albumArtistCheckbox.Size = new System.Drawing.Size(81, 17); - this.albumArtistCheckbox.TabIndex = 13; - this.albumArtistCheckbox.Text = "Album Artist"; - this.albumArtistCheckbox.UseVisualStyleBackColor = true; - this.albumArtistCheckbox.CheckedChanged += new System.EventHandler(this.AlbumArtistCheckbox_CheckedChanged); + albumArtistCheckbox.AutoSize = true; + albumArtistCheckbox.Checked = true; + albumArtistCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + albumArtistCheckbox.FlatAppearance.BorderSize = 0; + albumArtistCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + albumArtistCheckbox.Location = new System.Drawing.Point(26, 1330); + albumArtistCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + albumArtistCheckbox.Name = "albumArtistCheckbox"; + albumArtistCheckbox.Size = new System.Drawing.Size(178, 36); + albumArtistCheckbox.TabIndex = 13; + albumArtistCheckbox.Text = "Album Artist"; + albumArtistCheckbox.UseVisualStyleBackColor = true; + albumArtistCheckbox.CheckedChanged += AlbumArtistCheckbox_CheckedChanged; // // artistCheckbox // - this.artistCheckbox.AutoSize = true; - this.artistCheckbox.Checked = true; - this.artistCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.artistCheckbox.FlatAppearance.BorderSize = 0; - this.artistCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.artistCheckbox.Location = new System.Drawing.Point(181, 540); - this.artistCheckbox.Name = "artistCheckbox"; - this.artistCheckbox.Size = new System.Drawing.Size(80, 17); - this.artistCheckbox.TabIndex = 15; - this.artistCheckbox.Text = "Track Artist"; - this.artistCheckbox.UseVisualStyleBackColor = true; - this.artistCheckbox.CheckedChanged += new System.EventHandler(this.ArtistCheckbox_CheckedChanged); + artistCheckbox.AutoSize = true; + artistCheckbox.Checked = true; + artistCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + artistCheckbox.FlatAppearance.BorderSize = 0; + artistCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + artistCheckbox.Location = new System.Drawing.Point(392, 1330); + artistCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + artistCheckbox.Name = "artistCheckbox"; + artistCheckbox.Size = new System.Drawing.Size(162, 36); + artistCheckbox.TabIndex = 15; + artistCheckbox.Text = "Track Artist"; + artistCheckbox.UseVisualStyleBackColor = true; + artistCheckbox.CheckedChanged += ArtistCheckbox_CheckedChanged; // // trackTitleCheckbox // - this.trackTitleCheckbox.AutoSize = true; - this.trackTitleCheckbox.Checked = true; - this.trackTitleCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.trackTitleCheckbox.FlatAppearance.BorderSize = 0; - this.trackTitleCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.trackTitleCheckbox.Location = new System.Drawing.Point(266, 540); - this.trackTitleCheckbox.Name = "trackTitleCheckbox"; - this.trackTitleCheckbox.Size = new System.Drawing.Size(77, 17); - this.trackTitleCheckbox.TabIndex = 16; - this.trackTitleCheckbox.Text = "Track Title"; - this.trackTitleCheckbox.UseVisualStyleBackColor = true; - this.trackTitleCheckbox.CheckedChanged += new System.EventHandler(this.TrackTitleCheckbox_CheckedChanged); + trackTitleCheckbox.AutoSize = true; + trackTitleCheckbox.Checked = true; + trackTitleCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + trackTitleCheckbox.FlatAppearance.BorderSize = 0; + trackTitleCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + trackTitleCheckbox.Location = new System.Drawing.Point(577, 1330); + trackTitleCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + trackTitleCheckbox.Name = "trackTitleCheckbox"; + trackTitleCheckbox.Size = new System.Drawing.Size(153, 36); + trackTitleCheckbox.TabIndex = 16; + trackTitleCheckbox.Text = "Track Title"; + trackTitleCheckbox.UseVisualStyleBackColor = true; + trackTitleCheckbox.CheckedChanged += TrackTitleCheckbox_CheckedChanged; // // trackNumberCheckbox // - this.trackNumberCheckbox.AutoSize = true; - this.trackNumberCheckbox.Checked = true; - this.trackNumberCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.trackNumberCheckbox.FlatAppearance.BorderSize = 0; - this.trackNumberCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.trackNumberCheckbox.Location = new System.Drawing.Point(104, 595); - this.trackNumberCheckbox.Name = "trackNumberCheckbox"; - this.trackNumberCheckbox.Size = new System.Drawing.Size(94, 17); - this.trackNumberCheckbox.TabIndex = 29; - this.trackNumberCheckbox.Text = "Track Number"; - this.trackNumberCheckbox.UseVisualStyleBackColor = true; - this.trackNumberCheckbox.CheckedChanged += new System.EventHandler(this.TrackNumberCheckbox_CheckedChanged); + trackNumberCheckbox.AutoSize = true; + trackNumberCheckbox.Checked = true; + trackNumberCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + trackNumberCheckbox.FlatAppearance.BorderSize = 0; + trackNumberCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + trackNumberCheckbox.Location = new System.Drawing.Point(226, 1464); + trackNumberCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + trackNumberCheckbox.Name = "trackNumberCheckbox"; + trackNumberCheckbox.Size = new System.Drawing.Size(195, 36); + trackNumberCheckbox.TabIndex = 29; + trackNumberCheckbox.Text = "Track Number"; + trackNumberCheckbox.UseVisualStyleBackColor = true; + trackNumberCheckbox.CheckedChanged += TrackNumberCheckbox_CheckedChanged; // // trackTotalCheckbox // - this.trackTotalCheckbox.AutoSize = true; - this.trackTotalCheckbox.Checked = true; - this.trackTotalCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.trackTotalCheckbox.FlatAppearance.BorderSize = 0; - this.trackTotalCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.trackTotalCheckbox.Location = new System.Drawing.Point(12, 595); - this.trackTotalCheckbox.Name = "trackTotalCheckbox"; - this.trackTotalCheckbox.Size = new System.Drawing.Size(86, 17); - this.trackTotalCheckbox.TabIndex = 28; - this.trackTotalCheckbox.Text = "Total Tracks"; - this.trackTotalCheckbox.UseVisualStyleBackColor = true; - this.trackTotalCheckbox.CheckedChanged += new System.EventHandler(this.TrackTotalCheckbox_CheckedChanged); + trackTotalCheckbox.AutoSize = true; + trackTotalCheckbox.Checked = true; + trackTotalCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + trackTotalCheckbox.FlatAppearance.BorderSize = 0; + trackTotalCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + trackTotalCheckbox.Location = new System.Drawing.Point(26, 1464); + trackTotalCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + trackTotalCheckbox.Name = "trackTotalCheckbox"; + trackTotalCheckbox.Size = new System.Drawing.Size(168, 36); + trackTotalCheckbox.TabIndex = 28; + trackTotalCheckbox.Text = "Total Tracks"; + trackTotalCheckbox.UseVisualStyleBackColor = true; + trackTotalCheckbox.CheckedChanged += TrackTotalCheckbox_CheckedChanged; // // discNumberCheckbox // - this.discNumberCheckbox.AutoSize = true; - this.discNumberCheckbox.Checked = true; - this.discNumberCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.discNumberCheckbox.FlatAppearance.BorderSize = 0; - this.discNumberCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.discNumberCheckbox.Location = new System.Drawing.Point(289, 595); - this.discNumberCheckbox.Name = "discNumberCheckbox"; - this.discNumberCheckbox.Size = new System.Drawing.Size(87, 17); - this.discNumberCheckbox.TabIndex = 31; - this.discNumberCheckbox.Text = "Disc Number"; - this.discNumberCheckbox.UseVisualStyleBackColor = true; - this.discNumberCheckbox.CheckedChanged += new System.EventHandler(this.DiscNumberCheckbox_CheckedChanged); + discNumberCheckbox.AutoSize = true; + discNumberCheckbox.Checked = true; + discNumberCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + discNumberCheckbox.FlatAppearance.BorderSize = 0; + discNumberCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + discNumberCheckbox.Location = new System.Drawing.Point(626, 1464); + discNumberCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + discNumberCheckbox.Name = "discNumberCheckbox"; + discNumberCheckbox.Size = new System.Drawing.Size(185, 36); + discNumberCheckbox.TabIndex = 31; + discNumberCheckbox.Text = "Disc Number"; + discNumberCheckbox.UseVisualStyleBackColor = true; + discNumberCheckbox.CheckedChanged += DiscNumberCheckbox_CheckedChanged; // // discTotalCheckbox // - this.discTotalCheckbox.AutoSize = true; - this.discTotalCheckbox.Checked = true; - this.discTotalCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.discTotalCheckbox.FlatAppearance.BorderSize = 0; - this.discTotalCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.discTotalCheckbox.Location = new System.Drawing.Point(204, 595); - this.discTotalCheckbox.Name = "discTotalCheckbox"; - this.discTotalCheckbox.Size = new System.Drawing.Size(79, 17); - this.discTotalCheckbox.TabIndex = 30; - this.discTotalCheckbox.Text = "Total Discs"; - this.discTotalCheckbox.UseVisualStyleBackColor = true; - this.discTotalCheckbox.CheckedChanged += new System.EventHandler(this.DiscTotalCheckbox_CheckedChanged); + discTotalCheckbox.AutoSize = true; + discTotalCheckbox.Checked = true; + discTotalCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + discTotalCheckbox.FlatAppearance.BorderSize = 0; + discTotalCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + discTotalCheckbox.Location = new System.Drawing.Point(442, 1464); + discTotalCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + discTotalCheckbox.Name = "discTotalCheckbox"; + discTotalCheckbox.Size = new System.Drawing.Size(158, 36); + discTotalCheckbox.TabIndex = 30; + discTotalCheckbox.Text = "Total Discs"; + discTotalCheckbox.UseVisualStyleBackColor = true; + discTotalCheckbox.CheckedChanged += DiscTotalCheckbox_CheckedChanged; // // albumCheckbox // - this.albumCheckbox.AutoSize = true; - this.albumCheckbox.Checked = true; - this.albumCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.albumCheckbox.FlatAppearance.BorderSize = 0; - this.albumCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.albumCheckbox.Location = new System.Drawing.Point(98, 540); - this.albumCheckbox.Name = "albumCheckbox"; - this.albumCheckbox.Size = new System.Drawing.Size(78, 17); - this.albumCheckbox.TabIndex = 14; - this.albumCheckbox.Text = "Album Title"; - this.albumCheckbox.UseVisualStyleBackColor = true; - this.albumCheckbox.CheckedChanged += new System.EventHandler(this.AlbumCheckbox_CheckedChanged); + albumCheckbox.AutoSize = true; + albumCheckbox.Checked = true; + albumCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + albumCheckbox.FlatAppearance.BorderSize = 0; + albumCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + albumCheckbox.Location = new System.Drawing.Point(213, 1330); + albumCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + albumCheckbox.Name = "albumCheckbox"; + albumCheckbox.Size = new System.Drawing.Size(169, 36); + albumCheckbox.TabIndex = 14; + albumCheckbox.Text = "Album Title"; + albumCheckbox.UseVisualStyleBackColor = true; + albumCheckbox.CheckedChanged += AlbumCheckbox_CheckedChanged; // // explicitCheckbox // - this.explicitCheckbox.AutoSize = true; - this.explicitCheckbox.Checked = true; - this.explicitCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.explicitCheckbox.FlatAppearance.BorderSize = 0; - this.explicitCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.explicitCheckbox.Location = new System.Drawing.Point(458, 595); - this.explicitCheckbox.Name = "explicitCheckbox"; - this.explicitCheckbox.Size = new System.Drawing.Size(106, 17); - this.explicitCheckbox.TabIndex = 33; - this.explicitCheckbox.Text = "Explicit Advisory*"; - this.explicitCheckbox.UseVisualStyleBackColor = true; - this.explicitCheckbox.CheckedChanged += new System.EventHandler(this.ExplicitCheckbox_CheckedChanged); + explicitCheckbox.AutoSize = true; + explicitCheckbox.Checked = true; + explicitCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + explicitCheckbox.FlatAppearance.BorderSize = 0; + explicitCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + explicitCheckbox.Location = new System.Drawing.Point(993, 1464); + explicitCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + explicitCheckbox.Name = "explicitCheckbox"; + explicitCheckbox.Size = new System.Drawing.Size(228, 36); + explicitCheckbox.TabIndex = 33; + explicitCheckbox.Text = "Explicit Advisory*"; + explicitCheckbox.UseVisualStyleBackColor = true; + explicitCheckbox.CheckedChanged += ExplicitCheckbox_CheckedChanged; // // upcCheckbox // - this.upcCheckbox.AutoSize = true; - this.upcCheckbox.Checked = true; - this.upcCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.upcCheckbox.FlatAppearance.BorderSize = 0; - this.upcCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.upcCheckbox.Location = new System.Drawing.Point(771, 540); - this.upcCheckbox.Name = "upcCheckbox"; - this.upcCheckbox.Size = new System.Drawing.Size(52, 17); - this.upcCheckbox.TabIndex = 22; - this.upcCheckbox.Text = "UPC*"; - this.upcCheckbox.UseVisualStyleBackColor = true; - this.upcCheckbox.CheckedChanged += new System.EventHandler(this.UpcCheckbox_CheckedChanged); + upcCheckbox.AutoSize = true; + upcCheckbox.Checked = true; + upcCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + upcCheckbox.FlatAppearance.BorderSize = 0; + upcCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + upcCheckbox.Location = new System.Drawing.Point(1670, 1330); + upcCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + upcCheckbox.Name = "upcCheckbox"; + upcCheckbox.Size = new System.Drawing.Size(100, 36); + upcCheckbox.TabIndex = 22; + upcCheckbox.Text = "UPC*"; + upcCheckbox.UseVisualStyleBackColor = true; + upcCheckbox.CheckedChanged += UpcCheckbox_CheckedChanged; // // isrcCheckbox // - this.isrcCheckbox.AutoSize = true; - this.isrcCheckbox.Checked = true; - this.isrcCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.isrcCheckbox.FlatAppearance.BorderSize = 0; - this.isrcCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.isrcCheckbox.Location = new System.Drawing.Point(828, 540); - this.isrcCheckbox.Name = "isrcCheckbox"; - this.isrcCheckbox.Size = new System.Drawing.Size(51, 17); - this.isrcCheckbox.TabIndex = 23; - this.isrcCheckbox.Text = "ISRC"; - this.isrcCheckbox.UseVisualStyleBackColor = true; - this.isrcCheckbox.CheckedChanged += new System.EventHandler(this.IsrcCheckbox_CheckedChanged); + isrcCheckbox.AutoSize = true; + isrcCheckbox.Checked = true; + isrcCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + isrcCheckbox.FlatAppearance.BorderSize = 0; + isrcCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + isrcCheckbox.Location = new System.Drawing.Point(1794, 1330); + isrcCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + isrcCheckbox.Name = "isrcCheckbox"; + isrcCheckbox.Size = new System.Drawing.Size(94, 36); + isrcCheckbox.TabIndex = 23; + isrcCheckbox.Text = "ISRC"; + isrcCheckbox.UseVisualStyleBackColor = true; + isrcCheckbox.CheckedChanged += IsrcCheckbox_CheckedChanged; // // copyrightCheckbox // - this.copyrightCheckbox.AutoSize = true; - this.copyrightCheckbox.Checked = true; - this.copyrightCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.copyrightCheckbox.FlatAppearance.BorderSize = 0; - this.copyrightCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.copyrightCheckbox.Location = new System.Drawing.Point(696, 540); - this.copyrightCheckbox.Name = "copyrightCheckbox"; - this.copyrightCheckbox.Size = new System.Drawing.Size(70, 17); - this.copyrightCheckbox.TabIndex = 21; - this.copyrightCheckbox.Text = "Copyright"; - this.copyrightCheckbox.UseVisualStyleBackColor = true; - this.copyrightCheckbox.CheckedChanged += new System.EventHandler(this.CopyrightCheckbox_CheckedChanged); + copyrightCheckbox.AutoSize = true; + copyrightCheckbox.Checked = true; + copyrightCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + copyrightCheckbox.FlatAppearance.BorderSize = 0; + copyrightCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + copyrightCheckbox.Location = new System.Drawing.Point(1508, 1330); + copyrightCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + copyrightCheckbox.Name = "copyrightCheckbox"; + copyrightCheckbox.Size = new System.Drawing.Size(151, 36); + copyrightCheckbox.TabIndex = 21; + copyrightCheckbox.Text = "Copyright"; + copyrightCheckbox.UseVisualStyleBackColor = true; + copyrightCheckbox.CheckedChanged += CopyrightCheckbox_CheckedChanged; // // composerCheckbox // - this.composerCheckbox.AutoSize = true; - this.composerCheckbox.Checked = true; - this.composerCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.composerCheckbox.FlatAppearance.BorderSize = 0; - this.composerCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.composerCheckbox.Location = new System.Drawing.Point(12, 567); - this.composerCheckbox.Name = "composerCheckbox"; - this.composerCheckbox.Size = new System.Drawing.Size(73, 17); - this.composerCheckbox.TabIndex = 20; - this.composerCheckbox.Text = "Composer"; - this.composerCheckbox.UseVisualStyleBackColor = true; - this.composerCheckbox.CheckedChanged += new System.EventHandler(this.ComposerCheckbox_CheckedChanged); + composerCheckbox.AutoSize = true; + composerCheckbox.Checked = true; + composerCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + composerCheckbox.FlatAppearance.BorderSize = 0; + composerCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + composerCheckbox.Location = new System.Drawing.Point(26, 1395); + composerCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + composerCheckbox.Name = "composerCheckbox"; + composerCheckbox.Size = new System.Drawing.Size(155, 36); + composerCheckbox.TabIndex = 20; + composerCheckbox.Text = "Composer"; + composerCheckbox.UseVisualStyleBackColor = true; + composerCheckbox.CheckedChanged += ComposerCheckbox_CheckedChanged; // // genreCheckbox // - this.genreCheckbox.AutoSize = true; - this.genreCheckbox.Checked = true; - this.genreCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.genreCheckbox.FlatAppearance.BorderSize = 0; - this.genreCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.genreCheckbox.Location = new System.Drawing.Point(636, 540); - this.genreCheckbox.Name = "genreCheckbox"; - this.genreCheckbox.Size = new System.Drawing.Size(55, 17); - this.genreCheckbox.TabIndex = 19; - this.genreCheckbox.Text = "Genre"; - this.genreCheckbox.UseVisualStyleBackColor = true; - this.genreCheckbox.CheckedChanged += new System.EventHandler(this.GenreCheckbox_CheckedChanged); + genreCheckbox.AutoSize = true; + genreCheckbox.Checked = true; + genreCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + genreCheckbox.FlatAppearance.BorderSize = 0; + genreCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + genreCheckbox.Location = new System.Drawing.Point(1378, 1330); + genreCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + genreCheckbox.Name = "genreCheckbox"; + genreCheckbox.Size = new System.Drawing.Size(110, 36); + genreCheckbox.TabIndex = 19; + genreCheckbox.Text = "Genre"; + genreCheckbox.UseVisualStyleBackColor = true; + genreCheckbox.CheckedChanged += GenreCheckbox_CheckedChanged; // // releasYearCheckbox // - this.releasYearCheckbox.AutoSize = true; - this.releasYearCheckbox.Checked = true; - this.releasYearCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.releasYearCheckbox.FlatAppearance.BorderSize = 0; - this.releasYearCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.releasYearCheckbox.Location = new System.Drawing.Point(445, 540); - this.releasYearCheckbox.Name = "releasYearCheckbox"; - this.releasYearCheckbox.Size = new System.Drawing.Size(90, 17); - this.releasYearCheckbox.TabIndex = 18; - this.releasYearCheckbox.Text = "Release Year"; - this.releasYearCheckbox.UseVisualStyleBackColor = true; - this.releasYearCheckbox.CheckedChanged += new System.EventHandler(this.ReleaseYearCheckbox_CheckedChanged); + releasYearCheckbox.AutoSize = true; + releasYearCheckbox.Checked = true; + releasYearCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + releasYearCheckbox.FlatAppearance.BorderSize = 0; + releasYearCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + releasYearCheckbox.Location = new System.Drawing.Point(964, 1330); + releasYearCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + releasYearCheckbox.Name = "releasYearCheckbox"; + releasYearCheckbox.Size = new System.Drawing.Size(177, 36); + releasYearCheckbox.TabIndex = 18; + releasYearCheckbox.Text = "Release Year"; + releasYearCheckbox.UseVisualStyleBackColor = true; + releasYearCheckbox.CheckedChanged += ReleaseYearCheckbox_CheckedChanged; // // commentCheckbox // - this.commentCheckbox.AutoSize = true; - this.commentCheckbox.FlatAppearance.BorderSize = 0; - this.commentCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.commentCheckbox.Location = new System.Drawing.Point(570, 595); - this.commentCheckbox.Name = "commentCheckbox"; - this.commentCheckbox.Size = new System.Drawing.Size(70, 17); - this.commentCheckbox.TabIndex = 34; - this.commentCheckbox.Text = "Comment"; - this.commentCheckbox.UseVisualStyleBackColor = true; - this.commentCheckbox.CheckedChanged += new System.EventHandler(this.CommentCheckbox_CheckedChanged); + commentCheckbox.AutoSize = true; + commentCheckbox.FlatAppearance.BorderSize = 0; + commentCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + commentCheckbox.Location = new System.Drawing.Point(1235, 1464); + commentCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + commentCheckbox.Name = "commentCheckbox"; + commentCheckbox.Size = new System.Drawing.Size(152, 36); + commentCheckbox.TabIndex = 34; + commentCheckbox.Text = "Comment"; + commentCheckbox.UseVisualStyleBackColor = true; + commentCheckbox.CheckedChanged += CommentCheckbox_CheckedChanged; // // commentTextbox // - this.commentTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.commentTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.commentTextbox.ForeColor = System.Drawing.Color.White; - this.commentTextbox.Location = new System.Drawing.Point(646, 593); - this.commentTextbox.Multiline = true; - this.commentTextbox.Name = "commentTextbox"; - this.commentTextbox.Size = new System.Drawing.Size(112, 17); - this.commentTextbox.TabIndex = 35; - this.commentTextbox.TextChanged += new System.EventHandler(this.CommentTextbox_TextChanged); + commentTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + commentTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + commentTextbox.ForeColor = System.Drawing.Color.White; + commentTextbox.Location = new System.Drawing.Point(1399, 1459); + commentTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + commentTextbox.Multiline = true; + commentTextbox.Name = "commentTextbox"; + commentTextbox.Size = new System.Drawing.Size(242, 42); + commentTextbox.TabIndex = 35; + commentTextbox.TextChanged += CommentTextbox_TextChanged; // // imageCheckbox // - this.imageCheckbox.AutoSize = true; - this.imageCheckbox.Checked = true; - this.imageCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.imageCheckbox.FlatAppearance.BorderSize = 0; - this.imageCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.imageCheckbox.Location = new System.Drawing.Point(382, 595); - this.imageCheckbox.Name = "imageCheckbox"; - this.imageCheckbox.Size = new System.Drawing.Size(70, 17); - this.imageCheckbox.TabIndex = 32; - this.imageCheckbox.Text = "Cover Art"; - this.imageCheckbox.UseVisualStyleBackColor = true; - this.imageCheckbox.CheckedChanged += new System.EventHandler(this.ImageCheckbox_CheckedChanged); + imageCheckbox.AutoSize = true; + imageCheckbox.Checked = true; + imageCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + imageCheckbox.FlatAppearance.BorderSize = 0; + imageCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + imageCheckbox.Location = new System.Drawing.Point(827, 1464); + imageCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + imageCheckbox.Name = "imageCheckbox"; + imageCheckbox.Size = new System.Drawing.Size(146, 36); + imageCheckbox.TabIndex = 32; + imageCheckbox.Text = "Cover Art"; + imageCheckbox.UseVisualStyleBackColor = true; + imageCheckbox.CheckedChanged += ImageCheckbox_CheckedChanged; // // mp3Checkbox // - this.mp3Checkbox.AutoSize = true; - this.mp3Checkbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.mp3Checkbox.Location = new System.Drawing.Point(243, 61); - this.mp3Checkbox.Name = "mp3Checkbox"; - this.mp3Checkbox.Size = new System.Drawing.Size(69, 17); - this.mp3Checkbox.TabIndex = 7; - this.mp3Checkbox.Text = "MP3 320"; - this.mp3Checkbox.UseVisualStyleBackColor = true; - this.mp3Checkbox.CheckedChanged += new System.EventHandler(this.mp3Checkbox_CheckedChanged); + mp3Checkbox.AutoSize = true; + mp3Checkbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + mp3Checkbox.Location = new System.Drawing.Point(526, 150); + mp3Checkbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + mp3Checkbox.Name = "mp3Checkbox"; + mp3Checkbox.Size = new System.Drawing.Size(140, 36); + mp3Checkbox.TabIndex = 7; + mp3Checkbox.Text = "MP3 320"; + mp3Checkbox.UseVisualStyleBackColor = true; + mp3Checkbox.CheckedChanged += mp3Checkbox_CheckedChanged; // // flacLowCheckbox // - this.flacLowCheckbox.AutoSize = true; - this.flacLowCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.flacLowCheckbox.Location = new System.Drawing.Point(318, 61); - this.flacLowCheckbox.Name = "flacLowCheckbox"; - this.flacLowCheckbox.Size = new System.Drawing.Size(93, 17); - this.flacLowCheckbox.TabIndex = 8; - this.flacLowCheckbox.Text = "FLAC 16/44.1"; - this.flacLowCheckbox.UseVisualStyleBackColor = true; - this.flacLowCheckbox.CheckedChanged += new System.EventHandler(this.flacLowCheckbox_CheckedChanged); + flacLowCheckbox.AutoSize = true; + flacLowCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + flacLowCheckbox.Location = new System.Drawing.Point(689, 150); + flacLowCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + flacLowCheckbox.Name = "flacLowCheckbox"; + flacLowCheckbox.Size = new System.Drawing.Size(186, 36); + flacLowCheckbox.TabIndex = 8; + flacLowCheckbox.Text = "FLAC 16/44.1"; + flacLowCheckbox.UseVisualStyleBackColor = true; + flacLowCheckbox.CheckedChanged += flacLowCheckbox_CheckedChanged; // // flacMidCheckbox // - this.flacMidCheckbox.AutoSize = true; - this.flacMidCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.flacMidCheckbox.Location = new System.Drawing.Point(417, 61); - this.flacMidCheckbox.Name = "flacMidCheckbox"; - this.flacMidCheckbox.Size = new System.Drawing.Size(84, 17); - this.flacMidCheckbox.TabIndex = 9; - this.flacMidCheckbox.Text = "FLAC 24/96"; - this.flacMidCheckbox.UseVisualStyleBackColor = true; - this.flacMidCheckbox.CheckedChanged += new System.EventHandler(this.flacMidCheckbox_CheckedChanged); + flacMidCheckbox.AutoSize = true; + flacMidCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + flacMidCheckbox.Location = new System.Drawing.Point(904, 150); + flacMidCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + flacMidCheckbox.Name = "flacMidCheckbox"; + flacMidCheckbox.Size = new System.Drawing.Size(168, 36); + flacMidCheckbox.TabIndex = 9; + flacMidCheckbox.Text = "FLAC 24/96"; + flacMidCheckbox.UseVisualStyleBackColor = true; + flacMidCheckbox.CheckedChanged += flacMidCheckbox_CheckedChanged; // // flacHighCheckbox // - this.flacHighCheckbox.AutoSize = true; - this.flacHighCheckbox.Checked = true; - this.flacHighCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.flacHighCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.flacHighCheckbox.Location = new System.Drawing.Point(507, 61); - this.flacHighCheckbox.Name = "flacHighCheckbox"; - this.flacHighCheckbox.Size = new System.Drawing.Size(90, 17); - this.flacHighCheckbox.TabIndex = 10; - this.flacHighCheckbox.Text = "FLAC 24/192"; - this.flacHighCheckbox.UseVisualStyleBackColor = true; - this.flacHighCheckbox.CheckedChanged += new System.EventHandler(this.flacHighCheckbox_CheckedChanged); + flacHighCheckbox.AutoSize = true; + flacHighCheckbox.Checked = true; + flacHighCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + flacHighCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + flacHighCheckbox.Location = new System.Drawing.Point(1098, 150); + flacHighCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + flacHighCheckbox.Name = "flacHighCheckbox"; + flacHighCheckbox.Size = new System.Drawing.Size(181, 36); + flacHighCheckbox.TabIndex = 10; + flacHighCheckbox.Text = "FLAC 24/192"; + flacHighCheckbox.UseVisualStyleBackColor = true; + flacHighCheckbox.CheckedChanged += flacHighCheckbox_CheckedChanged; // // mp3WarnLabel // - this.mp3WarnLabel.AutoSize = true; - this.mp3WarnLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.mp3WarnLabel.Location = new System.Drawing.Point(744, 621); - this.mp3WarnLabel.Name = "mp3WarnLabel"; - this.mp3WarnLabel.Size = new System.Drawing.Size(182, 13); - this.mp3WarnLabel.TabIndex = 85; - this.mp3WarnLabel.Text = "* = Not available on MP3 downloads."; + mp3WarnLabel.AutoSize = true; + mp3WarnLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + mp3WarnLabel.Location = new System.Drawing.Point(1612, 1528); + mp3WarnLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + mp3WarnLabel.Name = "mp3WarnLabel"; + mp3WarnLabel.Size = new System.Drawing.Size(411, 32); + mp3WarnLabel.TabIndex = 85; + mp3WarnLabel.Text = "* = Not available on MP3 downloads."; // // panel1 // - this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel1.Location = new System.Drawing.Point(15, 107); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(576, 1); - this.panel1.TabIndex = 86; + panel1.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel1.Location = new System.Drawing.Point(32, 264); + panel1.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel1.Name = "panel1"; + panel1.Size = new System.Drawing.Size(1248, 3); + panel1.TabIndex = 86; // // exitLabel // - this.exitLabel.AutoSize = true; - this.exitLabel.BackColor = System.Drawing.Color.Transparent; - this.exitLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.exitLabel.ForeColor = System.Drawing.Color.White; - this.exitLabel.Location = new System.Drawing.Point(911, 8); - this.exitLabel.Name = "exitLabel"; - this.exitLabel.Size = new System.Drawing.Size(20, 23); - this.exitLabel.TabIndex = 87; - this.exitLabel.Text = "X"; - this.exitLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.exitLabel.Click += new System.EventHandler(this.exitLabel_Click); - this.exitLabel.MouseLeave += new System.EventHandler(this.exitLabel_MouseLeave); - this.exitLabel.MouseHover += new System.EventHandler(this.exitLabel_MouseHover); + exitLabel.AutoSize = true; + exitLabel.BackColor = System.Drawing.Color.Transparent; + exitLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + exitLabel.ForeColor = System.Drawing.Color.White; + exitLabel.Location = new System.Drawing.Point(1974, 19); + exitLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + exitLabel.Name = "exitLabel"; + exitLabel.Size = new System.Drawing.Size(41, 46); + exitLabel.TabIndex = 87; + exitLabel.Text = "X"; + exitLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; + exitLabel.Click += exitLabel_Click; + exitLabel.MouseLeave += exitLabel_MouseLeave; + exitLabel.MouseHover += exitLabel_MouseHover; // // minimizeLabel // - this.minimizeLabel.AutoSize = true; - this.minimizeLabel.BackColor = System.Drawing.Color.Transparent; - this.minimizeLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.minimizeLabel.ForeColor = System.Drawing.Color.White; - this.minimizeLabel.Location = new System.Drawing.Point(886, 4); - this.minimizeLabel.Name = "minimizeLabel"; - this.minimizeLabel.Size = new System.Drawing.Size(19, 23); - this.minimizeLabel.TabIndex = 88; - this.minimizeLabel.Text = "_"; - this.minimizeLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.minimizeLabel.Click += new System.EventHandler(this.minimizeLabel_Click); - this.minimizeLabel.MouseLeave += new System.EventHandler(this.minimizeLabel_MouseLeave); - this.minimizeLabel.MouseHover += new System.EventHandler(this.minimizeLabel_MouseHover); + minimizeLabel.AutoSize = true; + minimizeLabel.BackColor = System.Drawing.Color.Transparent; + minimizeLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + minimizeLabel.ForeColor = System.Drawing.Color.White; + minimizeLabel.Location = new System.Drawing.Point(1919, 10); + minimizeLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + minimizeLabel.Name = "minimizeLabel"; + minimizeLabel.Size = new System.Drawing.Size(39, 46); + minimizeLabel.TabIndex = 88; + minimizeLabel.Text = "_"; + minimizeLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; + minimizeLabel.Click += minimizeLabel_Click; + minimizeLabel.MouseLeave += minimizeLabel_MouseLeave; + minimizeLabel.MouseHover += minimizeLabel_MouseHover; // // panel2 // - this.panel2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel2.Location = new System.Drawing.Point(754, 271); - this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(150, 1); - this.panel2.TabIndex = 87; + panel2.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel2.Location = new System.Drawing.Point(1633, 667); + panel2.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel2.Name = "panel2"; + panel2.Size = new System.Drawing.Size(325, 3); + panel2.TabIndex = 87; // // panel3 // - this.panel3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel3.Location = new System.Drawing.Point(754, 313); - this.panel3.Name = "panel3"; - this.panel3.Size = new System.Drawing.Size(150, 1); - this.panel3.TabIndex = 88; + panel3.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel3.Location = new System.Drawing.Point(1633, 771); + panel3.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel3.Name = "panel3"; + panel3.Size = new System.Drawing.Size(325, 3); + panel3.TabIndex = 88; // // panel4 // - this.panel4.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel4.Location = new System.Drawing.Point(754, 355); - this.panel4.Name = "panel4"; - this.panel4.Size = new System.Drawing.Size(150, 1); - this.panel4.TabIndex = 89; + panel4.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel4.Location = new System.Drawing.Point(1633, 874); + panel4.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel4.Name = "panel4"; + panel4.Size = new System.Drawing.Size(325, 3); + panel4.TabIndex = 89; // // panel5 // - this.panel5.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel5.Location = new System.Drawing.Point(754, 397); - this.panel5.Name = "panel5"; - this.panel5.Size = new System.Drawing.Size(150, 1); - this.panel5.TabIndex = 89; + panel5.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel5.Location = new System.Drawing.Point(1633, 978); + panel5.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel5.Name = "panel5"; + panel5.Size = new System.Drawing.Size(325, 3); + panel5.TabIndex = 89; // // panel6 // - this.panel6.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel6.Location = new System.Drawing.Point(754, 439); - this.panel6.Name = "panel6"; - this.panel6.Size = new System.Drawing.Size(150, 1); - this.panel6.TabIndex = 89; + panel6.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel6.Location = new System.Drawing.Point(1633, 1080); + panel6.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel6.Name = "panel6"; + panel6.Size = new System.Drawing.Size(325, 3); + panel6.TabIndex = 89; // // panel7 // - this.panel7.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel7.Location = new System.Drawing.Point(754, 482); - this.panel7.Name = "panel7"; - this.panel7.Size = new System.Drawing.Size(150, 1); - this.panel7.TabIndex = 89; + panel7.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel7.Location = new System.Drawing.Point(1633, 1187); + panel7.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel7.Name = "panel7"; + panel7.Size = new System.Drawing.Size(325, 3); + panel7.TabIndex = 89; // // panel8 // - this.panel8.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel8.Location = new System.Drawing.Point(646, 612); - this.panel8.Name = "panel8"; - this.panel8.Size = new System.Drawing.Size(112, 1); - this.panel8.TabIndex = 90; + panel8.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel8.Location = new System.Drawing.Point(1399, 1507); + panel8.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel8.Name = "panel8"; + panel8.Size = new System.Drawing.Size(242, 3); + panel8.TabIndex = 90; // // streamableCheckbox // - this.streamableCheckbox.AutoSize = true; - this.streamableCheckbox.Checked = true; - this.streamableCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.streamableCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.streamableCheckbox.Location = new System.Drawing.Point(243, 41); - this.streamableCheckbox.Name = "streamableCheckbox"; - this.streamableCheckbox.Size = new System.Drawing.Size(113, 17); - this.streamableCheckbox.TabIndex = 91; - this.streamableCheckbox.Text = "Streamable Check"; - this.streamableCheckbox.UseVisualStyleBackColor = true; - this.streamableCheckbox.Visible = false; - this.streamableCheckbox.CheckedChanged += new System.EventHandler(this.StreamableCheckbox_CheckedChanged); + streamableCheckbox.AutoSize = true; + streamableCheckbox.Checked = true; + streamableCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + streamableCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + streamableCheckbox.Location = new System.Drawing.Point(526, 101); + streamableCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + streamableCheckbox.Name = "streamableCheckbox"; + streamableCheckbox.Size = new System.Drawing.Size(237, 36); + streamableCheckbox.TabIndex = 91; + streamableCheckbox.Text = "Streamable Check"; + streamableCheckbox.UseVisualStyleBackColor = true; + streamableCheckbox.Visible = false; + streamableCheckbox.CheckedChanged += StreamableCheckbox_CheckedChanged; // // secretTextbox // - this.secretTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.secretTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.secretTextbox.ForeColor = System.Drawing.Color.White; - this.secretTextbox.Location = new System.Drawing.Point(412, 15); - this.secretTextbox.Multiline = true; - this.secretTextbox.Name = "secretTextbox"; - this.secretTextbox.ReadOnly = true; - this.secretTextbox.Size = new System.Drawing.Size(179, 20); - this.secretTextbox.TabIndex = 92; - this.secretTextbox.Visible = false; - this.secretTextbox.WordWrap = false; + secretTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + secretTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + secretTextbox.ForeColor = System.Drawing.Color.White; + secretTextbox.Location = new System.Drawing.Point(892, 37); + secretTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + secretTextbox.Multiline = true; + secretTextbox.Name = "secretTextbox"; + secretTextbox.ReadOnly = true; + secretTextbox.Size = new System.Drawing.Size(388, 50); + secretTextbox.TabIndex = 92; + secretTextbox.Visible = false; + secretTextbox.WordWrap = false; // // displaySecretButton // - this.displaySecretButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.displaySecretButton.FlatAppearance.BorderSize = 0; - this.displaySecretButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.displaySecretButton.ForeColor = System.Drawing.Color.White; - this.displaySecretButton.Location = new System.Drawing.Point(303, 12); - this.displaySecretButton.Name = "displaySecretButton"; - this.displaySecretButton.Size = new System.Drawing.Size(103, 23); - this.displaySecretButton.TabIndex = 93; - this.displaySecretButton.Text = "Display Globals_AppSecret"; - this.displaySecretButton.UseVisualStyleBackColor = false; - this.displaySecretButton.Visible = false; - this.displaySecretButton.Click += new System.EventHandler(this.displaySecretButton_Click); + displaySecretButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + displaySecretButton.FlatAppearance.BorderSize = 0; + displaySecretButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + displaySecretButton.ForeColor = System.Drawing.Color.White; + displaySecretButton.Location = new System.Drawing.Point(656, 29); + displaySecretButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + displaySecretButton.Name = "displaySecretButton"; + displaySecretButton.Size = new System.Drawing.Size(223, 56); + displaySecretButton.TabIndex = 93; + displaySecretButton.Text = "Display Globals_AppSecret"; + displaySecretButton.UseVisualStyleBackColor = false; + displaySecretButton.Visible = false; + displaySecretButton.Click += displaySecretButton_Click; // // profilePictureBox // - this.profilePictureBox.Location = new System.Drawing.Point(15, 501); - this.profilePictureBox.Name = "profilePictureBox"; - this.profilePictureBox.Size = new System.Drawing.Size(20, 20); - this.profilePictureBox.TabIndex = 94; - this.profilePictureBox.TabStop = false; + profilePictureBox.Location = new System.Drawing.Point(32, 1234); + profilePictureBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + profilePictureBox.Name = "profilePictureBox"; + profilePictureBox.Size = new System.Drawing.Size(44, 50); + profilePictureBox.TabIndex = 94; + profilePictureBox.TabStop = false; // // logoutLabel // - this.logoutLabel.AutoSize = true; - this.logoutLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.logoutLabel.Location = new System.Drawing.Point(41, 506); - this.logoutLabel.Name = "logoutLabel"; - this.logoutLabel.Size = new System.Drawing.Size(161, 13); - this.logoutLabel.TabIndex = 11; - this.logoutLabel.Text = "Logged in as %name%, Log out?"; - this.logoutLabel.Click += new System.EventHandler(this.logoutLabel_Click); - this.logoutLabel.MouseLeave += new System.EventHandler(this.logoutLabel_MouseLeave); - this.logoutLabel.MouseHover += new System.EventHandler(this.logoutLabel_MouseHover); + logoutLabel.AutoSize = true; + logoutLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + logoutLabel.Location = new System.Drawing.Point(89, 1245); + logoutLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + logoutLabel.Name = "logoutLabel"; + logoutLabel.Size = new System.Drawing.Size(362, 32); + logoutLabel.TabIndex = 11; + logoutLabel.Text = "Logged in as %name%, Log out?"; + logoutLabel.Click += logoutLabel_Click; + logoutLabel.MouseLeave += logoutLabel_MouseLeave; + logoutLabel.MouseHover += logoutLabel_MouseHover; // // hiddenTextPanel // - this.hiddenTextPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.hiddenTextPanel.Location = new System.Drawing.Point(412, 36); - this.hiddenTextPanel.Name = "hiddenTextPanel"; - this.hiddenTextPanel.Size = new System.Drawing.Size(179, 1); - this.hiddenTextPanel.TabIndex = 87; - this.hiddenTextPanel.Visible = false; + hiddenTextPanel.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + hiddenTextPanel.Location = new System.Drawing.Point(892, 88); + hiddenTextPanel.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + hiddenTextPanel.Name = "hiddenTextPanel"; + hiddenTextPanel.Size = new System.Drawing.Size(388, 3); + hiddenTextPanel.TabIndex = 87; + hiddenTextPanel.Visible = false; // // artSizeSelect // - this.artSizeSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.artSizeSelect.FormattingEnabled = true; - this.artSizeSelect.Items.AddRange(new object[] { - "org", - "max", - "600", - "300", - "150", - "100", - "50"}); - this.artSizeSelect.Location = new System.Drawing.Point(113, 621); - this.artSizeSelect.Name = "artSizeSelect"; - this.artSizeSelect.Size = new System.Drawing.Size(87, 21); - this.artSizeSelect.TabIndex = 36; - this.artSizeSelect.SelectedIndexChanged += new System.EventHandler(this.ArtSizeSelect_SelectedIndexChanged); + artSizeSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + artSizeSelect.FormattingEnabled = true; + artSizeSelect.Items.AddRange(new object[] { "org", "max", "600", "300", "150", "100", "50" }); + artSizeSelect.Location = new System.Drawing.Point(245, 1528); + artSizeSelect.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + artSizeSelect.Name = "artSizeSelect"; + artSizeSelect.Size = new System.Drawing.Size(184, 40); + artSizeSelect.TabIndex = 36; + artSizeSelect.SelectedIndexChanged += ArtSizeSelect_SelectedIndexChanged; // // artSizeLabel // - this.artSizeLabel.AutoSize = true; - this.artSizeLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.artSizeLabel.Location = new System.Drawing.Point(12, 624); - this.artSizeLabel.Name = "artSizeLabel"; - this.artSizeLabel.Size = new System.Drawing.Size(207, 13); - this.artSizeLabel.TabIndex = 97; - this.artSizeLabel.Text = "Embedded Art Size: px"; + artSizeLabel.AutoSize = true; + artSizeLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + artSizeLabel.Location = new System.Drawing.Point(26, 1536); + artSizeLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + artSizeLabel.Name = "artSizeLabel"; + artSizeLabel.Size = new System.Drawing.Size(471, 32); + artSizeLabel.TabIndex = 97; + artSizeLabel.Text = "Embedded Art Size: px"; // // typeCheckbox // - this.typeCheckbox.AutoSize = true; - this.typeCheckbox.Checked = true; - this.typeCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.typeCheckbox.FlatAppearance.BorderSize = 0; - this.typeCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.typeCheckbox.Location = new System.Drawing.Point(348, 540); - this.typeCheckbox.Name = "typeCheckbox"; - this.typeCheckbox.Size = new System.Drawing.Size(92, 17); - this.typeCheckbox.TabIndex = 17; - this.typeCheckbox.Text = "Release Type"; - this.typeCheckbox.UseVisualStyleBackColor = true; - this.typeCheckbox.CheckedChanged += new System.EventHandler(this.TypeCheckbox_CheckedChanged); + typeCheckbox.AutoSize = true; + typeCheckbox.Checked = true; + typeCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + typeCheckbox.FlatAppearance.BorderSize = 0; + typeCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + typeCheckbox.Location = new System.Drawing.Point(754, 1330); + typeCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + typeCheckbox.Name = "typeCheckbox"; + typeCheckbox.Size = new System.Drawing.Size(184, 36); + typeCheckbox.TabIndex = 17; + typeCheckbox.Text = "Release Type"; + typeCheckbox.UseVisualStyleBackColor = true; + typeCheckbox.CheckedChanged += TypeCheckbox_CheckedChanged; // // aboutLabel // - this.aboutLabel.AutoSize = true; - this.aboutLabel.BackColor = System.Drawing.Color.Transparent; - this.aboutLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.aboutLabel.ForeColor = System.Drawing.Color.White; - this.aboutLabel.Location = new System.Drawing.Point(866, 8); - this.aboutLabel.Name = "aboutLabel"; - this.aboutLabel.Size = new System.Drawing.Size(15, 23); - this.aboutLabel.TabIndex = 99; - this.aboutLabel.Text = "i"; - this.aboutLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.aboutLabel.Click += new System.EventHandler(this.aboutLabel_Click); - this.aboutLabel.MouseLeave += new System.EventHandler(this.aboutLabel_MouseLeave); - this.aboutLabel.MouseHover += new System.EventHandler(this.aboutLabel_MouseHover); + aboutLabel.AutoSize = true; + aboutLabel.BackColor = System.Drawing.Color.Transparent; + aboutLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0); + aboutLabel.ForeColor = System.Drawing.Color.White; + aboutLabel.Location = new System.Drawing.Point(1877, 19); + aboutLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + aboutLabel.Name = "aboutLabel"; + aboutLabel.Size = new System.Drawing.Size(29, 46); + aboutLabel.TabIndex = 99; + aboutLabel.Text = "i"; + aboutLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; + aboutLabel.Click += aboutLabel_Click; + aboutLabel.MouseLeave += aboutLabel_MouseLeave; + aboutLabel.MouseHover += aboutLabel_MouseHover; // // enableBtnsButton // - this.enableBtnsButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.enableBtnsButton.FlatAppearance.BorderSize = 0; - this.enableBtnsButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.enableBtnsButton.ForeColor = System.Drawing.Color.White; - this.enableBtnsButton.Location = new System.Drawing.Point(597, 28); - this.enableBtnsButton.Name = "enableBtnsButton"; - this.enableBtnsButton.Size = new System.Drawing.Size(120, 23); - this.enableBtnsButton.TabIndex = 100; - this.enableBtnsButton.Text = "Re-Enable Buttons"; - this.enableBtnsButton.UseVisualStyleBackColor = false; - this.enableBtnsButton.Visible = false; - this.enableBtnsButton.Click += new System.EventHandler(this.enableBtnsButton_Click); + enableBtnsButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + enableBtnsButton.FlatAppearance.BorderSize = 0; + enableBtnsButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + enableBtnsButton.ForeColor = System.Drawing.Color.White; + enableBtnsButton.Location = new System.Drawing.Point(1294, 69); + enableBtnsButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + enableBtnsButton.Name = "enableBtnsButton"; + enableBtnsButton.Size = new System.Drawing.Size(260, 56); + enableBtnsButton.TabIndex = 100; + enableBtnsButton.Text = "Re-Enable Buttons"; + enableBtnsButton.UseVisualStyleBackColor = false; + enableBtnsButton.Visible = false; + enableBtnsButton.Click += enableBtnsButton_Click; // // hideDebugButton // - this.hideDebugButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.hideDebugButton.FlatAppearance.BorderSize = 0; - this.hideDebugButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.hideDebugButton.ForeColor = System.Drawing.Color.White; - this.hideDebugButton.Location = new System.Drawing.Point(243, 12); - this.hideDebugButton.Name = "hideDebugButton"; - this.hideDebugButton.Size = new System.Drawing.Size(54, 23); - this.hideDebugButton.TabIndex = 101; - this.hideDebugButton.Text = "Hide"; - this.hideDebugButton.UseVisualStyleBackColor = false; - this.hideDebugButton.Visible = false; - this.hideDebugButton.Click += new System.EventHandler(this.hideDebugButton_Click); + hideDebugButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + hideDebugButton.FlatAppearance.BorderSize = 0; + hideDebugButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + hideDebugButton.ForeColor = System.Drawing.Color.White; + hideDebugButton.Location = new System.Drawing.Point(526, 29); + hideDebugButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + hideDebugButton.Name = "hideDebugButton"; + hideDebugButton.Size = new System.Drawing.Size(117, 56); + hideDebugButton.TabIndex = 101; + hideDebugButton.Text = "Hide"; + hideDebugButton.UseVisualStyleBackColor = false; + hideDebugButton.Visible = false; + hideDebugButton.Click += hideDebugButton_Click; // // maxLengthLabel // - this.maxLengthLabel.AutoSize = true; - this.maxLengthLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.maxLengthLabel.Location = new System.Drawing.Point(444, 624); - this.maxLengthLabel.Name = "maxLengthLabel"; - this.maxLengthLabel.Size = new System.Drawing.Size(121, 13); - this.maxLengthLabel.TabIndex = 102; - this.maxLengthLabel.Text = "Max File Name Length**"; + maxLengthLabel.AutoSize = true; + maxLengthLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + maxLengthLabel.Location = new System.Drawing.Point(962, 1536); + maxLengthLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + maxLengthLabel.Name = "maxLengthLabel"; + maxLengthLabel.Size = new System.Drawing.Size(275, 32); + maxLengthLabel.TabIndex = 102; + maxLengthLabel.Text = "Max File Name Length**"; // // panel9 // - this.panel9.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel9.Location = new System.Drawing.Point(567, 638); - this.panel9.Name = "panel9"; - this.panel9.Size = new System.Drawing.Size(68, 1); - this.panel9.TabIndex = 92; + panel9.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel9.Location = new System.Drawing.Point(1228, 1571); + panel9.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel9.Name = "panel9"; + panel9.Size = new System.Drawing.Size(148, 3); + panel9.TabIndex = 92; // // maxLengthTextbox // - this.maxLengthTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.maxLengthTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.maxLengthTextbox.ForeColor = System.Drawing.Color.White; - this.maxLengthTextbox.Location = new System.Drawing.Point(567, 624); - this.maxLengthTextbox.Multiline = true; - this.maxLengthTextbox.Name = "maxLengthTextbox"; - this.maxLengthTextbox.Size = new System.Drawing.Size(68, 17); - this.maxLengthTextbox.TabIndex = 38; - this.maxLengthTextbox.TextChanged += new System.EventHandler(this.maxLengthTextbox_TextChanged); + maxLengthTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + maxLengthTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + maxLengthTextbox.ForeColor = System.Drawing.Color.White; + maxLengthTextbox.Location = new System.Drawing.Point(1228, 1536); + maxLengthTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + maxLengthTextbox.Multiline = true; + maxLengthTextbox.Name = "maxLengthTextbox"; + maxLengthTextbox.Size = new System.Drawing.Size(148, 42); + maxLengthTextbox.TabIndex = 38; + maxLengthTextbox.TextChanged += maxLengthTextbox_TextChanged; // // maxLengthWarnLabel // - this.maxLengthWarnLabel.AutoSize = true; - this.maxLengthWarnLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.maxLengthWarnLabel.Location = new System.Drawing.Point(819, 635); - this.maxLengthWarnLabel.Name = "maxLengthWarnLabel"; - this.maxLengthWarnLabel.Size = new System.Drawing.Size(107, 13); - this.maxLengthWarnLabel.TabIndex = 103; - this.maxLengthWarnLabel.Text = "** = Max value is 150"; + maxLengthWarnLabel.AutoSize = true; + maxLengthWarnLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + maxLengthWarnLabel.Location = new System.Drawing.Point(1774, 1563); + maxLengthWarnLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + maxLengthWarnLabel.Name = "maxLengthWarnLabel"; + maxLengthWarnLabel.Size = new System.Drawing.Size(242, 32); + maxLengthWarnLabel.TabIndex = 103; + maxLengthWarnLabel.Text = "** = Max value is 150"; // // customFormatPanel // - this.customFormatPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.customFormatPanel.Location = new System.Drawing.Point(572, 60); - this.customFormatPanel.Name = "customFormatPanel"; - this.customFormatPanel.Size = new System.Drawing.Size(19, 1); - this.customFormatPanel.TabIndex = 104; - this.customFormatPanel.Visible = false; + customFormatPanel.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + customFormatPanel.Location = new System.Drawing.Point(1240, 147); + customFormatPanel.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + customFormatPanel.Name = "customFormatPanel"; + customFormatPanel.Size = new System.Drawing.Size(41, 3); + customFormatPanel.TabIndex = 104; + customFormatPanel.Visible = false; // // customFormatIDTextbox // - this.customFormatIDTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.customFormatIDTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.customFormatIDTextbox.ForeColor = System.Drawing.Color.White; - this.customFormatIDTextbox.Location = new System.Drawing.Point(572, 42); - this.customFormatIDTextbox.Multiline = true; - this.customFormatIDTextbox.Name = "customFormatIDTextbox"; - this.customFormatIDTextbox.Size = new System.Drawing.Size(19, 20); - this.customFormatIDTextbox.TabIndex = 105; - this.customFormatIDTextbox.Visible = false; - this.customFormatIDTextbox.WordWrap = false; - this.customFormatIDTextbox.TextChanged += new System.EventHandler(this.customFormatIDTextbox_TextChanged); + customFormatIDTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + customFormatIDTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + customFormatIDTextbox.ForeColor = System.Drawing.Color.White; + customFormatIDTextbox.Location = new System.Drawing.Point(1240, 104); + customFormatIDTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + customFormatIDTextbox.Multiline = true; + customFormatIDTextbox.Name = "customFormatIDTextbox"; + customFormatIDTextbox.Size = new System.Drawing.Size(41, 50); + customFormatIDTextbox.TabIndex = 105; + customFormatIDTextbox.Visible = false; + customFormatIDTextbox.WordWrap = false; + customFormatIDTextbox.TextChanged += customFormatIDTextbox_TextChanged; // // formatIDLabel // - this.formatIDLabel.AutoSize = true; - this.formatIDLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.formatIDLabel.Location = new System.Drawing.Point(513, 42); - this.formatIDLabel.Name = "formatIDLabel"; - this.formatIDLabel.Size = new System.Drawing.Size(53, 13); - this.formatIDLabel.TabIndex = 106; - this.formatIDLabel.Text = "Format ID"; - this.formatIDLabel.Visible = false; + formatIDLabel.AutoSize = true; + formatIDLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + formatIDLabel.Location = new System.Drawing.Point(1112, 104); + formatIDLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + formatIDLabel.Name = "formatIDLabel"; + formatIDLabel.Size = new System.Drawing.Size(119, 32); + formatIDLabel.TabIndex = 106; + formatIDLabel.Text = "Format ID"; + formatIDLabel.Visible = false; // // filenameTempSelect // - this.filenameTempSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.filenameTempSelect.FormattingEnabled = true; - this.filenameTempSelect.Items.AddRange(new object[] { - "00 Trackname", - "00 - Trackname"}); - this.filenameTempSelect.Location = new System.Drawing.Point(325, 621); - this.filenameTempSelect.Name = "filenameTempSelect"; - this.filenameTempSelect.Size = new System.Drawing.Size(108, 21); - this.filenameTempSelect.TabIndex = 37; - this.filenameTempSelect.SelectedIndexChanged += new System.EventHandler(this.filenameTempSelect_SelectedIndexChanged); + filenameTempSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + filenameTempSelect.FormattingEnabled = true; + filenameTempSelect.Items.AddRange(new object[] { "00 Trackname", "00 - Trackname" }); + filenameTempSelect.Location = new System.Drawing.Point(704, 1528); + filenameTempSelect.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + filenameTempSelect.Name = "filenameTempSelect"; + filenameTempSelect.Size = new System.Drawing.Size(230, 40); + filenameTempSelect.TabIndex = 37; + filenameTempSelect.SelectedIndexChanged += filenameTempSelect_SelectedIndexChanged; // // label7 // - this.label7.AutoSize = true; - this.label7.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.label7.Location = new System.Drawing.Point(225, 624); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(99, 13); - this.label7.TabIndex = 108; - this.label7.Text = "Filename Template:"; + label7.AutoSize = true; + label7.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + label7.Location = new System.Drawing.Point(488, 1536); + label7.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + label7.Name = "label7"; + label7.Size = new System.Drawing.Size(221, 32); + label7.TabIndex = 108; + label7.Text = "Filename Template:"; // // testURLBox // - this.testURLBox.Location = new System.Drawing.Point(946, 394); - this.testURLBox.Multiline = true; - this.testURLBox.Name = "testURLBox"; - this.testURLBox.Size = new System.Drawing.Size(390, 20); - this.testURLBox.TabIndex = 1; - this.testURLBox.Text = "Steamed Qobuz File URL"; - this.testURLBox.Visible = false; - this.testURLBox.WordWrap = false; + testURLBox.Location = new System.Drawing.Point(2049, 970); + testURLBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + testURLBox.Multiline = true; + testURLBox.Name = "testURLBox"; + testURLBox.Size = new System.Drawing.Size(841, 44); + testURLBox.TabIndex = 1; + testURLBox.Text = "Steamed Qobuz File URL"; + testURLBox.Visible = false; + testURLBox.WordWrap = false; // // openLogFolderButton // - this.openLogFolderButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.openLogFolderButton.FlatAppearance.BorderSize = 0; - this.openLogFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.openLogFolderButton.ForeColor = System.Drawing.Color.White; - this.openLogFolderButton.Location = new System.Drawing.Point(486, 115); - this.openLogFolderButton.Name = "openLogFolderButton"; - this.openLogFolderButton.Size = new System.Drawing.Size(231, 23); - this.openLogFolderButton.TabIndex = 5; - this.openLogFolderButton.Text = "Open Log Folder"; - this.openLogFolderButton.UseVisualStyleBackColor = false; - this.openLogFolderButton.Click += new System.EventHandler(this.OpenLogFolderButton_Click); + openLogFolderButton.BackColor = System.Drawing.Color.FromArgb(0, 112, 239); + openLogFolderButton.FlatAppearance.BorderSize = 0; + openLogFolderButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + openLogFolderButton.ForeColor = System.Drawing.Color.White; + openLogFolderButton.Location = new System.Drawing.Point(863, 282); + openLogFolderButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + openLogFolderButton.Name = "openLogFolderButton"; + openLogFolderButton.Size = new System.Drawing.Size(374, 56); + openLogFolderButton.TabIndex = 5; + openLogFolderButton.Text = "Open Log Folder"; + openLogFolderButton.UseVisualStyleBackColor = false; + openLogFolderButton.Click += OpenLogFolderButton_Click; // // downloadSpeedLabel // - this.downloadSpeedLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.downloadSpeedLabel.Location = new System.Drawing.Point(655, 506); - this.downloadSpeedLabel.Name = "downloadSpeedLabel"; - this.downloadSpeedLabel.Size = new System.Drawing.Size(250, 13); - this.downloadSpeedLabel.TabIndex = 109; - this.downloadSpeedLabel.Text = "Idle"; - this.downloadSpeedLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; + downloadSpeedLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + downloadSpeedLabel.Location = new System.Drawing.Point(1419, 1245); + downloadSpeedLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + downloadSpeedLabel.Name = "downloadSpeedLabel"; + downloadSpeedLabel.Size = new System.Drawing.Size(541, 32); + downloadSpeedLabel.TabIndex = 109; + downloadSpeedLabel.Text = "Idle"; + downloadSpeedLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; // // panel10 // - this.panel10.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel10.Location = new System.Drawing.Point(549, 583); - this.panel10.Name = "panel10"; - this.panel10.Size = new System.Drawing.Size(15, 1); - this.panel10.TabIndex = 115; + panel10.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel10.Location = new System.Drawing.Point(1190, 1435); + panel10.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel10.Name = "panel10"; + panel10.Size = new System.Drawing.Size(32, 3); + panel10.TabIndex = 115; // // labelCheckbox // - this.labelCheckbox.AutoSize = true; - this.labelCheckbox.Checked = true; - this.labelCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.labelCheckbox.FlatAppearance.BorderSize = 0; - this.labelCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.labelCheckbox.Location = new System.Drawing.Point(166, 567); - this.labelCheckbox.Name = "labelCheckbox"; - this.labelCheckbox.Size = new System.Drawing.Size(52, 17); - this.labelCheckbox.TabIndex = 25; - this.labelCheckbox.Text = "Label"; - this.labelCheckbox.UseVisualStyleBackColor = true; - this.labelCheckbox.CheckedChanged += new System.EventHandler(this.LabelCheckbox_CheckedChanged); + labelCheckbox.AutoSize = true; + labelCheckbox.Checked = true; + labelCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + labelCheckbox.FlatAppearance.BorderSize = 0; + labelCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + labelCheckbox.Location = new System.Drawing.Point(359, 1395); + labelCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + labelCheckbox.Name = "labelCheckbox"; + labelCheckbox.Size = new System.Drawing.Size(102, 36); + labelCheckbox.TabIndex = 25; + labelCheckbox.Text = "Label"; + labelCheckbox.UseVisualStyleBackColor = true; + labelCheckbox.CheckedChanged += LabelCheckbox_CheckedChanged; // // InitialListSeparatorTextbox // - this.InitialListSeparatorTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.InitialListSeparatorTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.InitialListSeparatorTextbox.ForeColor = System.Drawing.Color.White; - this.InitialListSeparatorTextbox.Location = new System.Drawing.Point(549, 564); - this.InitialListSeparatorTextbox.MaxLength = 3; - this.InitialListSeparatorTextbox.Multiline = true; - this.InitialListSeparatorTextbox.Name = "InitialListSeparatorTextbox"; - this.InitialListSeparatorTextbox.Size = new System.Drawing.Size(15, 17); - this.InitialListSeparatorTextbox.TabIndex = 27; - this.InitialListSeparatorTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; - this.InitialListSeparatorTextbox.TextChanged += new System.EventHandler(this.InitialListSeparatorTextbox_TextChanged); + InitialListSeparatorTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + InitialListSeparatorTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + InitialListSeparatorTextbox.ForeColor = System.Drawing.Color.White; + InitialListSeparatorTextbox.Location = new System.Drawing.Point(1190, 1389); + InitialListSeparatorTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + InitialListSeparatorTextbox.MaxLength = 3; + InitialListSeparatorTextbox.Multiline = true; + InitialListSeparatorTextbox.Name = "InitialListSeparatorTextbox"; + InitialListSeparatorTextbox.Size = new System.Drawing.Size(32, 42); + InitialListSeparatorTextbox.TabIndex = 27; + InitialListSeparatorTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + InitialListSeparatorTextbox.TextChanged += InitialListSeparatorTextbox_TextChanged; // // involvedPeopleCheckBox // - this.involvedPeopleCheckBox.AutoSize = true; - this.involvedPeopleCheckBox.Checked = true; - this.involvedPeopleCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.involvedPeopleCheckBox.FlatAppearance.BorderSize = 0; - this.involvedPeopleCheckBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.involvedPeopleCheckBox.Location = new System.Drawing.Point(222, 567); - this.involvedPeopleCheckBox.Name = "involvedPeopleCheckBox"; - this.involvedPeopleCheckBox.Size = new System.Drawing.Size(103, 17); - this.involvedPeopleCheckBox.TabIndex = 26; - this.involvedPeopleCheckBox.Text = "Involved People"; - this.involvedPeopleCheckBox.UseVisualStyleBackColor = true; - this.involvedPeopleCheckBox.CheckedChanged += new System.EventHandler(this.InvolvedPeopleCheckbox_CheckedChanged); + involvedPeopleCheckBox.AutoSize = true; + involvedPeopleCheckBox.Checked = true; + involvedPeopleCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + involvedPeopleCheckBox.FlatAppearance.BorderSize = 0; + involvedPeopleCheckBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + involvedPeopleCheckBox.Location = new System.Drawing.Point(481, 1395); + involvedPeopleCheckBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + involvedPeopleCheckBox.Name = "involvedPeopleCheckBox"; + involvedPeopleCheckBox.Size = new System.Drawing.Size(216, 36); + involvedPeopleCheckBox.TabIndex = 26; + involvedPeopleCheckBox.Text = "Involved People"; + involvedPeopleCheckBox.UseVisualStyleBackColor = true; + involvedPeopleCheckBox.CheckedChanged += InvolvedPeopleCheckbox_CheckedChanged; // // producerCheckbox // - this.producerCheckbox.AutoSize = true; - this.producerCheckbox.Checked = true; - this.producerCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.producerCheckbox.FlatAppearance.BorderSize = 0; - this.producerCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.producerCheckbox.Location = new System.Drawing.Point(89, 567); - this.producerCheckbox.Name = "producerCheckbox"; - this.producerCheckbox.Size = new System.Drawing.Size(73, 17); - this.producerCheckbox.TabIndex = 24; - this.producerCheckbox.Text = "Producer*"; - this.producerCheckbox.UseVisualStyleBackColor = true; - this.producerCheckbox.CheckedChanged += new System.EventHandler(this.ProducerCheckbox_CheckedChanged); + producerCheckbox.AutoSize = true; + producerCheckbox.Checked = true; + producerCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + producerCheckbox.FlatAppearance.BorderSize = 0; + producerCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + producerCheckbox.Location = new System.Drawing.Point(193, 1395); + producerCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + producerCheckbox.Name = "producerCheckbox"; + producerCheckbox.Size = new System.Drawing.Size(151, 36); + producerCheckbox.TabIndex = 24; + producerCheckbox.Text = "Producer*"; + producerCheckbox.UseVisualStyleBackColor = true; + producerCheckbox.CheckedChanged += ProducerCheckbox_CheckedChanged; // // PrimaryListSeparatorLabel // - this.PrimaryListSeparatorLabel.AutoSize = true; - this.PrimaryListSeparatorLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.PrimaryListSeparatorLabel.Location = new System.Drawing.Point(442, 568); - this.PrimaryListSeparatorLabel.Name = "PrimaryListSeparatorLabel"; - this.PrimaryListSeparatorLabel.Size = new System.Drawing.Size(103, 13); - this.PrimaryListSeparatorLabel.TabIndex = 100; - this.PrimaryListSeparatorLabel.Text = "PrimaryListSeparator"; + PrimaryListSeparatorLabel.AutoSize = true; + PrimaryListSeparatorLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + PrimaryListSeparatorLabel.Location = new System.Drawing.Point(957, 1398); + PrimaryListSeparatorLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + PrimaryListSeparatorLabel.Name = "PrimaryListSeparatorLabel"; + PrimaryListSeparatorLabel.Size = new System.Drawing.Size(231, 32); + PrimaryListSeparatorLabel.TabIndex = 100; + PrimaryListSeparatorLabel.Text = "PrimaryListSeparator"; // // ListEndSeparatorLabel // - this.ListEndSeparatorLabel.AutoSize = true; - this.ListEndSeparatorLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.ListEndSeparatorLabel.Location = new System.Drawing.Point(576, 568); - this.ListEndSeparatorLabel.Name = "ListEndSeparatorLabel"; - this.ListEndSeparatorLabel.Size = new System.Drawing.Size(88, 13); - this.ListEndSeparatorLabel.TabIndex = 117; - this.ListEndSeparatorLabel.Text = "ListEndSeparator"; + ListEndSeparatorLabel.AutoSize = true; + ListEndSeparatorLabel.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + ListEndSeparatorLabel.Location = new System.Drawing.Point(1248, 1398); + ListEndSeparatorLabel.Margin = new System.Windows.Forms.Padding(6, 0, 6, 0); + ListEndSeparatorLabel.Name = "ListEndSeparatorLabel"; + ListEndSeparatorLabel.Size = new System.Drawing.Size(191, 32); + ListEndSeparatorLabel.TabIndex = 117; + ListEndSeparatorLabel.Text = "ListEndSeparator"; // // panel11 // - this.panel11.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel11.Location = new System.Drawing.Point(669, 583); - this.panel11.Name = "panel11"; - this.panel11.Size = new System.Drawing.Size(15, 1); - this.panel11.TabIndex = 118; + panel11.BackColor = System.Drawing.Color.FromArgb(88, 92, 102); + panel11.Location = new System.Drawing.Point(1450, 1435); + panel11.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + panel11.Name = "panel11"; + panel11.Size = new System.Drawing.Size(32, 3); + panel11.TabIndex = 118; // // ListEndSeparatorTextbox // - this.ListEndSeparatorTextbox.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.ListEndSeparatorTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.ListEndSeparatorTextbox.ForeColor = System.Drawing.Color.White; - this.ListEndSeparatorTextbox.Location = new System.Drawing.Point(669, 564); - this.ListEndSeparatorTextbox.MaxLength = 3; - this.ListEndSeparatorTextbox.Multiline = true; - this.ListEndSeparatorTextbox.Name = "ListEndSeparatorTextbox"; - this.ListEndSeparatorTextbox.Size = new System.Drawing.Size(15, 17); - this.ListEndSeparatorTextbox.TabIndex = 116; - this.ListEndSeparatorTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + ListEndSeparatorTextbox.BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + ListEndSeparatorTextbox.BorderStyle = System.Windows.Forms.BorderStyle.None; + ListEndSeparatorTextbox.ForeColor = System.Drawing.Color.White; + ListEndSeparatorTextbox.Location = new System.Drawing.Point(1450, 1389); + ListEndSeparatorTextbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + ListEndSeparatorTextbox.MaxLength = 3; + ListEndSeparatorTextbox.Multiline = true; + ListEndSeparatorTextbox.Name = "ListEndSeparatorTextbox"; + ListEndSeparatorTextbox.Size = new System.Drawing.Size(32, 42); + ListEndSeparatorTextbox.TabIndex = 116; + ListEndSeparatorTextbox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; // // mergePerformersCheckBox // - this.mergePerformersCheckBox.AutoSize = true; - this.mergePerformersCheckBox.Checked = true; - this.mergePerformersCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.mergePerformersCheckBox.FlatAppearance.BorderSize = 0; - this.mergePerformersCheckBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.mergePerformersCheckBox.Location = new System.Drawing.Point(329, 567); - this.mergePerformersCheckBox.Name = "mergePerformersCheckBox"; - this.mergePerformersCheckBox.Size = new System.Drawing.Size(109, 17); - this.mergePerformersCheckBox.TabIndex = 119; - this.mergePerformersCheckBox.Text = "Merge Performers"; - this.mergeListsToolTip.SetToolTip(this.mergePerformersCheckBox, resources.GetString("mergePerformersCheckBox.ToolTip")); - this.mergePerformersCheckBox.UseVisualStyleBackColor = true; - this.mergePerformersCheckBox.CheckedChanged += new System.EventHandler(this.MergePerformersCheckbox_CheckedChanged); + mergePerformersCheckBox.AutoSize = true; + mergePerformersCheckBox.Checked = true; + mergePerformersCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + mergePerformersCheckBox.FlatAppearance.BorderSize = 0; + mergePerformersCheckBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + mergePerformersCheckBox.Location = new System.Drawing.Point(713, 1395); + mergePerformersCheckBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + mergePerformersCheckBox.Name = "mergePerformersCheckBox"; + mergePerformersCheckBox.Size = new System.Drawing.Size(238, 36); + mergePerformersCheckBox.TabIndex = 119; + mergePerformersCheckBox.Text = "Merge Performers"; + mergeListsToolTip.SetToolTip(mergePerformersCheckBox, resources.GetString("mergePerformersCheckBox.ToolTip")); + mergePerformersCheckBox.UseVisualStyleBackColor = true; + mergePerformersCheckBox.CheckedChanged += MergePerformersCheckbox_CheckedChanged; // // mergeListsToolTip // - this.mergeListsToolTip.AutoPopDelay = 32000; - this.mergeListsToolTip.InitialDelay = 500; - this.mergeListsToolTip.ReshowDelay = 100; + mergeListsToolTip.AutoPopDelay = 32000; + mergeListsToolTip.InitialDelay = 500; + mergeListsToolTip.ReshowDelay = 100; // // releaseDateCheckbox // - this.releaseDateCheckbox.AutoSize = true; - this.releaseDateCheckbox.Checked = true; - this.releaseDateCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.releaseDateCheckbox.FlatAppearance.BorderSize = 0; - this.releaseDateCheckbox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.releaseDateCheckbox.Location = new System.Drawing.Point(540, 540); - this.releaseDateCheckbox.Name = "releaseDateCheckbox"; - this.releaseDateCheckbox.Size = new System.Drawing.Size(91, 17); - this.releaseDateCheckbox.TabIndex = 18; - this.releaseDateCheckbox.Text = "Release Date"; - this.releaseDateCheckbox.UseVisualStyleBackColor = true; - this.releaseDateCheckbox.CheckedChanged += new System.EventHandler(this.ReleaseDateCheckbox_CheckedChanged); + releaseDateCheckbox.AutoSize = true; + releaseDateCheckbox.Checked = true; + releaseDateCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + releaseDateCheckbox.FlatAppearance.BorderSize = 0; + releaseDateCheckbox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + releaseDateCheckbox.Location = new System.Drawing.Point(1170, 1330); + releaseDateCheckbox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + releaseDateCheckbox.Name = "releaseDateCheckbox"; + releaseDateCheckbox.Size = new System.Drawing.Size(183, 36); + releaseDateCheckbox.TabIndex = 18; + releaseDateCheckbox.Text = "Release Date"; + releaseDateCheckbox.UseVisualStyleBackColor = true; + releaseDateCheckbox.CheckedChanged += ReleaseDateCheckbox_CheckedChanged; // // urlCheckBox // - this.urlCheckBox.AutoSize = true; - this.urlCheckBox.Checked = true; - this.urlCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.urlCheckBox.FlatAppearance.BorderSize = 0; - this.urlCheckBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.urlCheckBox.Location = new System.Drawing.Point(696, 567); - this.urlCheckBox.Name = "urlCheckBox"; - this.urlCheckBox.Size = new System.Drawing.Size(48, 17); - this.urlCheckBox.TabIndex = 120; - this.urlCheckBox.Text = "URL"; - this.urlCheckBox.UseVisualStyleBackColor = true; - this.urlCheckBox.CheckedChanged += new System.EventHandler(this.UrlCheckbox_CheckedChanged); + urlCheckBox.AutoSize = true; + urlCheckBox.Checked = true; + urlCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + urlCheckBox.FlatAppearance.BorderSize = 0; + urlCheckBox.ForeColor = System.Drawing.Color.FromArgb(88, 92, 102); + urlCheckBox.Location = new System.Drawing.Point(1508, 1395); + urlCheckBox.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + urlCheckBox.Name = "urlCheckBox"; + urlCheckBox.Size = new System.Drawing.Size(87, 36); + urlCheckBox.TabIndex = 120; + urlCheckBox.Text = "URL"; + urlCheckBox.UseVisualStyleBackColor = true; + urlCheckBox.CheckedChanged += UrlCheckbox_CheckedChanged; + // + // stopButton + // + stopButton.BackColor = System.Drawing.Color.FromArgb(200, 50, 80); + stopButton.FlatAppearance.BorderSize = 0; + stopButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + stopButton.ForeColor = System.Drawing.Color.White; + stopButton.Location = new System.Drawing.Point(1294, 283); + stopButton.Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + stopButton.Name = "stopButton"; + stopButton.Size = new System.Drawing.Size(260, 56); + stopButton.TabIndex = 121; + stopButton.Text = "Stop Download"; + stopButton.UseVisualStyleBackColor = false; + stopButton.Click += stopButton_Click; // // QobuzDownloaderX // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.ClientSize = new System.Drawing.Size(938, 660); - this.Controls.Add(this.urlCheckBox); - this.Controls.Add(this.mergePerformersCheckBox); - this.Controls.Add(this.ListEndSeparatorLabel); - this.Controls.Add(this.panel11); - this.Controls.Add(this.ListEndSeparatorTextbox); - this.Controls.Add(this.PrimaryListSeparatorLabel); - this.Controls.Add(this.panel10); - this.Controls.Add(this.labelCheckbox); - this.Controls.Add(this.InitialListSeparatorTextbox); - this.Controls.Add(this.involvedPeopleCheckBox); - this.Controls.Add(this.producerCheckbox); - this.Controls.Add(this.downloadSpeedLabel); - this.Controls.Add(this.openLogFolderButton); - this.Controls.Add(this.filenameTempSelect); - this.Controls.Add(this.label7); - this.Controls.Add(this.formatIDLabel); - this.Controls.Add(this.customFormatPanel); - this.Controls.Add(this.customFormatIDTextbox); - this.Controls.Add(this.maxLengthWarnLabel); - this.Controls.Add(this.panel9); - this.Controls.Add(this.maxLengthTextbox); - this.Controls.Add(this.maxLengthLabel); - this.Controls.Add(this.hideDebugButton); - this.Controls.Add(this.enableBtnsButton); - this.Controls.Add(this.aboutLabel); - this.Controls.Add(this.typeCheckbox); - this.Controls.Add(this.artSizeSelect); - this.Controls.Add(this.artSizeLabel); - this.Controls.Add(this.hiddenTextPanel); - this.Controls.Add(this.logoutLabel); - this.Controls.Add(this.profilePictureBox); - this.Controls.Add(this.displaySecretButton); - this.Controls.Add(this.secretTextbox); - this.Controls.Add(this.streamableCheckbox); - this.Controls.Add(this.panel8); - this.Controls.Add(this.panel7); - this.Controls.Add(this.panel6); - this.Controls.Add(this.panel5); - this.Controls.Add(this.panel4); - this.Controls.Add(this.panel3); - this.Controls.Add(this.panel2); - this.Controls.Add(this.minimizeLabel); - this.Controls.Add(this.exitLabel); - this.Controls.Add(this.panel1); - this.Controls.Add(this.mp3WarnLabel); - this.Controls.Add(this.flacHighCheckbox); - this.Controls.Add(this.flacMidCheckbox); - this.Controls.Add(this.flacLowCheckbox); - this.Controls.Add(this.mp3Checkbox); - this.Controls.Add(this.imageCheckbox); - this.Controls.Add(this.commentTextbox); - this.Controls.Add(this.commentCheckbox); - this.Controls.Add(this.explicitCheckbox); - this.Controls.Add(this.upcCheckbox); - this.Controls.Add(this.isrcCheckbox); - this.Controls.Add(this.copyrightCheckbox); - this.Controls.Add(this.composerCheckbox); - this.Controls.Add(this.genreCheckbox); - this.Controls.Add(this.releaseDateCheckbox); - this.Controls.Add(this.releasYearCheckbox); - this.Controls.Add(this.albumCheckbox); - this.Controls.Add(this.discTotalCheckbox); - this.Controls.Add(this.discNumberCheckbox); - this.Controls.Add(this.trackTotalCheckbox); - this.Controls.Add(this.trackNumberCheckbox); - this.Controls.Add(this.trackTitleCheckbox); - this.Controls.Add(this.artistCheckbox); - this.Controls.Add(this.albumArtistCheckbox); - this.Controls.Add(this.tagsLabel); - this.Controls.Add(this.openSearchButton); - this.Controls.Add(this.qualityTextbox); - this.Controls.Add(this.qualityLabel); - this.Controls.Add(this.totalTracksTextbox); - this.Controls.Add(this.totalTracksLabel); - this.Controls.Add(this.label6); - this.Controls.Add(this.upcTextBox); - this.Controls.Add(this.label5); - this.Controls.Add(this.releaseDateTextBox); - this.Controls.Add(this.label4); - this.Controls.Add(this.albumTextBox); - this.Controls.Add(this.label3); - this.Controls.Add(this.albumArtistTextBox); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.Controls.Add(this.albumArtPicBox); - this.Controls.Add(this.verNumLabel); - this.Controls.Add(this.logoBox); - this.Controls.Add(this.imageURLTextbox); - this.Controls.Add(this.downloadButton); - this.Controls.Add(this.downloadUrl); - this.Controls.Add(this.openFolderButton); - this.Controls.Add(this.output); - this.Controls.Add(this.selectFolderButton); - this.Controls.Add(this.testURLBox); - this.DoubleBuffered = true; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.Name = "QobuzDownloaderX"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "QobuzDownloaderX"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.QobuzDownloaderX_FormClosed); - this.Load += new System.EventHandler(this.MainForm_Load); - this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.QobuzDownloaderX_MouseMove); - ((System.ComponentModel.ISupportInitialize)(this.albumArtPicBox)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.logoBox)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.profilePictureBox)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + BackColor = System.Drawing.Color.FromArgb(20, 20, 20); + ClientSize = new System.Drawing.Size(2033, 1624); + Controls.Add(stopButton); + Controls.Add(urlCheckBox); + Controls.Add(mergePerformersCheckBox); + Controls.Add(ListEndSeparatorLabel); + Controls.Add(panel11); + Controls.Add(ListEndSeparatorTextbox); + Controls.Add(PrimaryListSeparatorLabel); + Controls.Add(panel10); + Controls.Add(labelCheckbox); + Controls.Add(InitialListSeparatorTextbox); + Controls.Add(involvedPeopleCheckBox); + Controls.Add(producerCheckbox); + Controls.Add(downloadSpeedLabel); + Controls.Add(openLogFolderButton); + Controls.Add(filenameTempSelect); + Controls.Add(label7); + Controls.Add(formatIDLabel); + Controls.Add(customFormatPanel); + Controls.Add(customFormatIDTextbox); + Controls.Add(maxLengthWarnLabel); + Controls.Add(panel9); + Controls.Add(maxLengthTextbox); + Controls.Add(maxLengthLabel); + Controls.Add(hideDebugButton); + Controls.Add(enableBtnsButton); + Controls.Add(aboutLabel); + Controls.Add(typeCheckbox); + Controls.Add(artSizeSelect); + Controls.Add(artSizeLabel); + Controls.Add(hiddenTextPanel); + Controls.Add(logoutLabel); + Controls.Add(profilePictureBox); + Controls.Add(displaySecretButton); + Controls.Add(secretTextbox); + Controls.Add(streamableCheckbox); + Controls.Add(panel8); + Controls.Add(panel7); + Controls.Add(panel6); + Controls.Add(panel5); + Controls.Add(panel4); + Controls.Add(panel3); + Controls.Add(panel2); + Controls.Add(minimizeLabel); + Controls.Add(exitLabel); + Controls.Add(panel1); + Controls.Add(mp3WarnLabel); + Controls.Add(flacHighCheckbox); + Controls.Add(flacMidCheckbox); + Controls.Add(flacLowCheckbox); + Controls.Add(mp3Checkbox); + Controls.Add(imageCheckbox); + Controls.Add(commentTextbox); + Controls.Add(commentCheckbox); + Controls.Add(explicitCheckbox); + Controls.Add(upcCheckbox); + Controls.Add(isrcCheckbox); + Controls.Add(copyrightCheckbox); + Controls.Add(composerCheckbox); + Controls.Add(genreCheckbox); + Controls.Add(releaseDateCheckbox); + Controls.Add(releasYearCheckbox); + Controls.Add(albumCheckbox); + Controls.Add(discTotalCheckbox); + Controls.Add(discNumberCheckbox); + Controls.Add(trackTotalCheckbox); + Controls.Add(trackNumberCheckbox); + Controls.Add(trackTitleCheckbox); + Controls.Add(artistCheckbox); + Controls.Add(albumArtistCheckbox); + Controls.Add(tagsLabel); + Controls.Add(openSearchButton); + Controls.Add(qualityTextbox); + Controls.Add(qualityLabel); + Controls.Add(totalTracksTextbox); + Controls.Add(totalTracksLabel); + Controls.Add(label6); + Controls.Add(upcTextBox); + Controls.Add(label5); + Controls.Add(releaseDateTextBox); + Controls.Add(label4); + Controls.Add(albumTextBox); + Controls.Add(label3); + Controls.Add(albumArtistTextBox); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(albumArtPicBox); + Controls.Add(verNumLabel); + Controls.Add(logoBox); + Controls.Add(imageURLTextbox); + Controls.Add(downloadButton); + Controls.Add(downloadUrl); + Controls.Add(openFolderButton); + Controls.Add(output); + Controls.Add(selectFolderButton); + Controls.Add(testURLBox); + DoubleBuffered = true; + FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon"); + Margin = new System.Windows.Forms.Padding(6, 8, 6, 8); + MaximizeBox = false; + Name = "QobuzDownloaderX"; + StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + Text = "QobuzDownloaderX"; + FormClosed += QobuzDownloaderX_FormClosed; + Load += MainForm_Load; + MouseMove += QobuzDownloaderX_MouseMove; + ((System.ComponentModel.ISupportInitialize)albumArtPicBox).EndInit(); + ((System.ComponentModel.ISupportInitialize)logoBox).EndInit(); + ((System.ComponentModel.ISupportInitialize)profilePictureBox).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -1525,6 +1633,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolTip mergeListsToolTip; private System.Windows.Forms.CheckBox releaseDateCheckbox; private System.Windows.Forms.CheckBox urlCheckBox; + private System.Windows.Forms.Button stopButton; } } diff --git a/QobuzDownloaderX/View/MainForm.cs b/QobuzDownloaderX/View/MainForm.cs index 3766982..e42b320 100644 --- a/QobuzDownloaderX/View/MainForm.cs +++ b/QobuzDownloaderX/View/MainForm.cs @@ -1,13 +1,17 @@ -using QobuzDownloaderX.Models; +using DownloadAssistant.Requests; +using QobuzDownloaderX.Models; using QobuzDownloaderX.Properties; using QobuzDownloaderX.Shared; using QobuzDownloaderX.View; +using Requests; +using Requests.Options; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; +using System.Linq; using System.Reflection; using System.Threading; -using System.Threading.Tasks; using System.Windows.Forms; namespace QobuzDownloaderX @@ -15,22 +19,26 @@ namespace QobuzDownloaderX public partial class QobuzDownloaderX : HeadlessForm { private readonly DownloadLogger logger; - private readonly DownloadManager downloadManager; public QobuzDownloaderX() { + // this.AutoSize = true; InitializeComponent(); - - logger = new DownloadLogger(output, UpdateControlsDownloadEnd); + this.Height = 750; + this.Width = 1086; + logger = new DownloadLogger(output, "MainForm"); + RequestHandler.MainRequestHandlers[0].StaticDegreeOfParallelism = 2; // Remove previous download error log logger.RemovePreviousErrorLog(); - - downloadManager = new DownloadManager(logger, UpdateAlbumTagsUI, UpdateDownloadSpeedLabel) + _requests.SpeedReporter.Timeout = 1000; + _requests.SpeedReporter.SpeedChanged += (obj, speed) => { - CheckIfStreamable = streamableCheckbox.Checked + double speedInMB = ((double)speed) / (1024 * 1024); + UpdateDownloadSpeedLabel($"{speedInMB:F2} MB/s"); }; } + private ExtendedContainer _requests = []; public string DownloadLogPath { get; set; } public int DevClickEggThingValue { get; set; } @@ -45,7 +53,6 @@ public QobuzDownloaderX() private void MainForm_Load(object sender, EventArgs e) { // Set main form size on launch and bring to center. - this.Height = 533; this.CenterToScreen(); // Grab profile image @@ -78,7 +85,8 @@ private void MainForm_Load(object sender, EventArgs e) output.Invoke(new Action(() => output.AppendText("Active Family sub-account, unknown End Date \r\n"))); output.Invoke(new Action(() => output.AppendText("Credential Label - " + Globals.Login.User.Credential.Label + "\r\n"))); output.Invoke(new Action(() => output.AppendText("==========================\r\n\r\n"))); - } else + } + else { output.Invoke(new Action(() => output.AppendText("No active subscriptions, only sample downloads possible!\r\n"))); output.Invoke(new Action(() => output.AppendText("==========================\r\n\r\n"))); @@ -225,13 +233,8 @@ private void OpenSearch_Click(object sender, EventArgs e) private async void DownloadButton_Click(object sender, EventArgs e) { - if (!downloadManager.IsBuzy) - { - await StartLinkItemDownloadAsync(downloadUrl.Text); - } else - { - downloadManager.StopDownloadTask(); - } + StartLinkItemDownload(downloadUrl.Text); + _requests.Remove(_requests.Where(x => x.State is RequestState.Failed or RequestState.Compleated or RequestState.Cancelled)?.ToArray()); } private async void DownloadUrl_KeyDown(object sender, KeyEventArgs e) @@ -241,11 +244,11 @@ private async void DownloadUrl_KeyDown(object sender, KeyEventArgs e) e.Handled = true; e.SuppressKeyPress = true; - await StartLinkItemDownloadAsync(downloadUrl.Text); + StartLinkItemDownload(downloadUrl.Text); } } - public async Task StartLinkItemDownloadAsync(string downloadLink) + public void StartLinkItemDownload(params string[] downloadLinks) { // Check if there's no selected path. if (string.IsNullOrEmpty(Settings.Default.savedFolder)) @@ -255,26 +258,59 @@ public async Task StartLinkItemDownloadAsync(string downloadLink) output.Invoke(new Action(() => output.AppendText($"No path has been set! Remember to Choose a Folder!{Environment.NewLine}"))); return; } - - // Get download item type and ID from url - DownloadItem downloadItem = DownloadUrlParser.ParseDownloadUrl(downloadLink); - - // If download item could not be parsed, abort - if (downloadItem.IsEmpty()) + if (downloadLinks.All(string.IsNullOrWhiteSpace)) { - logger.ClearUiLogComponent(); - output.Invoke(new Action(() => output.AppendText("URL not understood. Is there a typo?"))); + if (_requests.State == RequestState.Paused && _requests.Length > 0) + { + output.Invoke(new Action(() => output.AppendText("Starting all paused downloads.\r\n"))); + _requests.Start(); + } + else if (_requests.State == RequestState.Running) + _requests.ToList().ForEach(x => x.Start()); + else + output.Invoke(new Action(() => output.AppendText("The download links were empty.\r\n"))); return; } - // If, for some reason, a download is still buzy, do nothing - if (downloadManager.IsBuzy) + List downloadItems = new(downloadLinks.Length); + foreach (string downloadLink in downloadLinks) { - return; + var request = _requests.FirstOrDefault(x => x.StartOptions.DownloadItem.Url == downloadLink); + + switch (request) + { + case null: + downloadItems.Add(DownloadUrlParser.ParseDownloadUrl(downloadLink)); + break; + case var r when r.State == RequestState.Paused: + r.Start(); + output.Invoke(new Action(() => output.AppendText($"Restarting download for URL: {downloadLink}\r\n"))); + break; + default: + output.Invoke(new Action(() => output.AppendText($"URL: {downloadLink} is already being downloaded.\r\n"))); + break; + } } + foreach (var downloadItem in downloadItems) + if (downloadItem.IsEmpty()) + output.Invoke(new Action(() => output.AppendText($"URL >{downloadItem.Url}< not understood. Is there a typo?\r\n"))); + + else + _requests.Add(new DownloadRequest(new() + { + DownloadItem = downloadItem, + UpdateAlbumTagsUi = UpdateAlbumTagsUI, + CheckIfStreamable = streamableCheckbox.Checked, + Handler = RequestHandler.MainRequestHandlers[0], + RequestStarted = (_) => UpdateControlsDownloadStart(), + RequestCancelled = (_) => UpdateControlsDownloadEnd(), + RequestFailed = (_, _) => UpdateControlsDownloadEnd(), + RequestCompleated = (_, _) => UpdateControlsDownloadEnd(), + Logger = new DownloadLogger(output, $"Download_Log_Item_{downloadItem.Id}_Time_{DateTime.Now:yyyy-MM-dd_HH.mm.ss.fff}") + })); + // Run the StartDownloadItemTaskAsync method on a background thread & Wait for the task to complete - await Task.Run(() => downloadManager.StartDownloadItemTaskAsync(downloadItem, UpdateControlsDownloadStart, UpdateControlsDownloadEnd)); } public void UpdateControlsDownloadStart() @@ -283,16 +319,14 @@ public void UpdateControlsDownloadStart() flacLowCheckbox.Invoke(new Action(() => flacLowCheckbox.AutoCheck = false)); flacMidCheckbox.Invoke(new Action(() => flacMidCheckbox.AutoCheck = false)); flacHighCheckbox.Invoke(new Action(() => flacHighCheckbox.AutoCheck = false)); - - downloadUrl.Invoke(new Action(() => downloadUrl.Enabled = false)); - + //downloadUrl.Invoke(new Action(() => downloadUrl.Enabled = false)); selectFolderButton.Invoke(new Action(() => selectFolderButton.Enabled = false)); - openSearchButton.Invoke(new Action(() => openSearchButton.Enabled = false)); + //openSearchButton.Invoke(new Action(() => openSearchButton.Enabled = false)); - downloadButton.Invoke(new Action(() => { - downloadButton.Text = "Stop Download"; - downloadButton.BackColor = BuzyButtonBackColor; - })); + //downloadButton.Invoke(new Action(() => { + // downloadButton.Text = "Stop Download"; + // downloadButton.BackColor = BuzyButtonBackColor; + //})); } public void UpdateControlsDownloadEnd() @@ -307,7 +341,8 @@ public void UpdateControlsDownloadEnd() selectFolderButton.Invoke(new Action(() => selectFolderButton.Enabled = true)); openSearchButton.Invoke(new Action(() => openSearchButton.Enabled = true)); - downloadButton.Invoke(new Action(() => { + downloadButton.Invoke(new Action(() => + { downloadButton.Text = "Download"; downloadButton.BackColor = ReadyButtonBackColor; })); @@ -343,15 +378,44 @@ private void OpenFolderButton_Click(object sender, EventArgs e) { // If selected path doesn't exist, create it. (Will be ignored if it does) System.IO.Directory.CreateDirectory(folderBrowserDialog.SelectedPath); + // Open selected folder - Process.Start(@folderBrowserDialog.SelectedPath); + try + { + ProcessStartInfo startInfo = new() + { + FileName = folderBrowserDialog.SelectedPath, + UseShellExecute = true, + WorkingDirectory = folderBrowserDialog.SelectedPath + }; + Process.Start(startInfo); + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}", "ERROR", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } } } private void OpenLogFolderButton_Click(object sender, EventArgs e) { // Open log folder. Folder should exist here so no extra check - Process.Start(@Globals.LoggingDir); + try + { + ProcessStartInfo startInfo = new() + { + FileName = Globals.LoggingDir, + UseShellExecute = true, + WorkingDirectory = Globals.LoggingDir + }; + Process.Start(startInfo); + } + catch (Exception ex) + { + MessageBox.Show($"An error occurred: {ex.Message}", "ERROR", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } } // Update UI for downloading album @@ -373,18 +437,21 @@ public void UpdateAlbumTagsUI(DownloadItemInfo downloadInfo) private void tagsLabel_Click(object sender, EventArgs e) { - if (this.Height == 533) + + if (this.Height == 610) { - //New Height - this.Height = 660; + // New Height + this.Height = 750; tagsLabel.Text = "🠉 Choose which tags to save (click me) 🠉"; } - else if (this.Height == 660) + else if (this.Height == 750) { - //New Height - this.Height = 533; + // New Height + this.Height = 610; tagsLabel.Text = "🠋 Choose which tags to save (click me) 🠋"; } + + Debug.WriteLine($"After setting Height: {this.Height}"); } private void AlbumCheckbox_CheckedChanged(object sender, EventArgs e) @@ -903,7 +970,36 @@ private void enableBtnsButton_Click(object sender, EventArgs e) private void StreamableCheckbox_CheckedChanged(object sender, EventArgs e) { - downloadManager.CheckIfStreamable = streamableCheckbox.Checked; + // Not implemented + } + + private void stopButton_Click(object sender, EventArgs e) + { + if (downloadUrl.Text == "cancel") + { + _requests.Cancel(); + output.AppendText("Canceling all downloads.\r\n"); + _requests = new(); + } + else if (string.IsNullOrWhiteSpace(downloadUrl.Text)) + { + _requests.Pause(); + output.AppendText("Pausing all downloads.\r\n"); + } + else + { + var request = _requests.FirstOrDefault(x => x.StartOptions.DownloadItem.Url == downloadUrl.Text); + if (request != null) + { + request.Pause(); + output.AppendText($"Pausing download for URL: {downloadUrl.Text}\r\n"); + } + else + { + output.AppendText($"No active download found to pause URL: {downloadUrl.Text}\r\n"); + } + } } + } } \ No newline at end of file diff --git a/QobuzDownloaderX/View/MainForm.resx b/QobuzDownloaderX/View/MainForm.resx index c95290d..0fb35b9 100644 --- a/QobuzDownloaderX/View/MainForm.resx +++ b/QobuzDownloaderX/View/MainForm.resx @@ -1,17 +1,17 @@  - diff --git a/QobuzDownloaderX/View/SearchForm.Designer.cs b/QobuzDownloaderX/View/SearchForm.Designer.cs index 519f848..0291ebe 100644 --- a/QobuzDownloaderX/View/SearchForm.Designer.cs +++ b/QobuzDownloaderX/View/SearchForm.Designer.cs @@ -1,4 +1,7 @@ -namespace QobuzDownloaderX +using System.Drawing; +using System.Windows.Forms; + +namespace QobuzDownloaderX { partial class SearchForm { @@ -29,126 +32,149 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SearchForm)); - this.searchInput = new System.Windows.Forms.TextBox(); - this.searchButton = new System.Windows.Forms.Button(); - this.panel1 = new System.Windows.Forms.Panel(); - this.exitLabel = new System.Windows.Forms.Label(); - this.logoPictureBox = new System.Windows.Forms.PictureBox(); - this.containerScrollPanel = new System.Windows.Forms.Panel(); - this.searchTypeSelect = new System.Windows.Forms.ComboBox(); - ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit(); - this.SuspendLayout(); + searchInput = new TextBox(); + searchButton = new Button(); + panel1 = new Panel(); + exitLabel = new Label(); + logoPictureBox = new PictureBox(); + containerScrollPanel = new Panel(); + downloadAllButton = new Button(); + searchTypeSelect = new ComboBox(); + ((System.ComponentModel.ISupportInitialize)logoPictureBox).BeginInit(); + SuspendLayout(); // // searchInput // - this.searchInput.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.searchInput.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.searchInput.ForeColor = System.Drawing.Color.White; - this.searchInput.Location = new System.Drawing.Point(118, 45); - this.searchInput.Multiline = true; - this.searchInput.Name = "searchInput"; - this.searchInput.Size = new System.Drawing.Size(682, 20); - this.searchInput.TabIndex = 0; - this.searchInput.WordWrap = false; - this.searchInput.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SearchInput_KeyDown); + searchInput.BackColor = Color.FromArgb(20, 20, 20); + searchInput.BorderStyle = BorderStyle.None; + searchInput.ForeColor = Color.White; + searchInput.Location = new Point(157, 69); + searchInput.Margin = new Padding(4, 5, 4, 5); + searchInput.Multiline = true; + searchInput.Name = "searchInput"; + searchInput.Size = new Size(909, 31); + searchInput.TabIndex = 0; + searchInput.WordWrap = false; + searchInput.KeyDown += SearchInput_KeyDown; // // searchButton // - this.searchButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(112)))), ((int)(((byte)(239))))); - this.searchButton.FlatAppearance.BorderSize = 0; - this.searchButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.searchButton.ForeColor = System.Drawing.Color.White; - this.searchButton.Location = new System.Drawing.Point(806, 40); - this.searchButton.Name = "searchButton"; - this.searchButton.Size = new System.Drawing.Size(120, 23); - this.searchButton.TabIndex = 1; - this.searchButton.Text = "Search"; - this.searchButton.UseVisualStyleBackColor = false; - this.searchButton.Click += new System.EventHandler(this.SearchButton_Click); + searchButton.BackColor = Color.FromArgb(0, 112, 239); + searchButton.FlatAppearance.BorderSize = 0; + searchButton.FlatStyle = FlatStyle.Flat; + searchButton.ForeColor = Color.White; + searchButton.Location = new Point(1075, 62); + searchButton.Margin = new Padding(4, 5, 4, 5); + searchButton.Name = "searchButton"; + searchButton.Size = new Size(160, 35); + searchButton.TabIndex = 1; + searchButton.Text = "Search"; + searchButton.UseVisualStyleBackColor = false; + searchButton.Click += SearchButton_Click; // // panel1 // - this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(88)))), ((int)(((byte)(92)))), ((int)(((byte)(102))))); - this.panel1.Location = new System.Drawing.Point(118, 63); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(680, 1); - this.panel1.TabIndex = 87; + panel1.BackColor = Color.FromArgb(88, 92, 102); + panel1.Location = new Point(157, 97); + panel1.Margin = new Padding(4, 5, 4, 5); + panel1.Name = "panel1"; + panel1.Size = new Size(907, 2); + panel1.TabIndex = 87; // // exitLabel // - this.exitLabel.AutoSize = true; - this.exitLabel.BackColor = System.Drawing.Color.Transparent; - this.exitLabel.Font = new System.Drawing.Font("Calibri", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.exitLabel.ForeColor = System.Drawing.Color.White; - this.exitLabel.Location = new System.Drawing.Point(906, 8); - this.exitLabel.Name = "exitLabel"; - this.exitLabel.Size = new System.Drawing.Size(20, 23); - this.exitLabel.TabIndex = 89; - this.exitLabel.Text = "X"; - this.exitLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.exitLabel.Click += new System.EventHandler(this.ExitLabel_Click); - this.exitLabel.MouseLeave += new System.EventHandler(this.ExitLabel_MouseLeave); - this.exitLabel.MouseHover += new System.EventHandler(this.ExitLabel_MouseHover); + exitLabel.AutoSize = true; + exitLabel.BackColor = Color.Transparent; + exitLabel.Font = new Font("Calibri", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 0); + exitLabel.ForeColor = Color.White; + exitLabel.Location = new Point(1208, 12); + exitLabel.Margin = new Padding(4, 0, 4, 0); + exitLabel.Name = "exitLabel"; + exitLabel.Size = new Size(26, 29); + exitLabel.TabIndex = 89; + exitLabel.Text = "X"; + exitLabel.TextAlign = ContentAlignment.TopCenter; + exitLabel.Click += ExitLabel_Click; + exitLabel.MouseLeave += ExitLabel_MouseLeave; + exitLabel.MouseHover += ExitLabel_MouseHover; // // logoPictureBox // - this.logoPictureBox.BackColor = System.Drawing.Color.Transparent; - this.logoPictureBox.Image = global::QobuzDownloaderX.Properties.Resources.qbdlx_white; - this.logoPictureBox.Location = new System.Drawing.Point(12, 9); - this.logoPictureBox.Name = "logoPictureBox"; - this.logoPictureBox.Size = new System.Drawing.Size(105, 26); - this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; - this.logoPictureBox.TabIndex = 90; - this.logoPictureBox.TabStop = false; + logoPictureBox.BackColor = Color.Transparent; + logoPictureBox.Image = Properties.Resources.qbdlx_white; + logoPictureBox.Location = new Point(16, 14); + logoPictureBox.Margin = new Padding(4, 5, 4, 5); + logoPictureBox.Name = "logoPictureBox"; + logoPictureBox.Size = new Size(140, 40); + logoPictureBox.SizeMode = PictureBoxSizeMode.StretchImage; + logoPictureBox.TabIndex = 90; + logoPictureBox.TabStop = false; // // containerScrollPanel // - this.containerScrollPanel.AutoScroll = true; - this.containerScrollPanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(33)))), ((int)(((byte)(33)))), ((int)(((byte)(33))))); - this.containerScrollPanel.Location = new System.Drawing.Point(12, 70); - this.containerScrollPanel.Name = "containerScrollPanel"; - this.containerScrollPanel.Size = new System.Drawing.Size(914, 451); - this.containerScrollPanel.TabIndex = 4; + containerScrollPanel.AutoScroll = true; + containerScrollPanel.BackColor = Color.FromArgb(33, 33, 33); + containerScrollPanel.Location = new Point(16, 108); + containerScrollPanel.Margin = new Padding(4, 5, 4, 5); + containerScrollPanel.Name = "containerScrollPanel"; + containerScrollPanel.Size = new Size(1219, 694); + containerScrollPanel.TabIndex = 4; + // + // downloadAllButton + // + downloadAllButton.BackColor = Color.FromArgb(0, 202, 255); + downloadAllButton.Enabled = false; + downloadAllButton.FlatAppearance.BorderSize = 0; + downloadAllButton.FlatStyle = FlatStyle.Flat; + downloadAllButton.ForeColor = Color.White; + downloadAllButton.Location = new Point(1075, 19); + downloadAllButton.Margin = new Padding(4, 5, 4, 5); + downloadAllButton.Name = "downloadAllButton"; + downloadAllButton.Size = new Size(112, 35); + downloadAllButton.TabIndex = 91; + downloadAllButton.Text = "Download All"; + downloadAllButton.UseVisualStyleBackColor = false; + downloadAllButton.Visible = false; + downloadAllButton.Click += DownloadAllButton_Click; // // searchTypeSelect // - this.searchTypeSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.searchTypeSelect.FormattingEnabled = true; - this.searchTypeSelect.Items.AddRange(new object[] { - "Album", - "Track"}); - this.searchTypeSelect.Location = new System.Drawing.Point(12, 43); - this.searchTypeSelect.Name = "searchTypeSelect"; - this.searchTypeSelect.Size = new System.Drawing.Size(100, 21); - this.searchTypeSelect.TabIndex = 3; + searchTypeSelect.DropDownStyle = ComboBoxStyle.DropDownList; + searchTypeSelect.FormattingEnabled = true; + searchTypeSelect.Items.AddRange(new object[] { "Album", "Track" }); + searchTypeSelect.Location = new Point(16, 66); + searchTypeSelect.Margin = new Padding(4, 5, 4, 5); + searchTypeSelect.Name = "searchTypeSelect"; + searchTypeSelect.Size = new Size(132, 28); + searchTypeSelect.TabIndex = 3; // // SearchForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); - this.ClientSize = new System.Drawing.Size(938, 533); - this.Controls.Add(this.exitLabel); - this.Controls.Add(this.searchTypeSelect); - this.Controls.Add(this.containerScrollPanel); - this.Controls.Add(this.logoPictureBox); - this.Controls.Add(this.panel1); - this.Controls.Add(this.searchButton); - this.Controls.Add(this.searchInput); - this.Cursor = System.Windows.Forms.Cursors.Default; - this.DoubleBuffered = true; - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "SearchForm"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; - this.Text = "QobuzDLX | Search"; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SearchForm_FormClosed); - this.Load += new System.EventHandler(this.SearchForm_Load); - this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.SearchForm_MouseMove); - ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + BackColor = Color.FromArgb(20, 20, 20); + ClientSize = new Size(1251, 820); + Controls.Add(downloadAllButton); + Controls.Add(exitLabel); + Controls.Add(searchTypeSelect); + Controls.Add(containerScrollPanel); + Controls.Add(logoPictureBox); + Controls.Add(panel1); + Controls.Add(searchButton); + Controls.Add(searchInput); + DoubleBuffered = true; + FormBorderStyle = FormBorderStyle.None; + Icon = (Icon)resources.GetObject("$this.Icon"); + Margin = new Padding(4, 5, 4, 5); + Name = "SearchForm"; + StartPosition = FormStartPosition.CenterParent; + Text = "QobuzDLX | Search"; + FormClosed += SearchForm_FormClosed; + Load += SearchForm_Load; + MouseMove += SearchForm_MouseMove; + ((System.ComponentModel.ISupportInitialize)logoPictureBox).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -160,5 +186,6 @@ private void InitializeComponent() private System.Windows.Forms.PictureBox logoPictureBox; private System.Windows.Forms.Panel containerScrollPanel; private System.Windows.Forms.ComboBox searchTypeSelect; + private Button downloadAllButton; } } \ No newline at end of file diff --git a/QobuzDownloaderX/View/SearchForm.cs b/QobuzDownloaderX/View/SearchForm.cs index fca59d1..c787847 100644 --- a/QobuzDownloaderX/View/SearchForm.cs +++ b/QobuzDownloaderX/View/SearchForm.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.Drawing; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -34,6 +35,38 @@ public SearchForm() searchTypeSelect.SelectedItem = "Album"; } + private void DownloadAllButton_Click(object sender, EventArgs e) + { + try + { + downloadAllButton.Enabled = false; + List downloadLinks = []; + for (int row = 0; row < resultsTableLayoutPanel.RowCount; row++) + { + if (resultsTableLayoutPanel.GetControlFromPosition(3, row) is Button downloadButton) + { + // Get the download link from the button's Tag property + string downloadLink = downloadButton.Tag?.ToString(); + if (!string.IsNullOrEmpty(downloadLink)) + downloadLinks.Add(downloadLink); + } + } + Globals.QbdlxForm.downloadUrl.Invoke(new Action(() => Globals.QbdlxForm.downloadUrl.Text = downloadLinks.FirstOrDefault())); + this.Close(); + Globals.QbdlxForm.StartLinkItemDownload([.. downloadLinks]); + } + catch (Exception ex) + { + List errorLines = ["Error starting download for all items", ex.ToString(), ""]; + System.IO.File.AppendAllLines(errorLog, errorLines); + MessageBox.Show("Error starting download for all items\nlog saved to " + errorLog, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + downloadAllButton.Enabled = true; + } + } + private void ResetResultsTableLayoutPanel() { if (resultsTableLayoutPanel != null) @@ -61,6 +94,8 @@ private void ResetResultsTableLayoutPanel() resultsTableLayoutPanel.CellPaint += ResultsTableLayoutPanel_CellPaint; containerScrollPanel.Controls.Add(resultsTableLayoutPanel); + downloadAllButton.Visible = false; + downloadAllButton.Enabled = false; } private void ShowAndLogSearchResultError(Exception ex) @@ -133,6 +168,12 @@ private void Fill_AlbumResultsTablePanel(SearchResult searchResult) HiRes = album.Hires.GetValueOrDefault(), TrackCount = album.TracksCount.GetValueOrDefault() }); + // Show and enable the "Download All" button if there are rows + if (resultsTableLayoutPanel.RowCount > 0) + { + downloadAllButton.Visible = true; + downloadAllButton.Enabled = true; + } } private void Fill_TrackResultsTablePanel(SearchResult searchResult) @@ -150,6 +191,12 @@ private void Fill_TrackResultsTablePanel(SearchResult searchResult) ReleaseDate = track.Album.ReleaseDateOriginal.GetValueOrDefault().ToString("yyyy-MM-dd"), HiRes = track.Hires.GetValueOrDefault() }); + // Show and enable the "Download All" button if there are rows + if (resultsTableLayoutPanel.RowCount > 0) + { + downloadAllButton.Visible = true; + downloadAllButton.Enabled = true; + } } private void FillResultsTablePanel(IEnumerable items, Func createSearchResultRow) @@ -259,7 +306,7 @@ private FlowLayoutPanel CreateTitlePanel(TextBox titleTextBox, bool isExplicit) if (isExplicit) { System.Windows.Forms.Label explicitLabel = CreateLabel("E", Color.FromArgb(75, 75, 75), Color.OrangeRed, FontManager.CreateFont("Hanken Grotesk ExtraBold", 8, FontStyle.Bold), BorderStyle.None, new Padding(5, 0, 0, 0), AnchorStyles.None); - + // Add tooltip for "Explicit" ToolTip toolTip = new ToolTip(); toolTip.SetToolTip(explicitLabel, "Explicit"); @@ -365,6 +412,7 @@ private Button CreateDownloadButton(string webPlayerUrl) UseVisualStyleBackColor = false, Height = 23, Anchor = AnchorStyles.None, + Tag = webPlayerUrl, TextAlign = ContentAlignment.MiddleCenter }; downloadButton.FlatAppearance.BorderSize = 0; @@ -384,7 +432,7 @@ private async Task HandleDownloadAsync(string webPlayerUrl) Globals.QbdlxForm.downloadUrl.Invoke(new Action(() => Globals.QbdlxForm.downloadUrl.Text = webPlayerUrl)); this.Close(); // Start download from the main form - await Globals.QbdlxForm.StartLinkItemDownloadAsync(webPlayerUrl); + Globals.QbdlxForm.StartLinkItemDownload(webPlayerUrl); } catch (Exception ex) { @@ -469,11 +517,11 @@ private void AddLinkLabelFunctionality(LinkLabel linkLabel) toolTip.SetToolTip(linkLabel, url); // Add context menu with "Copy URL" option - ContextMenu contextMenu = new ContextMenu(); - MenuItem copyUrlItem = new MenuItem("Copy URL"); + ContextMenuStrip contextMenu = new ContextMenuStrip(); + ToolStripMenuItem copyUrlItem = new ToolStripMenuItem("Copy URL"); copyUrlItem.Click += (sender, e) => CopyToClipboard(url); - contextMenu.MenuItems.Add(copyUrlItem); - linkLabel.ContextMenu = contextMenu; + contextMenu.Items.Add(copyUrlItem); + linkLabel.ContextMenuStrip = contextMenu; } private void ResizeControlForText(Control control, int extraMargin = 0, int fixedWidth = 0) diff --git a/QobuzDownloaderX/View/SearchForm.resx b/QobuzDownloaderX/View/SearchForm.resx index 6eac24d..ce3b5af 100644 --- a/QobuzDownloaderX/View/SearchForm.resx +++ b/QobuzDownloaderX/View/SearchForm.resx @@ -1,17 +1,17 @@  -