Consolidated base forms
This commit is contained in:
parent
2c20d03506
commit
3e2d69606b
4
FileLiberator/IFileLiberator.cs
Normal file
4
FileLiberator/IFileLiberator.cs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
namespace FileLiberator
|
||||||
|
{
|
||||||
|
public interface IFileLiberator { }
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ using Dinah.Core.ErrorHandling;
|
|||||||
|
|
||||||
namespace FileLiberator
|
namespace FileLiberator
|
||||||
{
|
{
|
||||||
public interface IProcessable
|
public interface IProcessable : IFileLiberator
|
||||||
{
|
{
|
||||||
event EventHandler<LibraryBook> Begin;
|
event EventHandler<LibraryBook> Begin;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ using Dinah.Core.Net.Http;
|
|||||||
|
|
||||||
namespace FileLiberator
|
namespace FileLiberator
|
||||||
{
|
{
|
||||||
public interface IStreamable
|
public interface IStreamable : IFileLiberator
|
||||||
{
|
{
|
||||||
event EventHandler<string> StreamingBegin;
|
event EventHandler<string> StreamingBegin;
|
||||||
event EventHandler<DownloadProgress> StreamingProgressChanged;
|
event EventHandler<DownloadProgress> StreamingProgressChanged;
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
<!-- <PublishSingleFile>true</PublishSingleFile> -->
|
<!-- <PublishSingleFile>true</PublishSingleFile> -->
|
||||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||||
|
|
||||||
<Version>5.4.9.274</Version>
|
<Version>5.4.9.279</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|||||||
@ -3,9 +3,9 @@ using System;
|
|||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
class AudioConvertForm : AudioDecodeBaseForm
|
class AudioConvertForm : AudioDecodeForm
|
||||||
{
|
{
|
||||||
#region AudioDecodeBaseForm overrides
|
#region AudioDecodeForm overrides
|
||||||
public override string DecodeActionName => "Converting";
|
public override string DecodeActionName => "Converting";
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
partial class AudioDecodeBaseForm
|
partial class AudioDecodeForm
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
@ -1,15 +1,20 @@
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.Net.Http;
|
using Dinah.Core.Net.Http;
|
||||||
using Dinah.Core.Windows.Forms;
|
using Dinah.Core.Windows.Forms;
|
||||||
using FileLiberator;
|
using LibationWinForms.BookLiberation.BaseForms;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
public partial class AudioDecodeBaseForm : ProcessBaseForm
|
public partial class AudioDecodeForm
|
||||||
|
#if DEBUG
|
||||||
|
: DebugIntermediate
|
||||||
|
#else
|
||||||
|
: LiberationBaseForm
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public virtual string DecodeActionName { get; } = "Decoding";
|
public virtual string DecodeActionName { get; } = "Decoding";
|
||||||
public AudioDecodeBaseForm() => InitializeComponent();
|
public AudioDecodeForm() => InitializeComponent();
|
||||||
|
|
||||||
private Func<byte[]> GetCoverArtDelegate;
|
private Func<byte[]> GetCoverArtDelegate;
|
||||||
|
|
||||||
@ -18,41 +23,6 @@ namespace LibationWinForms.BookLiberation
|
|||||||
private string authorNames;
|
private string authorNames;
|
||||||
private string narratorNames;
|
private string narratorNames;
|
||||||
|
|
||||||
#region ProcessBaseForm overrides
|
|
||||||
public override void SetProcessable(IStreamable streamProcessable, LogMe logMe)
|
|
||||||
{
|
|
||||||
base.SetProcessable(streamProcessable, logMe);
|
|
||||||
|
|
||||||
if (Streamable is not null && Streamable is IAudioDecodable audioDecodable)
|
|
||||||
{
|
|
||||||
OnUnsubscribeAll(this, EventArgs.Empty);
|
|
||||||
|
|
||||||
audioDecodable.RequestCoverArt += OnRequestCoverArt;
|
|
||||||
audioDecodable.TitleDiscovered += OnTitleDiscovered;
|
|
||||||
audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered;
|
|
||||||
audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered;
|
|
||||||
audioDecodable.CoverImageDiscovered += OnCoverImageDiscovered;
|
|
||||||
|
|
||||||
Disposed += OnUnsubscribeAll;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void OnUnsubscribeAll(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
if (Streamable is IAudioDecodable audioDecodable)
|
|
||||||
{
|
|
||||||
Disposed -= OnUnsubscribeAll;
|
|
||||||
audioDecodable.RequestCoverArt -= OnRequestCoverArt;
|
|
||||||
audioDecodable.TitleDiscovered -= OnTitleDiscovered;
|
|
||||||
audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered;
|
|
||||||
audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered;
|
|
||||||
audioDecodable.CoverImageDiscovered -= OnCoverImageDiscovered;
|
|
||||||
|
|
||||||
audioDecodable.Cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IProcessable event handler overrides
|
#region IProcessable event handler overrides
|
||||||
public override void OnBegin(object sender, LibraryBook libraryBook)
|
public override void OnBegin(object sender, LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
@ -74,6 +44,7 @@ namespace LibationWinForms.BookLiberation
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IStreamable event handler overrides
|
#region IStreamable event handler overrides
|
||||||
|
public override void OnStreamingBegin(object sender, string beginString) { }
|
||||||
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress)
|
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress)
|
||||||
{
|
{
|
||||||
if (!downloadProgress.ProgressPercentage.HasValue)
|
if (!downloadProgress.ProgressPercentage.HasValue)
|
||||||
@ -87,32 +58,34 @@ namespace LibationWinForms.BookLiberation
|
|||||||
|
|
||||||
public override void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining)
|
public override void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining)
|
||||||
=> updateRemainingTime((int)timeRemaining.TotalSeconds);
|
=> updateRemainingTime((int)timeRemaining.TotalSeconds);
|
||||||
|
|
||||||
|
public override void OnStreamingCompleted(object sender, string completedString) { }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IAudioDecodable event handlers
|
#region IAudioDecodable event handlers
|
||||||
public virtual void OnRequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate)
|
public override void OnRequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate)
|
||||||
=> setCoverArtDelegate(GetCoverArtDelegate?.Invoke());
|
=> setCoverArtDelegate(GetCoverArtDelegate?.Invoke());
|
||||||
|
|
||||||
public virtual void OnTitleDiscovered(object sender, string title)
|
public override void OnTitleDiscovered(object sender, string title)
|
||||||
{
|
{
|
||||||
this.UIThread(() => this.Text = DecodeActionName + " " + title);
|
this.UIThread(() => this.Text = DecodeActionName + " " + title);
|
||||||
this.title = title;
|
this.title = title;
|
||||||
updateBookInfo();
|
updateBookInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnAuthorsDiscovered(object sender, string authors)
|
public override void OnAuthorsDiscovered(object sender, string authors)
|
||||||
{
|
{
|
||||||
authorNames = authors;
|
authorNames = authors;
|
||||||
updateBookInfo();
|
updateBookInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnNarratorsDiscovered(object sender, string narrators)
|
public override void OnNarratorsDiscovered(object sender, string narrators)
|
||||||
{
|
{
|
||||||
narratorNames = narrators;
|
narratorNames = narrators;
|
||||||
updateBookInfo();
|
updateBookInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt)
|
public override void OnCoverImageDiscovered(object sender, byte[] coverArt)
|
||||||
=> pictureBox1.UIThread(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt));
|
=> pictureBox1.UIThread(() => pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(coverArt));
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -3,9 +3,9 @@ using System;
|
|||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
class AudioDecryptForm : AudioDecodeBaseForm
|
class AudioDecryptForm : AudioDecodeForm
|
||||||
{
|
{
|
||||||
#region AudioDecodeBaseForm overrides
|
#region AudioDecodeForm overrides
|
||||||
public override string DecodeActionName => "Decrypting";
|
public override string DecodeActionName => "Decrypting";
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
189
LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs
Normal file
189
LibationWinForms/BookLiberation/BaseForms/LiberationBaseForm.cs
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
using DataLayer;
|
||||||
|
using Dinah.Core.Net.Http;
|
||||||
|
using Dinah.Core.Windows.Forms;
|
||||||
|
using FileLiberator;
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace LibationWinForms.BookLiberation.BaseForms
|
||||||
|
{
|
||||||
|
public abstract class LiberationBaseForm : Form
|
||||||
|
{
|
||||||
|
protected IFileLiberator Liberation { get; private set; }
|
||||||
|
protected LogMe LogMe { get; private set; }
|
||||||
|
|
||||||
|
private int InstanceThreadId { get; } = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
public new bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
|
||||||
|
private SynchronizationContext SyncContext { get; }
|
||||||
|
|
||||||
|
public LiberationBaseForm()
|
||||||
|
{
|
||||||
|
//Will be null if set outside constructor.
|
||||||
|
SyncContext = SynchronizationContext.Current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterLiberation(IFileLiberator liberation, LogMe logMe = null)
|
||||||
|
{
|
||||||
|
if (liberation is null) return;
|
||||||
|
|
||||||
|
Liberation = liberation;
|
||||||
|
LogMe = logMe;
|
||||||
|
|
||||||
|
if (Liberation is IStreamable streamable)
|
||||||
|
Subscribe(streamable);
|
||||||
|
if (Liberation is IProcessable processable)
|
||||||
|
Subscribe(processable);
|
||||||
|
if (Liberation is IAudioDecodable audioDecodable)
|
||||||
|
Subscribe(audioDecodable);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Event Subscribers and Unsubscribers
|
||||||
|
private void Subscribe(IStreamable streamable)
|
||||||
|
{
|
||||||
|
UnsubscribeStreamable(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
streamable.StreamingBegin += ShowFormHandler;
|
||||||
|
streamable.StreamingBegin += OnStreamingBegin;
|
||||||
|
streamable.StreamingProgressChanged += OnStreamingProgressChanged;
|
||||||
|
streamable.StreamingTimeRemaining += OnStreamingTimeRemaining;
|
||||||
|
streamable.StreamingCompleted += OnStreamingCompleted;
|
||||||
|
streamable.StreamingCompleted += OnStreamingCompletedClose;
|
||||||
|
|
||||||
|
FormClosed += UnsubscribeStreamable;
|
||||||
|
}
|
||||||
|
private void Subscribe(IProcessable processable)
|
||||||
|
{
|
||||||
|
UnsubscribeProcessable(this, null);
|
||||||
|
|
||||||
|
processable.Begin += OnBegin;
|
||||||
|
processable.StatusUpdate += OnStatusUpdate;
|
||||||
|
processable.Completed += OnCompleted;
|
||||||
|
|
||||||
|
//The form is created on IProcessable.Begin and we
|
||||||
|
//dispose of it on IProcessable.Completed
|
||||||
|
processable.Completed += OnCompletedDispose;
|
||||||
|
|
||||||
|
//Don't unsubscribe from Dispose because it fires when
|
||||||
|
//IStreamable.StreamingCompleted closes the form, and
|
||||||
|
//the IProcessable events need to live past that event.
|
||||||
|
processable.Completed += UnsubscribeProcessable;
|
||||||
|
}
|
||||||
|
private void Subscribe(IAudioDecodable audioDecodable)
|
||||||
|
{
|
||||||
|
UnsubscribeAudioDecodable(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
audioDecodable.RequestCoverArt += OnRequestCoverArt;
|
||||||
|
audioDecodable.TitleDiscovered += OnTitleDiscovered;
|
||||||
|
audioDecodable.AuthorsDiscovered += OnAuthorsDiscovered;
|
||||||
|
audioDecodable.NarratorsDiscovered += OnNarratorsDiscovered;
|
||||||
|
audioDecodable.CoverImageDiscovered += OnCoverImageDiscovered;
|
||||||
|
|
||||||
|
Disposed += UnsubscribeAudioDecodable;
|
||||||
|
}
|
||||||
|
private void UnsubscribeStreamable(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Liberation is not IStreamable streamable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FormClosed -= UnsubscribeStreamable;
|
||||||
|
|
||||||
|
streamable.StreamingBegin -= ShowFormHandler;
|
||||||
|
streamable.StreamingBegin -= OnStreamingBegin;
|
||||||
|
streamable.StreamingProgressChanged -= OnStreamingProgressChanged;
|
||||||
|
streamable.StreamingTimeRemaining -= OnStreamingTimeRemaining;
|
||||||
|
streamable.StreamingCompleted -= OnStreamingCompleted;
|
||||||
|
streamable.StreamingCompleted -= OnStreamingCompletedClose;
|
||||||
|
}
|
||||||
|
private void UnsubscribeProcessable(object sender, LibraryBook e)
|
||||||
|
{
|
||||||
|
if (Liberation is not IProcessable processable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
processable.Completed -= UnsubscribeProcessable;
|
||||||
|
processable.Completed -= OnCompletedDispose;
|
||||||
|
processable.Completed -= OnCompleted;
|
||||||
|
processable.StatusUpdate -= OnStatusUpdate;
|
||||||
|
processable.Begin -= OnBegin;
|
||||||
|
}
|
||||||
|
private void UnsubscribeAudioDecodable(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Liberation is not IAudioDecodable audioDecodable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Disposed -= UnsubscribeAudioDecodable;
|
||||||
|
audioDecodable.RequestCoverArt -= OnRequestCoverArt;
|
||||||
|
audioDecodable.TitleDiscovered -= OnTitleDiscovered;
|
||||||
|
audioDecodable.AuthorsDiscovered -= OnAuthorsDiscovered;
|
||||||
|
audioDecodable.NarratorsDiscovered -= OnNarratorsDiscovered;
|
||||||
|
audioDecodable.CoverImageDiscovered -= OnCoverImageDiscovered;
|
||||||
|
|
||||||
|
audioDecodable.Cancel();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Form creation and disposal handling
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the form was shown using Show (not ShowDialog), Form.Close calls Form.Dispose
|
||||||
|
/// </summary>
|
||||||
|
private void OnStreamingCompletedClose(object sender, string completedString) => this.UIThread(() => Close());
|
||||||
|
private void OnCompletedDispose(object sender, LibraryBook e) => this.UIThread(() => Dispose());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If StreamingBegin is fired from a worker thread, the window will be created on
|
||||||
|
/// that UI thread. We need to make certain that we show the window on the same
|
||||||
|
/// thread that created form, otherwise the form and the window handle will be on
|
||||||
|
/// different threads. Form.BeginInvoke won't work until the form is created
|
||||||
|
/// (ie. shown) because control doesn't get a window handle until it is Shown.
|
||||||
|
/// </summary>
|
||||||
|
private void ShowFormHandler(object sender, string beginString)
|
||||||
|
{
|
||||||
|
static void sendCallback(object asyncArgs)
|
||||||
|
{
|
||||||
|
var e = asyncArgs as AsyncCompletedEventArgs;
|
||||||
|
((Action)e.UserState)();
|
||||||
|
}
|
||||||
|
|
||||||
|
Action show = Show;
|
||||||
|
|
||||||
|
if (InvokeRequired)
|
||||||
|
SyncContext.Send(
|
||||||
|
sendCallback,
|
||||||
|
new AsyncCompletedEventArgs(null, false, show));
|
||||||
|
else
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IStreamable event handlers
|
||||||
|
public virtual void OnStreamingBegin(object sender, string beginString) { }
|
||||||
|
public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress){ }
|
||||||
|
public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining){ }
|
||||||
|
public virtual void OnStreamingCompleted(object sender, string completedString){ }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IProcessable event handlers
|
||||||
|
public virtual void OnBegin(object sender, LibraryBook libraryBook){ }
|
||||||
|
public virtual void OnStatusUpdate(object sender, string statusUpdate){ }
|
||||||
|
public virtual void OnCompleted(object sender, LibraryBook libraryBook){ }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IAudioDecodable event handlers
|
||||||
|
public virtual void OnRequestCoverArt(object sender, Action<byte[]> setCoverArtDelegate){ }
|
||||||
|
public virtual void OnTitleDiscovered(object sender, string title){ }
|
||||||
|
public virtual void OnAuthorsDiscovered(object sender, string authors){ }
|
||||||
|
public virtual void OnNarratorsDiscovered(object sender, string narrators){ }
|
||||||
|
public virtual void OnCoverImageDiscovered(object sender, byte[] coverArt){ }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
#region VS Design View Hack
|
||||||
|
/// <summary>
|
||||||
|
/// This class is a hack so that VS designer will work wif an abstract base class.
|
||||||
|
/// https://stackoverflow.com/questions/1620847/how-can-i-get-visual-studio-2008-windows-forms-designer-to-render-a-form-that-im/2406058#2406058
|
||||||
|
/// </summary>
|
||||||
|
public class DebugIntermediate : LiberationBaseForm { }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -1,54 +0,0 @@
|
|||||||
using DataLayer;
|
|
||||||
using Dinah.Core.Windows.Forms;
|
|
||||||
using FileLiberator;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
public class ProcessBaseForm : StreamBaseForm
|
|
||||||
{
|
|
||||||
protected LogMe LogMe { get; private set; }
|
|
||||||
public virtual void SetProcessable(IStreamable streamable, LogMe logMe)
|
|
||||||
{
|
|
||||||
LogMe = logMe;
|
|
||||||
SetStreamable(streamable);
|
|
||||||
|
|
||||||
if (Streamable is not null && Streamable is IProcessable processable)
|
|
||||||
{
|
|
||||||
OnUnsubscribeAll(this, null);
|
|
||||||
|
|
||||||
processable.Begin += OnBegin;
|
|
||||||
processable.Completed += OnCompleted;
|
|
||||||
processable.StatusUpdate += OnStatusUpdate;
|
|
||||||
|
|
||||||
//The form is created on IProcessable.Begin and we
|
|
||||||
//dispose of it on IProcessable.Completed
|
|
||||||
processable.Completed += OnCompletedDispose;
|
|
||||||
|
|
||||||
//Don't unsubscribe from Dispose because it fires when
|
|
||||||
//IStreamable.StreamingCompleted closes the form, and
|
|
||||||
//the IProcessable events need to live past that event.
|
|
||||||
processable.Completed += OnUnsubscribeAll;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void OnCompletedDispose(object sender, LibraryBook e) => this.UIThread(() => Dispose());
|
|
||||||
|
|
||||||
private void OnUnsubscribeAll(object sender, LibraryBook e)
|
|
||||||
{
|
|
||||||
if (Streamable is IProcessable processable)
|
|
||||||
{
|
|
||||||
processable.Completed -= OnUnsubscribeAll;
|
|
||||||
processable.Completed -= OnCompletedDispose;
|
|
||||||
processable.Begin -= OnBegin;
|
|
||||||
processable.Completed -= OnCompleted;
|
|
||||||
processable.StatusUpdate -= OnStatusUpdate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IProcessable event handlers
|
|
||||||
public virtual void OnBegin(object sender, LibraryBook libraryBook) => LogMe.Info($"Begin: {libraryBook.Book}");
|
|
||||||
public virtual void OnStatusUpdate(object sender, string statusUpdate) => LogMe.Info("- " + statusUpdate);
|
|
||||||
public virtual void OnCompleted(object sender, LibraryBook libraryBook) => LogMe.Info($"Completed: {libraryBook.Book}{Environment.NewLine}");
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
using Dinah.Core.Net.Http;
|
|
||||||
using Dinah.Core.Windows.Forms;
|
|
||||||
using FileLiberator;
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
|
||||||
{
|
|
||||||
public class StreamBaseForm : Form
|
|
||||||
{
|
|
||||||
private int InstanceThreadId { get; } = Thread.CurrentThread.ManagedThreadId;
|
|
||||||
public new bool InvokeRequired => Thread.CurrentThread.ManagedThreadId != InstanceThreadId;
|
|
||||||
private SynchronizationContext SyncContext { get; }
|
|
||||||
|
|
||||||
public StreamBaseForm()
|
|
||||||
{
|
|
||||||
//Will be null if set outside constructor.
|
|
||||||
SyncContext = SynchronizationContext.Current;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IStreamable Streamable { get; private set; }
|
|
||||||
public void SetStreamable(IStreamable streamable)
|
|
||||||
{
|
|
||||||
Streamable = streamable;
|
|
||||||
|
|
||||||
if (Streamable is null) return;
|
|
||||||
|
|
||||||
OnUnsubscribeAll(this, EventArgs.Empty);
|
|
||||||
|
|
||||||
Streamable.StreamingBegin += ShowFormHandler;
|
|
||||||
Streamable.StreamingBegin += OnStreamingBegin;
|
|
||||||
Streamable.StreamingProgressChanged += OnStreamingProgressChanged;
|
|
||||||
Streamable.StreamingTimeRemaining += OnStreamingTimeRemaining;
|
|
||||||
Streamable.StreamingCompleted += OnStreamingCompleted;
|
|
||||||
Streamable.StreamingCompleted += CloseFormHandler;
|
|
||||||
|
|
||||||
FormClosed += OnUnsubscribeAll;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUnsubscribeAll(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
FormClosed -= OnUnsubscribeAll;
|
|
||||||
|
|
||||||
Streamable.StreamingBegin -= ShowFormHandler;
|
|
||||||
Streamable.StreamingBegin -= OnStreamingBegin;
|
|
||||||
Streamable.StreamingProgressChanged -= OnStreamingProgressChanged;
|
|
||||||
Streamable.StreamingTimeRemaining -= OnStreamingTimeRemaining;
|
|
||||||
Streamable.StreamingCompleted -= OnStreamingCompleted;
|
|
||||||
Streamable.StreamingCompleted -= CloseFormHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowFormHandler(object sender, string beginString)
|
|
||||||
{
|
|
||||||
//If StreamingBegin is fired from a worker thread, the window will be created on
|
|
||||||
//that UI thread. We need to make certain that we show the window on the same
|
|
||||||
//thread that created form, otherwise the form and the window handle will be on
|
|
||||||
//different threads. Form.BeginInvoke won't work until the form is created
|
|
||||||
//(ie. shown) because control doesn't get a window handle until it is Shown.
|
|
||||||
static void sendCallback(object asyncArgs)
|
|
||||||
{
|
|
||||||
var e = asyncArgs as AsyncCompletedEventArgs;
|
|
||||||
((Action)e.UserState)();
|
|
||||||
}
|
|
||||||
|
|
||||||
Action show = Show;
|
|
||||||
|
|
||||||
if (InvokeRequired)
|
|
||||||
SyncContext.Send(
|
|
||||||
sendCallback,
|
|
||||||
new AsyncCompletedEventArgs(null, false, show));
|
|
||||||
else
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If the form was shown using Show (not ShowDialog), Form.Close calls Form.Dispose
|
|
||||||
/// </summary>
|
|
||||||
private void CloseFormHandler(object sender, string completedString) => this.UIThread(() => Close());
|
|
||||||
|
|
||||||
|
|
||||||
#region IStreamable event handlers
|
|
||||||
public virtual void OnStreamingBegin(object sender, string beginString) { }
|
|
||||||
public virtual void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress) { }
|
|
||||||
public virtual void OnStreamingTimeRemaining(object sender, TimeSpan timeRemaining) { }
|
|
||||||
public virtual void OnStreamingCompleted(object sender, string completedString) { }
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
</root>
|
|
||||||
@ -1,4 +1,7 @@
|
|||||||
namespace LibationWinForms.BookLiberation
|
using DataLayer;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
partial class DownloadForm
|
partial class DownloadForm
|
||||||
{
|
{
|
||||||
@ -95,9 +98,10 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private System.Windows.Forms.Label filenameLbl;
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Label filenameLbl;
|
||||||
private System.Windows.Forms.ProgressBar progressBar1;
|
private System.Windows.Forms.ProgressBar progressBar1;
|
||||||
private System.Windows.Forms.Label progressLbl;
|
private System.Windows.Forms.Label progressLbl;
|
||||||
private System.Windows.Forms.Label lastUpdateLbl;
|
private System.Windows.Forms.Label lastUpdateLbl;
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
using DataLayer;
|
using Dinah.Core.Net.Http;
|
||||||
using Dinah.Core.Net.Http;
|
|
||||||
using Dinah.Core.Windows.Forms;
|
using Dinah.Core.Windows.Forms;
|
||||||
|
using LibationWinForms.BookLiberation.BaseForms;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace LibationWinForms.BookLiberation
|
namespace LibationWinForms.BookLiberation
|
||||||
{
|
{
|
||||||
public partial class DownloadForm : ProcessBaseForm
|
public partial class DownloadForm
|
||||||
|
#if DEBUG
|
||||||
|
: DebugIntermediate
|
||||||
|
#else
|
||||||
|
: LiberationBaseForm
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public DownloadForm()
|
public DownloadForm()
|
||||||
{
|
{
|
||||||
@ -17,11 +22,11 @@ namespace LibationWinForms.BookLiberation
|
|||||||
filenameLbl.Text = "";
|
filenameLbl.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region IStreamable event handler overrides
|
#region IStreamable event handler overrides
|
||||||
public override void OnStreamingBegin(object sender, string beginString)
|
public override void OnStreamingBegin(object sender, string beginString)
|
||||||
{
|
{
|
||||||
filenameLbl.UIThread(() => filenameLbl.Text = beginString);
|
filenameLbl.UIThread(() => filenameLbl.Text = beginString);
|
||||||
base.OnStreamingBegin(sender, beginString);
|
|
||||||
}
|
}
|
||||||
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress)
|
public override void OnStreamingProgressChanged(object sender, DownloadProgress downloadProgress)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
using FileLiberator;
|
using FileLiberator;
|
||||||
|
using LibationWinForms.BookLiberation.BaseForms;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -126,15 +127,15 @@ namespace LibationWinForms.BookLiberation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="IStreamProcessable"/> and links it to a new <see cref="ProcessBaseForm"/>.
|
/// Create a new <see cref="IStreamProcessable"/> and links it to a new <see cref="LiberationBaseForm"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TStrProc">The <see cref="IStreamProcessable"/> derrived type to create.</typeparam>
|
/// <typeparam name="TStrProc">The <see cref="IStreamProcessable"/> derrived type to create.</typeparam>
|
||||||
/// <typeparam name="TForm">The <see cref="ProcessBaseForm"/> derrived Form to create on <see cref="IProcessable.Begin"/>, Show on <see cref="IStreamable.StreamingBegin"/>, and Close & Dispose on <see cref="IStreamable.StreamingCompleted"/></typeparam>
|
/// <typeparam name="TForm">The <see cref="LiberationBaseForm"/> derrived Form to create on <see cref="IProcessable.Begin"/>, Show on <see cref="IStreamable.StreamingBegin"/>, Close on <see cref="IStreamable.StreamingCompleted"/>, and Dispose on <see cref="IProcessable.Completed"/> </typeparam>
|
||||||
/// <param name="logMe">The logger</param>
|
/// <param name="logMe">The logger</param>
|
||||||
/// <param name="completedAction">An additional event handler to handle <see cref="IProcessable.Completed"/></param>
|
/// <param name="completedAction">An additional event handler to handle <see cref="IProcessable.Completed"/></param>
|
||||||
/// <returns>A new <see cref="IStreamProcessable"/> of type <typeparamref name="TStrProc"/></returns>
|
/// <returns>A new <see cref="IStreamProcessable"/> of type <typeparamref name="TStrProc"/></returns>
|
||||||
private static TStrProc CreateStreamProcessable<TStrProc, TForm>(LogMe logMe, EventHandler<LibraryBook> completedAction = null)
|
private static TStrProc CreateStreamProcessable<TStrProc, TForm>(LogMe logMe, EventHandler<LibraryBook> completedAction = null)
|
||||||
where TForm : ProcessBaseForm, new()
|
where TForm : LiberationBaseForm, new()
|
||||||
where TStrProc : IStreamProcessable, new()
|
where TStrProc : IStreamProcessable, new()
|
||||||
{
|
{
|
||||||
var strProc = new TStrProc();
|
var strProc = new TStrProc();
|
||||||
@ -142,7 +143,7 @@ namespace LibationWinForms.BookLiberation
|
|||||||
strProc.Begin += (sender, libraryBook) =>
|
strProc.Begin += (sender, libraryBook) =>
|
||||||
{
|
{
|
||||||
var processForm = new TForm();
|
var processForm = new TForm();
|
||||||
processForm.SetProcessable(strProc, logMe);
|
processForm.RegisterLiberation(strProc, logMe);
|
||||||
processForm.OnBegin(sender, libraryBook);
|
processForm.OnBegin(sender, libraryBook);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,20 +154,20 @@ namespace LibationWinForms.BookLiberation
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="IStreamable"/> and links it to a new <see cref="StreamBaseForm"/>
|
/// Creates a new <see cref="IStreamable"/> and links it to a new <see cref="LiberationBaseForm"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TStr">The <see cref="IStreamable"/> derrived type to create.</typeparam>
|
/// <typeparam name="TStr">The <see cref="IStreamable"/> derrived type to create.</typeparam>
|
||||||
/// <typeparam name="TForm">The <see cref="StreamBaseForm"/> derrived Form to create, which will Show on <see cref="IStreamable.StreamingBegin"/> and Close & Dispose on <see cref="IStreamable.StreamingCompleted"/>.</typeparam>
|
/// <typeparam name="TForm">The <see cref="LiberationBaseForm"/> derrived Form to create, which will Show on <see cref="IStreamable.StreamingBegin"/> and Close, Dispose on <see cref="IStreamable.StreamingCompleted"/>.</typeparam>
|
||||||
/// <param name="completedAction">An additional event handler to handle <see cref="IStreamable.StreamingCompleted"/></param>
|
/// <param name="completedAction">An additional event handler to handle <see cref="IStreamable.StreamingCompleted"/></param>
|
||||||
/// <returns>A new <see cref="IStreamable"/> of type <typeparamref name="TStr"/></returns>
|
/// <returns>A new <see cref="IStreamable"/> of type <typeparamref name="TStr"/></returns>
|
||||||
private static TStr CreateStreamable<TStr, TForm>(EventHandler<string> completedAction = null)
|
private static TStr CreateStreamable<TStr, TForm>(EventHandler<string> completedAction = null)
|
||||||
where TForm : StreamBaseForm, new()
|
where TForm : LiberationBaseForm, new()
|
||||||
where TStr : IStreamable, new()
|
where TStr : IStreamable, new()
|
||||||
{
|
{
|
||||||
var streamable = new TStr();
|
var streamable = new TStr();
|
||||||
|
|
||||||
var streamForm = new TForm();
|
var streamForm = new TForm();
|
||||||
streamForm.SetStreamable(streamable);
|
streamForm.RegisterLiberation(streamable);
|
||||||
|
|
||||||
if (completedAction != null)
|
if (completedAction != null)
|
||||||
streamable.StreamingCompleted += completedAction;
|
streamable.StreamingCompleted += completedAction;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user