diff --git a/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs b/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs deleted file mode 100644 index 03f5ba05..00000000 --- a/Source/LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Windows.Forms; -using DataLayer; -using Dinah.Core.Net.Http; -using Dinah.Core.Threading; -using FileLiberator; - -namespace LibationWinForms.BookLiberation.BaseForms -{ - public class LiberationBaseForm : Form - { - protected Streamable Streamable { get; private set; } - protected LogMe LogMe { get; private set; } - private SynchronizeInvoker Invoker { get; init; } - - public LiberationBaseForm() - { - //SynchronizationContext.Current will be null until the process contains a Form. - //If this is the first form created, it will not exist until after execution - //reaches inside the constructor (after base class has been initialized). - Invoker = new SynchronizeInvoker(); - this.SetLibationIcon(); - } - - public void RegisterFileLiberator(Streamable streamable, LogMe logMe = null) - { - if (streamable is null) return; - - Streamable = streamable; - LogMe = logMe; - - Subscribe(streamable); - - if (Streamable is Processable processable) - Subscribe(processable); - if (Streamable is AudioDecodable audioDecodable) - Subscribe(audioDecodable); - } - - #region Event Subscribers and Unsubscribers - private void Subscribe(Streamable streamable) - { - UnsubscribeStreamable(this, EventArgs.Empty); - - streamable.StreamingBegin += OnStreamingBeginShow; - streamable.StreamingBegin += Streamable_StreamingBegin; - streamable.StreamingProgressChanged += Streamable_StreamingProgressChanged; - streamable.StreamingTimeRemaining += Streamable_StreamingTimeRemaining; - streamable.StreamingCompleted += Streamable_StreamingCompleted; - streamable.StreamingCompleted += OnStreamingCompletedClose; - - Disposed += UnsubscribeStreamable; - } - private void Subscribe(Processable processable) - { - UnsubscribeProcessable(this, null); - - processable.Begin += Processable_Begin; - processable.StatusUpdate += Processable_StatusUpdate; - processable.Completed += Processable_Completed; - - //The form is created on Processable.Begin and we - //dispose of it on Processable.Completed - processable.Completed += OnCompletedDispose; - - //Don't unsubscribe from Dispose because it fires when - //Streamable.StreamingCompleted closes the form, and - //the Processable events need to live past that event. - processable.Completed += UnsubscribeProcessable; - } - private void Subscribe(AudioDecodable audioDecodable) - { - UnsubscribeAudioDecodable(this, EventArgs.Empty); - - audioDecodable.RequestCoverArt += AudioDecodable_RequestCoverArt; - audioDecodable.TitleDiscovered += AudioDecodable_TitleDiscovered; - audioDecodable.AuthorsDiscovered += AudioDecodable_AuthorsDiscovered; - audioDecodable.NarratorsDiscovered += AudioDecodable_NarratorsDiscovered; - audioDecodable.CoverImageDiscovered += AudioDecodable_CoverImageDiscovered; - - Disposed += UnsubscribeAudioDecodable; - } - private void UnsubscribeStreamable(object sender, EventArgs e) - { - Disposed -= UnsubscribeStreamable; - - Streamable.StreamingBegin -= OnStreamingBeginShow; - Streamable.StreamingBegin -= Streamable_StreamingBegin; - Streamable.StreamingProgressChanged -= Streamable_StreamingProgressChanged; - Streamable.StreamingTimeRemaining -= Streamable_StreamingTimeRemaining; - Streamable.StreamingCompleted -= Streamable_StreamingCompleted; - Streamable.StreamingCompleted -= OnStreamingCompletedClose; - } - private void UnsubscribeProcessable(object sender, LibraryBook e) - { - if (Streamable is not Processable processable) - return; - - processable.Completed -= UnsubscribeProcessable; - processable.Completed -= OnCompletedDispose; - processable.Completed -= Processable_Completed; - processable.StatusUpdate -= Processable_StatusUpdate; - processable.Begin -= Processable_Begin; - } - private void UnsubscribeAudioDecodable(object sender, EventArgs e) - { - if (Streamable is not AudioDecodable audioDecodable) - return; - - Disposed -= UnsubscribeAudioDecodable; - audioDecodable.RequestCoverArt -= AudioDecodable_RequestCoverArt; - audioDecodable.TitleDiscovered -= AudioDecodable_TitleDiscovered; - audioDecodable.AuthorsDiscovered -= AudioDecodable_AuthorsDiscovered; - audioDecodable.NarratorsDiscovered -= AudioDecodable_NarratorsDiscovered; - audioDecodable.CoverImageDiscovered -= AudioDecodable_CoverImageDiscovered; - - audioDecodable.Cancel(); - } - #endregion - - #region Form creation and disposal handling - - /// - /// If the form was shown using Show (not ShowDialog), Form.Close calls Form.Dispose - /// - private void OnStreamingCompletedClose(object sender, string completedString) => this.UIThreadAsync(Close); - private void OnCompletedDispose(object sender, LibraryBook e) => this.UIThreadAsync(Dispose); - - /// - /// If StreamingBegin is fired from a worker thread, the window will be created on that - /// worker thread. We need to make certain that we show the window on the UI thread (same - /// thread that created form), otherwise the renderer will be on a worker thread which - /// could cause it to freeze. Form.BeginInvoke won't work until the form is created - /// (ie. shown) because Control doesn't get a window handle until it is Shown. - /// - private void OnStreamingBeginShow(object sender, string beginString) => Invoker.UIThreadAsync(Show); - - #endregion - - #region Streamable event handlers - public virtual void Streamable_StreamingBegin(object sender, string beginString) { } - public virtual void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress) { } - public virtual void Streamable_StreamingTimeRemaining(object sender, TimeSpan timeRemaining) { } - public virtual void Streamable_StreamingCompleted(object sender, string completedString) { } - - #endregion - - #region Processable event handlers - public virtual void Processable_Begin(object sender, LibraryBook libraryBook) { } - public virtual void Processable_StatusUpdate(object sender, string statusUpdate) { } - public virtual void Processable_Completed(object sender, LibraryBook libraryBook) { } - - #endregion - - #region AudioDecodable event handlers - public virtual void AudioDecodable_TitleDiscovered(object sender, string title) { } - public virtual void AudioDecodable_AuthorsDiscovered(object sender, string authors) { } - public virtual void AudioDecodable_NarratorsDiscovered(object sender, string narrators) { } - - public virtual void AudioDecodable_CoverImageDiscovered(object sender, byte[] coverArt) { } - public virtual void AudioDecodable_RequestCoverArt(object sender, Action setCoverArtDelegate) { } - #endregion - } -} diff --git a/Source/LibationWinForms/BookLiberation/DownloadForm.cs b/Source/LibationWinForms/BookLiberation/DownloadForm.cs index 3a307476..77d6058f 100644 --- a/Source/LibationWinForms/BookLiberation/DownloadForm.cs +++ b/Source/LibationWinForms/BookLiberation/DownloadForm.cs @@ -2,30 +2,48 @@ using System.Windows.Forms; using Dinah.Core.Net.Http; using Dinah.Core.Threading; -using LibationWinForms.BookLiberation.BaseForms; +using FileLiberator; namespace LibationWinForms.BookLiberation { - public partial class DownloadForm : LiberationBaseForm + public partial class DownloadForm : Form { + protected Streamable Streamable { get; private set; } + protected LogMe LogMe { get; private set; } + private SynchronizeInvoker Invoker { get; init; } + public DownloadForm() { + //SynchronizationContext.Current will be null until the process contains a Form. + //If this is the first form created, it will not exist until after execution + //reaches inside the constructor (after base class has been initialized). + Invoker = new SynchronizeInvoker(); InitializeComponent(); + this.SetLibationIcon(); progressLbl.Text = ""; filenameLbl.Text = ""; } + public void RegisterFileLiberator(Streamable streamable, LogMe logMe = null) + { + if (streamable is null) return; + streamable.StreamingBegin += Streamable_StreamingBegin; + streamable.StreamingProgressChanged += Streamable_StreamingProgressChanged; + streamable.StreamingCompleted += (_, _) => this.UIThreadAsync(Close); + Streamable = streamable; + LogMe = logMe; + } + #region Streamable event handler overrides - public override void Streamable_StreamingBegin(object sender, string beginString) + public void Streamable_StreamingBegin(object sender, string beginString) { - base.Streamable_StreamingBegin(sender, beginString); + Invoker.UIThreadAsync(Show); filenameLbl.UIThreadAsync(() => filenameLbl.Text = beginString); } - public override void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress) + public void Streamable_StreamingProgressChanged(object sender, DownloadProgress downloadProgress) { - base.Streamable_StreamingProgressChanged(sender, downloadProgress); // this won't happen with download file. it will happen with download string if (!downloadProgress.TotalBytesToReceive.HasValue || downloadProgress.TotalBytesToReceive.Value <= 0) return;