]> granicus.if.org Git - handbrake/commitdiff
WinGui: Refactor the Update service and add a new options tab to deal with updates.
authorsr55 <sr55.hb@outlook.com>
Sat, 30 Jun 2012 14:07:50 +0000 (14:07 +0000)
committersr55 <sr55.hb@outlook.com>
Sat, 30 Jun 2012 14:07:50 +0000 (14:07 +0000)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4799 b64f7644-9d1e-0410-96f1-a4d463321fa5

14 files changed:
win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckResult.cs [deleted file]
win/CS/HandBrake.ApplicationServices/Services/UpdateService.cs [deleted file]
win/CS/HandBrakeWPF/Converters/Options/OptionsTabConverter.cs
win/CS/HandBrakeWPF/HandBrakeWPF.csproj
win/CS/HandBrakeWPF/Helpers/UpdateCheckHelper.cs [deleted file]
win/CS/HandBrakeWPF/Model/DownloadStatus.cs [new file with mode: 0644]
win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs [moved from win/CS/HandBrake.ApplicationServices/Model/General/UpdateCheckInformation.cs with 94% similarity]
win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs [new file with mode: 0644]
win/CS/HandBrakeWPF/Services/UpdateService.cs [new file with mode: 0644]
win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs
win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
win/CS/HandBrakeWPF/Views/OptionsView.xaml

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