diff options
author | sr55 <[email protected]> | 2012-06-30 14:07:50 +0000 |
---|---|---|
committer | sr55 <[email protected]> | 2012-06-30 14:07:50 +0000 |
commit | ca023df6b2119d7bf29ade5c07f644fdf2de8731 (patch) | |
tree | 6ac3b68670cc9db3876c18239d56f0461ae7953b | |
parent | 4d6d9e007cbfadd9f63860038a8048a2c8da390a (diff) |
WinGui: Refactor the Update service and add a new options tab to deal with updates.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4799 b64f7644-9d1e-0410-96f1-a4d463321fa5
14 files changed, 584 insertions, 330 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj index 865a24b9a..7fa820e4c 100644 --- a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj +++ b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj @@ -117,8 +117,6 @@ <Compile Include="Model\EncodeTask.cs" />
<Compile Include="Model\Encoding\OutputFormat.cs" />
<Compile Include="Model\Encoding\SubtitleTrack.cs" />
- <Compile Include="Model\General\UpdateCheckInformation.cs" />
- <Compile Include="Model\General\UpdateCheckResult.cs" />
<Compile Include="Model\Preset.cs" />
<Compile Include="Model\PresetPictureSettingsMode.cs" />
<Compile Include="Model\QueueItemStatus.cs" />
@@ -152,7 +150,6 @@ <Compile Include="Services\QueueManager.cs" />
<Compile Include="Services\QueueProcessor.cs" />
<Compile Include="Services\ScanService.cs" />
- <Compile Include="Services\UpdateService.cs" />
<Compile Include="Services\UserSettingService.cs" />
<Compile Include="ASUserSettingConstants.cs" />
<Compile Include="Utilities\AppcastReader.cs" />
diff --git a/win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckResult.cs b/win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckResult.cs deleted file mode 100644 index f29cc8560..000000000 --- a/win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckResult.cs +++ /dev/null @@ -1,78 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="UpdateCheckResult.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// Used in EndUpdateCheck() for update checking and the IAsyncResult design pattern.
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrake.ApplicationServices.Model.General
-{
- using System;
- using System.Threading;
-
- /// <summary>
- /// Used in EndUpdateCheck() for update checking and the IAsyncResult design pattern.
- /// </summary>
- public class UpdateCheckResult : IAsyncResult
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="UpdateCheckResult"/> class.
- /// </summary>
- /// <param name="asyncState">
- /// The async state.
- /// </param>
- /// <param name="info">
- /// The info.
- /// </param>
- public UpdateCheckResult(object asyncState, UpdateCheckInformation info)
- {
- this.AsyncState = asyncState;
- this.Result = info;
- }
-
- /// <summary>
- /// Gets whether the check was executed in debug mode.
- /// </summary>
- public object AsyncState { get; private set; }
-
- /// <summary>
- /// Gets the result of the update check.
- /// </summary>
- public UpdateCheckInformation Result { get; private set; }
-
- /// <summary>
- /// Gets AsyncWaitHandle.
- /// </summary>
- /// <exception cref="NotImplementedException">
- /// This is not implemented as it is not used.
- /// </exception>
- public WaitHandle AsyncWaitHandle
- {
- get { throw new NotImplementedException(); }
- }
-
- /// <summary>
- /// Gets a value indicating whether CompletedSynchronously.
- /// </summary>
- /// <exception cref="NotImplementedException">
- /// This is not implemented as it is not used.
- /// </exception>
- public bool CompletedSynchronously
- {
- get { throw new NotImplementedException(); }
- }
-
- /// <summary>
- /// Gets a value indicating whether IsCompleted.
- /// </summary>
- /// <exception cref="NotImplementedException">
- /// This is not implemented as it is not used.
- /// </exception>
- public bool IsCompleted
- {
- get { throw new NotImplementedException(); }
- }
- }
-}
diff --git a/win/CS/HandBrake.ApplicationServices/Services/UpdateService.cs b/win/CS/HandBrake.ApplicationServices/Services/UpdateService.cs deleted file mode 100644 index 899a953c4..000000000 --- a/win/CS/HandBrake.ApplicationServices/Services/UpdateService.cs +++ /dev/null @@ -1,107 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="UpdateService.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// The Update Service
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrake.ApplicationServices.Services
-{
- using System;
- using System.IO;
- using System.Net;
- using System.Threading;
-
- using HandBrake.ApplicationServices.Model.General;
- using HandBrake.ApplicationServices.Utilities;
-
- /// <summary>
- /// The Update Service
- /// </summary>
- public class UpdateService
- {
- /*
- * TODO: Refactor this to use Caliburn Invocation
- */
-
- /// <summary>
- /// Begins checking for an update to HandBrake.
- /// </summary>
- /// <param name="callback">
- /// The method that will be called when the check is finished.
- /// </param>
- /// <param name="debug">
- /// Whether or not to execute this in debug mode.
- /// </param>
- /// <param name="url">
- /// The url.
- /// </param>
- /// <param name="currentBuild">
- /// The current Build.
- /// </param>
- /// <param name="skipBuild">
- /// The skip Build.
- /// </param>
- public static void BeginCheckForUpdates(AsyncCallback callback, bool debug, string url, int currentBuild, int skipBuild)
- {
- ThreadPool.QueueUserWorkItem(delegate
- {
- try
- {
- // Initialize variables
- WebRequest request = WebRequest.Create(url);
- WebResponse response = request.GetResponse();
- AppcastReader reader = new AppcastReader();
-
- // Get the data, convert it to a string, and parse it into the AppcastReader
- reader.GetUpdateInfo(new StreamReader(response.GetResponseStream()).ReadToEnd());
-
- // Further parse the information
- string build = reader.Build;
-
- int latest = int.Parse(build);
- int current = currentBuild;
- int skip = skipBuild;
-
- // If the user wanted to skip this version, don't report the update
- if (latest == skip)
- {
- UpdateCheckInformation info = new UpdateCheckInformation { NewVersionAvailable = false };
- callback(new UpdateCheckResult(debug, info));
- return;
- }
-
- UpdateCheckInformation info2 = new UpdateCheckInformation
- {
- NewVersionAvailable = latest > current,
- DescriptionUrl = reader.DescriptionUrl,
- DownloadFile = reader.DownloadFile,
- Build = reader.Build,
- Version = reader.Version,
- };
- callback(new UpdateCheckResult(debug, info2));
- }
- catch (Exception exc)
- {
- callback(new UpdateCheckResult(debug, new UpdateCheckInformation { Error = exc }));
- }
- });
- }
-
- /// <summary>
- /// End Check for Updates
- /// </summary>
- /// <param name="result">
- /// The result.
- /// </param>
- /// <returns>
- /// Update Check information
- /// </returns>
- public static UpdateCheckInformation EndCheckForUpdates(IAsyncResult result)
- {
- return ((UpdateCheckResult)result).Result;
- }
- }
-}
diff --git a/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs b/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs index 5799425d9..2a7350b33 100644 --- a/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs +++ b/win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs @@ -45,6 +45,9 @@ namespace HandBrakeWPF.Converters.Options case "Advanced":
if (parameter.ToString() == "Advanced") return Visibility.Visible;
break;
+ case "Updates":
+ if (parameter.ToString() == "Updates") return Visibility.Visible;
+ break;
}
}
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj index 7d0270859..e8e57eb23 100644 --- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj +++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj @@ -124,6 +124,10 @@ <Compile Include="Converters\Options\OptionsTabConverter.cs" />
<Compile Include="Converters\Video\VideoEncoderConverter.cs" />
<Compile Include="Model\ShellWindow.cs" />
+ <Compile Include="Model\UpdateCheckInformation.cs" />
+ <Compile Include="Model\DownloadStatus.cs" />
+ <Compile Include="Services\Interfaces\IUpdateService.cs" />
+ <Compile Include="Services\UpdateService.cs" />
<Compile Include="Views\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon>
</Compile>
@@ -145,7 +149,6 @@ <Compile Include="Helpers\CliCheckHelper.cs" />
<Compile Include="Helpers\ListBoxHelper.cs" />
<Compile Include="Helpers\QueueRecoveryHelper.cs" />
- <Compile Include="Helpers\UpdateCheckHelper.cs" />
<Compile Include="Model\AdvancedChoice.cs" />
<Compile Include="Services\ErrorService.cs" />
<Compile Include="Services\Interfaces\IJobContextService.cs" />
diff --git a/win/CS/HandBrakeWPF/Helpers/UpdateCheckHelper.cs b/win/CS/HandBrakeWPF/Helpers/UpdateCheckHelper.cs deleted file mode 100644 index 2e5398cd0..000000000 --- a/win/CS/HandBrakeWPF/Helpers/UpdateCheckHelper.cs +++ /dev/null @@ -1,126 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------
-// <copyright file="UpdateCheckHelper.cs" company="HandBrake Project (http://handbrake.fr)">
-// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
-// </copyright>
-// <summary>
-// Update Check Helper
-// </summary>
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace HandBrakeWPF.Helpers
-{
- using System;
- using System.Windows;
-
- using Caliburn.Micro;
-
- using HandBrake.ApplicationServices;
- using HandBrake.ApplicationServices.Model.General;
- using HandBrake.ApplicationServices.Services;
- using HandBrake.ApplicationServices.Services.Interfaces;
-
- using HandBrakeWPF.Services.Interfaces;
-
- /// <summary>
- /// Update Check Helper
- /// </summary>
- public class UpdateCheckHelper
- {
- /// <summary>
- /// Perform a startup update check. Abiding by user settings.
- /// </summary>
- public static void PerformStartupUpdateCheck()
- {
- // Make sure it's running on the calling thread
- IUserSettingService userSettingService = IoC.Get<IUserSettingService>();
- if (userSettingService.GetUserSetting<bool>(UserSettingConstants.UpdateStatus))
- {
- if (DateTime.Now.Subtract(userSettingService.GetUserSetting<DateTime>(UserSettingConstants.LastUpdateCheckDate)).TotalDays
- > userSettingService.GetUserSetting<int>(UserSettingConstants.DaysBetweenUpdateCheck))
- {
- userSettingService.SetUserSetting(UserSettingConstants.LastUpdateCheckDate, DateTime.Now);
- string url = userSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakePlatform).Contains("x86_64")
- ? userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_x64)
- : userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_i686);
- UpdateService.BeginCheckForUpdates(UpdateCheckDone, false,
- url, userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild),
- userSettingService.GetUserSetting<int>(UserSettingConstants.Skipversion));
- }
- }
- }
-
- /// <summary>
- /// Check for Updates.
- /// </summary>
- public static void CheckForUpdates()
- {
- IUserSettingService userSettingService = IoC.Get<IUserSettingService>();
- userSettingService.SetUserSetting(UserSettingConstants.LastUpdateCheckDate, DateTime.Now);
- string url = userSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakePlatform).Contains("x86_64")
- ? userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_x64)
- : userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_i686);
- UpdateService.BeginCheckForUpdates(UpdateCheckDoneMenu, false,
- url, userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild),
- userSettingService.GetUserSetting<int>(UserSettingConstants.Skipversion));
- }
-
- /// <summary>
- /// Handle the Update Check Finishing.
- /// </summary>
- /// <param name="result">
- /// The result.
- /// </param>
- private static void UpdateCheckDone(IAsyncResult result)
- {
- // Make sure it's running on the calling thread
- IErrorService errorService = IoC.Get<IErrorService>();
- try
- {
- // Get the information about the new build, if any, and close the window
- UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
-
- if (info.NewVersionAvailable)
- {
- errorService.ShowMessageBox(
- "A New Update is Available", "Update available!", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- }
- catch (Exception ex)
- {
- errorService.ShowError("Unable to check for updates", "Please try again later, the update service may currently be down.", ex);
- }
- }
-
- /// <summary>
- /// Handle the Update Check Finishing.
- /// </summary>
- /// <param name="result">
- /// The result.
- /// </param>
- private static void UpdateCheckDoneMenu(IAsyncResult result)
- {
- // Make sure it's running on the calling thread
- IErrorService errorService = IoC.Get<IErrorService>();
- try
- {
- // Get the information about the new build, if any, and close the window
- UpdateCheckInformation info = UpdateService.EndCheckForUpdates(result);
-
- if (info.NewVersionAvailable)
- {
- errorService.ShowMessageBox(
- "A New Update is Available", "Update available!", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- else
- {
- errorService.ShowMessageBox(
- "There is no new version at this time.", "No Updates", MessageBoxButton.OK, MessageBoxImage.Information);
- }
- }
- catch (Exception ex)
- {
- errorService.ShowError("Unable to check for updates", "Please try again later, the update service may currently be down.", ex);
- }
- }
- }
-}
diff --git a/win/CS/HandBrakeWPF/Model/DownloadStatus.cs b/win/CS/HandBrakeWPF/Model/DownloadStatus.cs new file mode 100644 index 000000000..8e58a7ecf --- /dev/null +++ b/win/CS/HandBrakeWPF/Model/DownloadStatus.cs @@ -0,0 +1,49 @@ +// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="DownloadStatus.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Progress of a File Download
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Model
+{
+ using System;
+
+ /// <summary>
+ /// The Progress of a File Download
+ /// </summary>
+ public class DownloadStatus
+ {
+ /// <summary>
+ /// Gets or sets BytesRead.
+ /// </summary>
+ public long BytesRead { get; set; }
+
+ /// <summary>
+ /// Gets or sets TotalBytes.
+ /// </summary>
+ public long TotalBytes { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether WasSuccessful.
+ /// </summary>
+ public bool WasSuccessful { get; set; }
+
+ /// <summary>
+ /// Gets or sets Exception.
+ /// </summary>
+ public Exception Exception { get; set; }
+
+ /// <summary>
+ /// Gets or sets Message.
+ /// </summary>
+ public string Message { get; set; }
+
+ /// <summary>
+ /// Gets or sets FilePath.
+ /// </summary>
+ public string FilePath { get; set; }
+ }
+}
diff --git a/win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckInformation.cs b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs index 86045c938..bc49a2ee3 100644 --- a/win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckInformation.cs +++ b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs @@ -7,7 +7,7 @@ // </summary>
// --------------------------------------------------------------------------------------------------------------------
-namespace HandBrake.ApplicationServices.Model.General
+namespace HandBrakeWPF.Model
{
using System;
diff --git a/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs b/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs new file mode 100644 index 000000000..cd1b50e9f --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs @@ -0,0 +1,51 @@ +// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IUpdateService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// An Interface for the Update Service
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services.Interfaces
+{
+ using System;
+
+ using HandBrakeWPF.Model;
+
+ /// <summary>
+ /// An Interface for the Update Service
+ /// </summary>
+ public interface IUpdateService
+ {
+ /// <summary>
+ /// Perform an update check at application start, but only daily, weekly or monthly depending on the users settings.
+ /// </summary>
+ /// <param name="callback">
+ /// The callback.
+ /// </param>
+ void PerformStartupUpdateCheck(Action<UpdateCheckInformation> callback);
+
+ /// <summary>
+ /// Perform an Update check and execute the Action when complete.
+ /// </summary>
+ /// <param name="callback">
+ /// The callback.
+ /// </param>
+ void CheckForUpdates(Action<UpdateCheckInformation> callback);
+
+ /// <summary>
+ /// Download the update file.
+ /// </summary>
+ /// <param name="url">
+ /// The url.
+ /// </param>
+ /// <param name="completed">
+ /// The complete.
+ /// </param>
+ /// <param name="progress">
+ /// The progress.
+ /// </param>
+ void DownloadFile(string url, Action<DownloadStatus> completed, Action<DownloadStatus> progress);
+ }
+}
diff --git a/win/CS/HandBrakeWPF/Services/UpdateService.cs b/win/CS/HandBrakeWPF/Services/UpdateService.cs new file mode 100644 index 000000000..2b6cfa852 --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/UpdateService.cs @@ -0,0 +1,206 @@ +// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="UpdateService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Update Service
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Services
+{
+ using System;
+ using System.IO;
+ using System.Net;
+ using System.Threading;
+
+ using HandBrake.ApplicationServices;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+ using HandBrake.ApplicationServices.Utilities;
+
+ using HandBrakeWPF.Model;
+ using HandBrakeWPF.Services.Interfaces;
+
+ /// <summary>
+ /// The Update Service
+ /// </summary>
+ public class UpdateService : IUpdateService
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// Backing field for the update service
+ /// </summary>
+ private readonly IUserSettingService userSettingService;
+
+ #endregion
+
+ #region Constructors and Destructors
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="UpdateService"/> class.
+ /// </summary>
+ /// <param name="userSettingService">
+ /// The user setting service.
+ /// </param>
+ public UpdateService(IUserSettingService userSettingService)
+ {
+ this.userSettingService = userSettingService;
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Perform an update check at application start, but only daily, weekly or monthly depending on the users settings.
+ /// </summary>
+ /// <param name="callback">
+ /// The callback.
+ /// </param>
+ public void PerformStartupUpdateCheck(Action<UpdateCheckInformation> callback)
+ {
+ // Make sure it's running on the calling thread
+ if (this.userSettingService.GetUserSetting<bool>(UserSettingConstants.UpdateStatus))
+ {
+ if (DateTime.Now.Subtract(this.userSettingService.GetUserSetting<DateTime>(UserSettingConstants.LastUpdateCheckDate)).TotalDays
+ > this.userSettingService.GetUserSetting<int>(UserSettingConstants.DaysBetweenUpdateCheck))
+ {
+ this.userSettingService.SetUserSetting(UserSettingConstants.LastUpdateCheckDate, DateTime.Now);
+
+ this.CheckForUpdates(callback);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Check for Updates
+ /// </summary>
+ /// <param name="callback">
+ /// The callback.
+ /// </param>
+ public void CheckForUpdates(Action<UpdateCheckInformation> callback)
+ {
+ ThreadPool.QueueUserWorkItem(
+ delegate
+ {
+ try
+ {
+ string url =
+ this.userSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakePlatform)
+ .Contains("x86_64")
+ ? this.userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_x64)
+ : this.userSettingService.GetUserSetting<string>(UserSettingConstants.Appcast_i686);
+
+ var currentBuild =
+ this.userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild);
+ var skipBuild = this.userSettingService.GetUserSetting<int>(
+ UserSettingConstants.Skipversion);
+
+ // Initialize variables
+ WebRequest request = WebRequest.Create(url);
+ WebResponse response = request.GetResponse();
+ var reader = new AppcastReader();
+
+ // Get the data, convert it to a string, and parse it into the AppcastReader
+ reader.GetUpdateInfo(new StreamReader(response.GetResponseStream()).ReadToEnd());
+
+ // Further parse the information
+ string build = reader.Build;
+
+ int latest = int.Parse(build);
+ int current = currentBuild;
+ int skip = skipBuild;
+
+ // If the user wanted to skip this version, don't report the update
+ if (latest == skip)
+ {
+ var info = new UpdateCheckInformation { NewVersionAvailable = false };
+ callback(info);
+ return;
+ }
+
+ var info2 = new UpdateCheckInformation
+ {
+ NewVersionAvailable = latest > current,
+ DescriptionUrl = reader.DescriptionUrl,
+ DownloadFile = reader.DownloadFile,
+ Build = reader.Build,
+ Version = reader.Version,
+ };
+
+ callback(info2);
+ }
+ catch (Exception exc)
+ {
+ callback(new UpdateCheckInformation { NewVersionAvailable = false, Error = exc });
+ }
+ });
+ }
+
+ /// <summary>
+ /// Download the update file.
+ /// </summary>
+ /// <param name="url">
+ /// The url.
+ /// </param>
+ /// <param name="completed">
+ /// The complete.
+ /// </param>
+ /// <param name="progress">
+ /// The progress.
+ /// </param>
+ public void DownloadFile(string url, Action<DownloadStatus> completed, Action<DownloadStatus> progress)
+ {
+ ThreadPool.QueueUserWorkItem(
+ delegate
+ {
+ string tempPath = Path.Combine(Path.GetTempPath(), "handbrake-setup.exe");
+ WebClient wcDownload = new WebClient();
+
+ try
+ {
+ if (File.Exists(tempPath))
+ File.Delete(tempPath);
+
+ HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
+ webRequest.Credentials = CredentialCache.DefaultCredentials;
+ HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
+ long fileSize = webResponse.ContentLength;
+
+ Stream responceStream = wcDownload.OpenRead(url);
+ Stream localStream = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.None);
+
+ int bytesSize;
+ byte[] downBuffer = new byte[2048];
+
+ long flength = 0;
+ while ((bytesSize = responceStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
+ {
+ localStream.Write(downBuffer, 0, bytesSize);
+ flength = localStream.Length;
+ progress(new DownloadStatus { BytesRead = localStream.Length, TotalBytes = fileSize});
+ }
+
+ responceStream.Close();
+ localStream.Close();
+
+ completed(
+ flength != fileSize
+ ? new DownloadStatus
+ {
+ WasSuccessful = false,
+ Message = "Partial Download. File is Incomplete. Please Retry the download."
+ }
+ : new DownloadStatus { WasSuccessful = true, Message = "Download Complete." });
+ }
+ catch (Exception exc)
+ {
+ progress(new DownloadStatus { WasSuccessful = false, Exception = exc, Message = "Download Failed." });
+ }
+ });
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs index 2b694252b..e929047ea 100644 --- a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs +++ b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs @@ -51,6 +51,9 @@ namespace HandBrakeWPF.Startup this.windsorContainer.Register(Component.For<IWindsorInstaller>().ImplementedBy<ServicesWindsorInstaller>());
this.windsorContainer.Install(windsorContainer.ResolveAll<IWindsorInstaller>());
+ // Services
+ this.windsorContainer.Register(Component.For<IUpdateService>().ImplementedBy<UpdateService>().LifeStyle.Is(LifestyleType.Singleton));
+
// Shell
this.windsorContainer.Register(Component.For<IErrorService>().ImplementedBy<ErrorService>().LifeStyle.Is(LifestyleType.Singleton));
this.windsorContainer.Register(Component.For<IErrorViewModel>().ImplementedBy<ErrorViewModel>().LifeStyle.Is(LifestyleType.Singleton));
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index cd5d06dbf..0e508a7a2 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -78,6 +78,11 @@ namespace HandBrakeWPF.ViewModels private readonly IShellViewModel shellViewModel;
/// <summary>
+ /// Backing field for the update serivce.
+ /// </summary>
+ private readonly IUpdateService updateService;
+
+ /// <summary>
/// Backing field for the user setting service.
/// </summary>
private readonly IUserSettingService userSettingService;
@@ -169,15 +174,19 @@ namespace HandBrakeWPF.ViewModels /// <param name="shellViewModel">
/// The shell View Model.
/// </param>
+ /// <param name="updateService">
+ /// The update Service.
+ /// </param>
[ImportingConstructor]
public MainViewModel(IWindowManager windowManager, IUserSettingService userSettingService, IScan scanService, IEncode encodeService, IPresetService presetService,
- IErrorService errorService, IShellViewModel shellViewModel)
+ IErrorService errorService, IShellViewModel shellViewModel, IUpdateService updateService)
{
this.scanService = scanService;
this.encodeService = encodeService;
this.presetService = presetService;
this.errorService = errorService;
this.shellViewModel = shellViewModel;
+ this.updateService = updateService;
this.userSettingService = userSettingService;
this.queueProcessor = IoC.Get<IQueueProcessor>(); // TODO Instance ID!
@@ -811,7 +820,7 @@ namespace HandBrakeWPF.ViewModels CliCheckHelper.CheckCLIVersion();
// Perform an update check if required
- UpdateCheckHelper.PerformStartupUpdateCheck();
+ this.updateService.PerformStartupUpdateCheck(this.HandleUpdateCheckResults);
// Setup the presets.
if (this.presetService.CheckIfPresetsAreOutOfDate())
@@ -854,7 +863,7 @@ namespace HandBrakeWPF.ViewModels if (result == MessageBoxResult.No)
{
e.Cancel = true;
- }
+ }
else
{
this.encodeService.Stop();
@@ -921,7 +930,8 @@ namespace HandBrakeWPF.ViewModels /// </summary>
public void CheckForUpdates()
{
- UpdateCheckHelper.CheckForUpdates();
+ this.ProgramStatusLabel = "Checking for Updates ...";
+ this.updateService.CheckForUpdates(this.HandleManualUpdateCheckResults);
}
/// <summary>
@@ -939,12 +949,12 @@ namespace HandBrakeWPF.ViewModels if (!this.queueProcessor.QueueManager.CheckForDestinationPathDuplicates(task.Task.Destination))
{
this.queueProcessor.QueueManager.Add(task);
- }
+ }
else
{
this.errorService.ShowMessageBox("There are jobs on the queue with the same destination path. Please choose a different path for this job.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning);
}
-
+
if (!this.IsEncoding)
{
@@ -1152,7 +1162,7 @@ namespace HandBrakeWPF.ViewModels if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] fileNames = e.Data.GetData(DataFormats.FileDrop, true) as string[];
- if (fileNames != null && fileNames.Any() && (File.Exists(fileNames[0]) || Directory.Exists(fileNames[0])) )
+ if (fileNames != null && fileNames.Any() && (File.Exists(fileNames[0]) || Directory.Exists(fileNames[0])))
{
this.StartScan(fileNames[0], 0);
}
@@ -1203,7 +1213,7 @@ namespace HandBrakeWPF.ViewModels }
this.NotifyOfPropertyChange(() => this.CurrentTask);
- }
+ }
}
/// <summary>
@@ -1435,6 +1445,38 @@ namespace HandBrakeWPF.ViewModels return "--:--:--";
}
+ /// <summary>
+ /// Handle Update Check Results
+ /// </summary>
+ /// <param name="information">
+ /// The information.
+ /// </param>
+ private void HandleUpdateCheckResults(UpdateCheckInformation information)
+ {
+ if (information.NewVersionAvailable)
+ {
+ this.ProgramStatusLabel = "A New Update is Available. Goto Tools Menu > Options to Install";
+ }
+ }
+
+ /// <summary>
+ /// Handle Update Check Results
+ /// </summary>
+ /// <param name="information">
+ /// The information.
+ /// </param>
+ private void HandleManualUpdateCheckResults(UpdateCheckInformation information)
+ {
+ if (information.NewVersionAvailable)
+ {
+ MessageBox.Show("A New Version is available. Goto Tools Menu > Options to Install or visit http://handbrake.fr for details.", "Update Available", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ else
+ {
+ MessageBox.Show("There is no new updates at this time.", "No Update Available", MessageBoxButton.OK, MessageBoxImage.Information);
+ }
+ }
+
#endregion
#region Event Handlers
diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs index bb2bff804..7036240cd 100644 --- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs @@ -27,6 +27,7 @@ namespace HandBrakeWPF.ViewModels using HandBrake.ApplicationServices.Utilities;
using HandBrakeWPF.Model;
+ using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.ViewModels.Interfaces;
using Ookii.Dialogs.Wpf;
@@ -50,6 +51,11 @@ namespace HandBrakeWPF.ViewModels private readonly IShellViewModel shellViewModel;
/// <summary>
+ /// Backing field for the update service.
+ /// </summary>
+ private readonly IUpdateService updateService;
+
+ /// <summary>
/// The add audio mode options.
/// </summary>
private BindingList<string> addAudioModeOptions = new BindingList<string>();
@@ -274,7 +280,6 @@ namespace HandBrakeWPF.ViewModels /// </summary>
private string sendFileToPath;
-
/// <summary>
/// The show cli window.
/// </summary>
@@ -315,6 +320,26 @@ namespace HandBrakeWPF.ViewModels /// </summary>
private string selectedTab;
+ /// <summary>
+ /// Update Message
+ /// </summary>
+ private string updateMessage;
+
+ /// <summary>
+ /// Update Available
+ /// </summary>
+ private bool updateAvailable;
+
+ /// <summary>
+ /// Download progress backing field.
+ /// </summary>
+ private int downloadProgressPercentage;
+
+ /// <summary>
+ /// Backing field for update info.
+ /// </summary>
+ private UpdateCheckInformation updateInfo;
+
#endregion
#region Constructors and Destructors
@@ -331,14 +356,19 @@ namespace HandBrakeWPF.ViewModels /// <param name="shellViewModel">
/// The shell View Model.
/// </param>
- public OptionsViewModel(IWindowManager windowManager, IUserSettingService userSettingService, IShellViewModel shellViewModel)
+ /// <param name="updateService">
+ /// The update Service.
+ /// </param>
+ public OptionsViewModel(IWindowManager windowManager, IUserSettingService userSettingService, IShellViewModel shellViewModel, IUpdateService updateService )
{
this.Title = "Options";
this.userSettingService = userSettingService;
this.shellViewModel = shellViewModel;
+ this.updateService = updateService;
this.OnLoad();
this.SelectedTab = "General";
+ this.UpdateMessage = "Click 'Check for Updates' to check for new versions";
}
#endregion
@@ -352,7 +382,7 @@ namespace HandBrakeWPF.ViewModels {
get
{
- return new List<string> { "General", "Output Files", "Language", "Advanced" };
+ return new List<string> { "General", "Output Files", "Language", "Advanced", "Updates" };
}
}
@@ -1289,6 +1319,74 @@ namespace HandBrakeWPF.ViewModels #endregion
+ #region About HandBrake
+
+ /// <summary>
+ /// Gets Version.
+ /// </summary>
+ public string Version
+ {
+ get
+ {
+ string nightly = UserSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakeVersion).Contains("svn") ? " (SVN / Nightly Build)" : string.Empty;
+ return string.Format(
+ "{0} ({1}) {2}",
+ UserSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakeVersion),
+ UserSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild),
+ nightly);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets UpdateMessage.
+ /// </summary>
+ public string UpdateMessage
+ {
+ get
+ {
+ return this.updateMessage;
+ }
+ set
+ {
+ this.updateMessage = value;
+ this.NotifyOfPropertyChange(() => this.UpdateMessage);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether UpdateAvailable.
+ /// </summary>
+ public bool UpdateAvailable
+ {
+ get
+ {
+ return this.updateAvailable;
+ }
+ set
+ {
+ this.updateAvailable = value;
+ this.NotifyOfPropertyChange(() => this.UpdateAvailable);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets DownloadProgressPercentage.
+ /// </summary>
+ public int DownloadProgressPercentage
+ {
+ get
+ {
+ return this.downloadProgressPercentage;
+ }
+ set
+ {
+ this.downloadProgressPercentage = value;
+ this.NotifyOfPropertyChange(() => this.DownloadProgressPercentage);
+ }
+ }
+
+ #endregion
+
#region Public Methods
/// <summary>
@@ -1633,6 +1731,27 @@ namespace HandBrakeWPF.ViewModels MessageBox.Show("HandBrake's Log file directory has been cleared!", "Notice", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
+ #endregion
+
+ #region Updates
+
+ /// <summary>
+ /// Download an Update
+ /// </summary>
+ public void DownloadUpdate()
+ {
+ this.UpdateMessage = "Preparing for Update ...";
+ this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.DownloadComplete, this.DownloadProgress);
+ }
+
+ /// <summary>
+ /// Check for updates
+ /// </summary>
+ public void PerformUpdateCheck()
+ {
+ this.UpdateMessage = "Checking for Updates ...";
+ this.updateService.CheckForUpdates(this.UpdateCheckComplete);
+ }
#endregion
@@ -1701,5 +1820,62 @@ namespace HandBrakeWPF.ViewModels userSettingService.SetUserSetting(ASUserSettingConstants.DisableLibDvdNav, this.DisableLibdvdNav);
}
+
+ /// <summary>
+ /// Update Check Complete
+ /// </summary>
+ /// <param name="info">
+ /// The info.
+ /// </param>
+ private void UpdateCheckComplete(UpdateCheckInformation info)
+ {
+ this.updateInfo = info;
+ if (info.NewVersionAvailable)
+ {
+ this.UpdateMessage = "A New Update is Available!";
+ this.UpdateAvailable = true;
+ }
+ else
+ {
+ this.UpdateMessage = "There are no new updates at this time.";
+ this.UpdateAvailable = false;
+ }
+ }
+
+ /// <summary>
+ /// Download Progress Action
+ /// </summary>
+ /// <param name="info">
+ /// The info.
+ /// </param>
+ private void DownloadProgress(DownloadStatus info)
+ {
+ if (info.TotalBytes == 0 || info.BytesRead == 0)
+ {
+ return;
+ }
+
+ long p = (info.BytesRead * 100) / info.TotalBytes;
+ int progress;
+ int.TryParse(p.ToString(CultureInfo.InvariantCulture), out progress);
+ this.DownloadProgressPercentage = progress;
+ this.UpdateMessage = string.Format(
+ "Downloading... {0}% - {1}k of {2}k", this.DownloadProgressPercentage, (info.BytesRead / 1024), (info.TotalBytes / 1024));
+ }
+
+ /// <summary>
+ /// Download Complete Action
+ /// </summary>
+ /// <param name="info">
+ /// The info.
+ /// </param>
+ private void DownloadComplete(DownloadStatus info)
+ {
+ this.UpdateAvailable = false;
+ this.UpdateMessage = info.WasSuccessful ? "Update Downloaded" : "Update Failed. You can try downloading the update from http://handbrake.fr";
+
+ Process.Start(Path.Combine(Path.GetTempPath(), "handbrake-setup.exe"));
+ Application.Current.Shutdown();
+ }
}
}
\ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Views/OptionsView.xaml b/win/CS/HandBrakeWPF/Views/OptionsView.xaml index f1ac5df81..bb41c30cc 100644 --- a/win/CS/HandBrakeWPF/Views/OptionsView.xaml +++ b/win/CS/HandBrakeWPF/Views/OptionsView.xaml @@ -4,7 +4,7 @@ xmlns:Helpers="clr-namespace:HandBrakeWPF.Helpers"
xmlns:Options="clr-namespace:HandBrakeWPF.Converters.Options"
xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
- Background="White">
+ xmlns:Converters="clr-namespace:HandBrakeWPF.Converters" Background="White">
<UserControl.Resources>
<Style TargetType="Button">
@@ -34,10 +34,9 @@ </Style>
<Options:OptionsTabConverter x:Key="tabConverter" />
+ <Converters:BooleanToVisibilityConverter x:Key="boolToVisConverter" />
</UserControl.Resources>
-
-
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
@@ -339,6 +338,42 @@ </StackPanel>
</StackPanel>
+
+ <StackPanel Name="Updates" Orientation="Vertical" Margin="10,10,0,0"
+ Visibility="{Binding SelectedTab, Converter={StaticResource tabConverter}, ConverterParameter='Updates'}">
+
+
+ <Border BorderThickness="0 0 0 1" BorderBrush="LightGray">
+ <TextBlock Text="Updates" FontSize="16" />
+ </Border>
+
+ <TextBlock Text="Current Version" Grid.Column="0" FontSize="14" Margin="0,10,0,10"/>
+
+ <Grid Margin="20,10,0,20">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="70" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+
+ <!-- Version -->
+ <TextBlock Grid.Column="0" Margin="0,0,5,0" Text="Version:" />
+ <TextBlock Grid.Column="1" Margin="0,0,0,1" VerticalAlignment="Bottom" Text="{Binding Version}" />
+ </Grid>
+
+ <TextBlock Text="Updates" Grid.Column="0" FontSize="14" Margin="0,10,0,10"/>
+
+ <StackPanel Margin="20,0,0,0" Orientation="Horizontal">
+ <Button Content="Check for Updates" Width="120" Margin="0,0,5,0" cal:Message.Attach="[Event Click] = [Action PerformUpdateCheck]" />
+ <Button Content="Download Update" Width="120" cal:Message.Attach="[Event Click] = [Action DownloadUpdate]" Visibility="{Binding UpdateAvailable, Converter={StaticResource boolToVisConverter}}" />
+ </StackPanel>
+
+ <StackPanel Margin="20,10,0,0" Orientation="Horizontal">
+ <ProgressBar Minimum="0" Maximum="100" Height="20" Width="400" Value="{Binding DownloadProgressPercentage}"
+ Visibility="{Binding UpdateAvailable, Converter={StaticResource boolToVisConverter}}" />
+ <TextBlock Text="{Binding UpdateMessage}" Margin="10,0,10,0" VerticalAlignment="Center" />
+ </StackPanel>
+
+ </StackPanel>
</StackPanel>
</ScrollViewer>
|