]> granicus.if.org Git - handbrake/commitdiff
WinGui: Add a Logging Service into the AppServices library. This does not depend...
authorsr55 <sr55.hb@outlook.com>
Mon, 21 Mar 2016 00:07:04 +0000 (00:07 +0000)
committersr55 <sr55.hb@outlook.com>
Mon, 21 Mar 2016 00:07:04 +0000 (00:07 +0000)
Changed the Logging screen to a single panel in the WinGui. This will change back to separate Scan/Encode logs when we get libhb it's own processes.
Added Auto-Scroll to the log window.

24 files changed:
win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
win/CS/HandBrake.ApplicationServices/Interop/HandBrakeInstance.cs
win/CS/HandBrake.ApplicationServices/Interop/HandBrakePresetService.cs
win/CS/HandBrake.ApplicationServices/Interop/HandBrakeUtils.cs
win/CS/HandBrake.ApplicationServices/Services/Logging/EventArgs/LogEventArgs.cs [new file with mode: 0644]
win/CS/HandBrake.ApplicationServices/Services/Logging/Interfaces/ILog.cs [new file with mode: 0644]
win/CS/HandBrake.ApplicationServices/Services/Logging/LogHelper.cs [deleted file]
win/CS/HandBrake.ApplicationServices/Services/Logging/LogService.cs [new file with mode: 0644]
win/CS/HandBrake.ApplicationServices/Services/Logging/Model/LogLevel.cs
win/CS/HandBrake.ApplicationServices/Services/Logging/Model/LogMessage.cs
win/CS/HandBrake.ApplicationServices/Services/Logging/Model/LogMessageType.cs
win/CS/HandBrake.ApplicationServices/Utilities/LanguageUtilities.cs
win/CS/HandBrakeWPF/HandBrakeWPF.csproj
win/CS/HandBrakeWPF/Helpers/LogManager.cs [new file with mode: 0644]
win/CS/HandBrakeWPF/Services/Encode/EncodeBase.cs
win/CS/HandBrakeWPF/Services/Encode/Interfaces/IEncode.cs
win/CS/HandBrakeWPF/Services/Encode/LibEncode.cs
win/CS/HandBrakeWPF/Services/Scan/Interfaces/IScan.cs
win/CS/HandBrakeWPF/Services/Scan/LibScan.cs
win/CS/HandBrakeWPF/ViewModels/Interfaces/ILogViewModel.cs
win/CS/HandBrakeWPF/ViewModels/LogViewModel.cs
win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
win/CS/HandBrakeWPF/Views/LogView.xaml
win/CS/HandBrakeWPF/Views/LogView.xaml.cs

index c6fddcfb7356b31f0c326565728c0daaaa3323aa..91342b0590408d01022b8987fdb72dd2e4de5e4a 100644 (file)
     <Compile Include="Interop\Model\VideoQualityLimits.cs" />\r
     <Compile Include="Model\HBConfiguration.cs" />\r
     <Compile Include="Model\VideoScaler.cs" />\r
-    <Compile Include="Services\Logging\LogHelper.cs" />\r
+    <Compile Include="Services\Logging\EventArgs\LogEventArgs.cs" />\r
+    <Compile Include="Services\Logging\Interfaces\ILog.cs" />\r
+    <Compile Include="Services\Logging\LogService.cs" />\r
     <Compile Include="Services\Logging\Model\LogLevel.cs" />\r
     <Compile Include="Services\Logging\Model\LogMessage.cs" />\r
     <Compile Include="Services\Logging\Model\LogMessageType.cs" />\r
index a862dc1e64134d04b61c4a4cfbbb903e9e5c6227..633c4e1fb784f8b3e48ee26d2c3092fcfddbbba8 100644 (file)
@@ -34,6 +34,7 @@ namespace HandBrake.ApplicationServices.Interop
     using HandBrake.ApplicationServices.Interop.Model.Encoding;\r
     using HandBrake.ApplicationServices.Interop.Model.Preview;\r
     using HandBrake.ApplicationServices.Services.Logging;\r
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;\r
     using HandBrake.ApplicationServices.Services.Logging.Model;\r
 \r
     using Newtonsoft.Json;\r
@@ -55,6 +56,8 @@ namespace HandBrake.ApplicationServices.Interop
         /// </summary>\r
         private const double EncodePollIntervalMs = 250;\r
 \r
+        private readonly ILog log = LogService.GetLogger();\r
+\r
         /// <summary>\r
         /// The native handle to the HandBrake instance.\r
         /// </summary>\r
@@ -502,7 +505,7 @@ namespace HandBrake.ApplicationServices.Interop
         {\r
             IntPtr json = HBFunctions.hb_get_state_json(this.hbHandle);\r
             string statusJson = Marshal.PtrToStringAnsi(json);\r
-            LogHelper.LogMessage(new LogMessage(statusJson, LogMessageType.progressJson, LogLevel.debug));\r
+            this.log.LogMessage(statusJson, LogMessageType.Progress, LogLevel.Trace);\r
             JsonState state = JsonConvert.DeserializeObject<JsonState>(statusJson);\r
 \r
             if (state != null && state.State == NativeConstants.HB_STATE_SCANNING)\r
@@ -516,7 +519,7 @@ namespace HandBrake.ApplicationServices.Interop
             {\r
                 var jsonMsg = HBFunctions.hb_get_title_set_json(this.hbHandle);\r
                 string scanJson = InteropUtilities.ToStringFromUtf8Ptr(jsonMsg);\r
-                LogHelper.LogMessage(new LogMessage(scanJson, LogMessageType.scanJson, LogLevel.debug));\r
+                this.log.LogMessage(scanJson, LogMessageType.Progress, LogLevel.Trace);\r
                 this.titles = JsonConvert.DeserializeObject<JsonScanObject>(scanJson);\r
                 this.featureTitle = this.titles.MainFeature;\r
 \r
@@ -541,7 +544,7 @@ namespace HandBrake.ApplicationServices.Interop
             IntPtr json = HBFunctions.hb_get_state_json(this.hbHandle);\r
             string statusJson = Marshal.PtrToStringAnsi(json);\r
 \r
-            LogHelper.LogMessage(new LogMessage(statusJson, LogMessageType.progressJson, LogLevel.debug));\r
+            this.log.LogMessage(statusJson, LogMessageType.Progress, LogLevel.Trace);\r
 \r
             JsonState state = JsonConvert.DeserializeObject<JsonState>(statusJson);\r
 \r
index fcc6d61da404b83855d850da40459a8454173f0a..7e1f95d3e4a1cf968d906ceed8b813e08be13583 100644 (file)
@@ -18,6 +18,7 @@ namespace HandBrake.ApplicationServices.Interop
     using HandBrake.ApplicationServices.Interop.Helpers;\r
     using HandBrake.ApplicationServices.Interop.Json.Presets;\r
     using HandBrake.ApplicationServices.Services.Logging;\r
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;\r
     using HandBrake.ApplicationServices.Services.Logging.Model;\r
 \r
     using Newtonsoft.Json;\r
@@ -27,6 +28,8 @@ namespace HandBrake.ApplicationServices.Interop
     /// </summary>\r
     public class HandBrakePresetService\r
     {\r
+        private static readonly ILog log = LogService.GetLogger();\r
+\r
         /// <summary>\r
         /// The get built in presets.\r
         /// Requires an hb_init to have been invoked.\r
@@ -39,7 +42,7 @@ namespace HandBrake.ApplicationServices.Interop
             IntPtr presets = HBFunctions.hb_presets_builtin_get_json();\r
             string presetJson = Marshal.PtrToStringAnsi(presets);\r
 \r
-            LogHelper.LogMessage(new LogMessage(presetJson, LogMessageType.progressJson, LogLevel.debug));\r
+            log.LogMessage(presetJson, LogMessageType.API, LogLevel.Debug);\r
 \r
             IList<PresetCategory> presetList = JsonConvert.DeserializeObject<IList<PresetCategory>>(presetJson);\r
 \r
@@ -60,7 +63,7 @@ namespace HandBrake.ApplicationServices.Interop
             IntPtr presetStringPointer = HBFunctions.hb_presets_read_file_json(InteropUtilities.ToUtf8PtrFromString(filename));\r
             string presetJson = Marshal.PtrToStringAnsi(presetStringPointer);\r
 \r
-            LogHelper.LogMessage(new LogMessage(presetJson, LogMessageType.libhb, LogLevel.debug));\r
+            log.LogMessage(presetJson, LogMessageType.API, LogLevel.Debug);\r
 \r
             PresetTransportContainer preset = JsonConvert.DeserializeObject<PresetTransportContainer>(presetJson);\r
 \r
index 3540bb368998b2fb63fabfeb6bdd8f6ccca96633..ef98f3f8678b1b5eee2c99fe99ba31db42a6f672 100644 (file)
@@ -11,7 +11,6 @@ namespace HandBrake.ApplicationServices.Interop
 {\r
     using System;\r
     using System.Collections.Generic;\r
-    using System.Diagnostics;\r
     using System.Runtime.InteropServices;\r
 \r
     using HandBrake.ApplicationServices.Interop.EventArgs;\r
@@ -19,6 +18,7 @@ namespace HandBrake.ApplicationServices.Interop
     using HandBrake.ApplicationServices.Interop.Json.Anamorphic;\r
     using HandBrake.ApplicationServices.Interop.Json.Shared;\r
     using HandBrake.ApplicationServices.Services.Logging;\r
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;\r
     using HandBrake.ApplicationServices.Services.Logging.Model;\r
 \r
     using Newtonsoft.Json;\r
@@ -28,6 +28,8 @@ namespace HandBrake.ApplicationServices.Interop
     /// </summary>\r
     public static class HandBrakeUtils\r
     {\r
+        private static readonly ILog log = LogService.GetLogger();\r
+\r
         /// <summary>\r
         /// The callback for log messages from HandBrake.\r
         /// </summary>\r
@@ -301,7 +303,7 @@ namespace HandBrake.ApplicationServices.Interop
         public static Geometry GetAnamorphicSize(AnamorphicGeometry anamorphicGeometry)\r
         {\r
             string encode = JsonConvert.SerializeObject(anamorphicGeometry, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });\r
-            LogHelper.LogMessage(new LogMessage(encode, LogMessageType.encodeJson, LogLevel.debug));\r
+            log.LogMessage(encode, LogMessageType.API, LogLevel.Debug);\r
             IntPtr json = HBFunctions.hb_set_anamorphic_size_json(Marshal.StringToHGlobalAnsi(encode));\r
             string result = Marshal.PtrToStringAnsi(json);\r
             return JsonConvert.DeserializeObject<Geometry>(result);\r
@@ -317,10 +319,9 @@ namespace HandBrake.ApplicationServices.Interop
         {\r
             if (MessageLogged != null)\r
             {\r
+                log.LogMessage(message, LogMessageType.ScanOrEncode, LogLevel.Info);\r
                 MessageLogged(null, new MessageLoggedEventArgs(message));\r
             }\r
-\r
-            Debug.WriteLine(message);\r
         }\r
 \r
         /// <summary>\r
@@ -333,10 +334,9 @@ namespace HandBrake.ApplicationServices.Interop
         {\r
             if (ErrorLogged != null)\r
             {\r
+                log.LogMessage(message, LogMessageType.ScanOrEncode, LogLevel.Error);\r
                 ErrorLogged(null, new MessageLoggedEventArgs(message));\r
             }\r
-\r
-            Debug.WriteLine("ERROR: " + message);\r
         }\r
     }\r
 }\r
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Logging/EventArgs/LogEventArgs.cs b/win/CS/HandBrake.ApplicationServices/Services/Logging/EventArgs/LogEventArgs.cs
new file mode 100644 (file)
index 0000000..b9691e4
--- /dev/null
@@ -0,0 +1,37 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="LogEventArgs.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>
+//   Defines the LogEventArgs type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services.Logging.EventArgs
+{
+    using System;
+
+    using Model;
+
+    /// <summary>
+    /// The Message Logged Event Args
+    /// </summary>
+    public class LogEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="LogEventArgs"/> class.
+        /// </summary>
+        /// <param name="message">
+        /// The message.
+        /// </param>
+        public LogEventArgs(LogMessage message)
+        {
+            this.Log = message;
+        }
+
+        /// <summary>
+        /// Gets the Message.
+        /// </summary>
+        public LogMessage Log { get; private set; }
+    }
+}
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Logging/Interfaces/ILog.cs b/win/CS/HandBrake.ApplicationServices/Services/Logging/Interfaces/ILog.cs
new file mode 100644 (file)
index 0000000..dc0b3c0
--- /dev/null
@@ -0,0 +1,87 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ILog.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>
+//   Defines the ILog type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services.Logging.Interfaces
+{
+    using System;
+    using System.Collections.Generic;
+
+    using EventArgs;
+
+    using Model;
+
+    /// <summary>
+    /// The Log interface.
+    /// </summary>
+    public interface ILog
+    {
+        /// <summary>
+        /// The message logged.
+        /// </summary>
+        event EventHandler<LogEventArgs> MessageLogged;
+
+        /// <summary>
+        /// The log reset event
+        /// </summary>
+        event EventHandler LogReset;
+
+        /// <summary>
+        /// Gets the log messages.
+        /// </summary>
+        IEnumerable<LogMessage> LogMessages { get; }
+
+        /// <summary>
+        /// Gets the activity log.
+        /// </summary>
+        string ActivityLog { get; }
+
+        /// <summary>
+        /// The reset.
+        /// </summary>
+        void Reset();
+
+        /// <summary>
+        /// The enable.
+        /// </summary>
+        void Enable();
+
+        /// <summary>
+        /// Log a message.
+        /// </summary>
+        /// <param name="content">
+        /// The content of the log message,
+        /// </param>
+        /// <param name="type">
+        /// The Message Type. (i.e. where it came from)
+        /// </param>
+        /// <param name="level">
+        /// The log level
+        /// </param>
+        void LogMessage(string content, LogMessageType type, LogLevel level);
+
+        /// <summary>
+        /// Enable Logging to Disk
+        /// </summary>
+        /// <param name="logFile">
+        /// The log file to write to.
+        /// </param>
+        /// <param name="deleteCurrentLogFirst">
+        /// Delete the current log file if it exists.
+        /// </param>
+        void EnableLoggingToDisk(string logFile, bool deleteCurrentLogFirst);
+
+        /// <summary>
+        /// The setup log header.
+        /// </summary>
+        /// <param name="header">
+        /// The header.
+        /// </param>
+        void SetupLogHeader(string header);
+    }
+}
\ No newline at end of file
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Logging/LogHelper.cs b/win/CS/HandBrake.ApplicationServices/Services/Logging/LogHelper.cs
deleted file mode 100644 (file)
index 44ccc75..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------\r
-// <copyright file="LogHelper.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 log service.\r
-//   For now, this is just a simple logging service but we could provide support for a formal logging library later.\r
-//   Also, we can consider providing the UI layer with more functional logging. (i.e levels, time/date, highlighting etc)\r
-//   The Interop Classes are not very OO friendly, so this is going to be a static class.\r
-// </summary>\r
-// --------------------------------------------------------------------------------------------------------------------\r
-\r
-namespace HandBrake.ApplicationServices.Services.Logging\r
-{\r
-    using System.Diagnostics;\r
-\r
-    using HandBrake.ApplicationServices.Services.Logging.Model;\r
-\r
-    /// <summary>\r
-    /// The log helper.\r
-    /// </summary>\r
-    public static class LogHelper\r
-    {\r
-        private static LogLevel currentLogLevel = LogLevel.debug; // TODO default to Info when this class is implimented. \r
-\r
-        /// <summary>\r
-        /// Log message.\r
-        /// </summary>\r
-        /// <param name="message">\r
-        /// The message.\r
-        /// </param>\r
-        public static void LogMessage(LogMessage message)\r
-        {\r
-            if (message.LogLevel <= currentLogLevel)\r
-            {\r
-                //Debug.WriteLine(message.Content);\r
-            }\r
-\r
-            // TODO cache logging.         \r
-        }\r
-\r
-        /// <summary>\r
-        /// The set log level. Default: Info.\r
-        /// </summary>\r
-        /// <param name="level">\r
-        /// The level.\r
-        /// </param>\r
-        public static void SetLogLevel(LogLevel level)\r
-        {\r
-            currentLogLevel = level;\r
-        }\r
-    }\r
-}\r
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Logging/LogService.cs b/win/CS/HandBrake.ApplicationServices/Services/Logging/LogService.cs
new file mode 100644 (file)
index 0000000..cd0d5a4
--- /dev/null
@@ -0,0 +1,361 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="LogService.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 log service.
+//   For now, this is just a simple logging service but we could provide support for a formal logging library later.
+//   Also, we can consider providing the UI layer with more functional logging. (i.e levels, time/date, highlighting etc)
+//   The Interop Classes are not very OO friendly, so this is going to be a static class.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services.Logging
+{
+    using System;
+    using System.Collections.Generic;
+    using System.Diagnostics;
+    using System.IO;
+    using System.Text;
+
+    using HandBrake.ApplicationServices.Services.Logging.EventArgs;
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;
+    using HandBrake.ApplicationServices.Services.Logging.Model;
+
+    /// <summary>
+    /// The log helper.
+    /// </summary>
+    public class LogService : ILog
+    {
+        // TODO List.
+        // Maybe make the event weak?
+        // Make this class Thread Safe.
+        private static ILog loggerInstance;
+        private readonly object lockObject = new object();
+        private readonly object FileWriterLock = new object();
+        private readonly StringBuilder logBuilder = new StringBuilder();
+        private LogLevel currentLogLevel = LogLevel.Error;
+        private bool isLoggingEnabled;
+        private List<LogMessage> logMessages = new List<LogMessage>(); 
+        private long messageIndex;
+        private string diskLogPath;
+        private bool deleteLogFirst;
+        private bool isDiskLoggingEnabled;
+        private StreamWriter fileWriter;
+        private string logHeader;
+
+        /// <summary>
+        /// Fires when a new QueueTask starts
+        /// </summary>
+        public event EventHandler<LogEventArgs> MessageLogged;
+
+        /// <summary>
+        /// The log reset event
+        /// </summary>
+        public event EventHandler LogReset;
+
+        /// <summary>
+        /// Gets the log messages.
+        /// </summary>
+        public IEnumerable<LogMessage> LogMessages
+        {
+            get
+            {
+                lock (this.lockObject)
+                {
+                    return this.logMessages;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the Activity Log as a string.
+        /// </summary>
+        public string ActivityLog
+        {
+            get
+            {
+                lock (this.lockObject)
+                {
+                    return this.logBuilder.ToString();
+                }
+            }
+        }
+
+        /// <summary>
+        /// Log message.
+        /// </summary>
+        /// <param name="content">
+        /// The content.
+        /// </param>
+        /// <param name="type">
+        /// The type.
+        /// </param>
+        /// <param name="level">
+        /// The level.
+        /// </param>
+        public void LogMessage(string content, LogMessageType type, LogLevel level)
+        {
+            if (!this.isLoggingEnabled)
+            {
+                return;
+            }
+
+            if (level >= this.currentLogLevel)
+            {
+                return;
+            }
+
+            LogMessage msg = new LogMessage(content, type, level, this.messageIndex);
+            lock (this.lockObject)
+            {
+                this.messageIndex = this.messageIndex + 1;   
+                this.logMessages.Add(msg);
+                this.logBuilder.AppendLine(msg.Content);
+                this.LogMessageToDisk(msg);
+
+                if (this.logMessages.Count > 50000)
+                {
+                    this.messageIndex = this.messageIndex + 1;
+                    msg = new LogMessage(
+                            "Log Service Pausing. Too Many Log messages. This may indicate a problem with your encode.",
+                            LogMessageType.Vital,
+                            LogLevel.Error,
+                            this.messageIndex);
+                    this.logMessages.Add(msg);
+                    this.logBuilder.AppendLine(msg.Content);
+                    this.LogMessageToDisk(msg);
+
+                    this.Disable();
+                }
+            }
+
+            this.OnMessageLogged(msg); // Must be outside lock to be thread safe. 
+        }
+
+        /// <summary>
+        /// Gets an shared instance of the logger. Logging is enabled by default
+        /// You can turn it off by calling Disable() if you don't want it.
+        /// </summary>
+        /// <returns>
+        /// An instance of this logger.
+        /// </returns>
+        public static ILog GetLogger()
+        {
+            return loggerInstance ?? (loggerInstance = new LogService());
+        }
+
+        /// <summary>
+        /// The set log level. Default: Info.
+        /// </summary>
+        /// <param name="level">
+        /// The level.
+        /// </param>
+        public void SetLogLevel(LogLevel level)
+        {
+            this.currentLogLevel = level;
+        }
+
+        /// <summary>
+        /// The enable.
+        /// </summary>
+        public void Enable()
+        {
+            this.isLoggingEnabled = true;
+        }
+
+        /// <summary>
+        /// Enable Logging to Disk
+        /// </summary>
+        /// <param name="logFile">
+        /// The log file to write to.
+        /// </param>
+        /// <param name="deleteCurrentLogFirst">
+        /// Delete the current log file if it exists.
+        /// </param>
+        public void EnableLoggingToDisk(string logFile, bool deleteCurrentLogFirst)
+        {
+            if (this.isDiskLoggingEnabled)
+            {
+                throw new Exception("Disk Logging already enabled!");
+            }
+
+            try
+            {
+                if (!Directory.Exists(Path.GetDirectoryName(logFile)))
+                {
+                    throw new Exception("Log Directory does not exist. This service will not create it for you!");
+                }
+
+                if (deleteCurrentLogFirst && File.Exists(logFile))
+                {
+                    File.Delete(logFile);
+                }
+
+                this.diskLogPath = logFile;
+                this.isDiskLoggingEnabled = true;
+                this.deleteLogFirst = deleteCurrentLogFirst;
+
+                lock (this.FileWriterLock)
+                {
+                    this.fileWriter = new StreamWriter(logFile) { AutoFlush = true };
+                }
+            }
+            catch (Exception exc)
+            {
+                this.LogMessage("Failed to Initialise Disk Logging. " + Environment.NewLine + exc, LogMessageType.Vital, LogLevel.Error);
+
+                if (this.fileWriter != null)
+                {
+                    lock (this.FileWriterLock)
+                    {
+                        this.fileWriter.Flush();
+                        this.fileWriter.Close();
+                        this.fileWriter.Dispose();
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// The setup log header.
+        /// </summary>
+        /// <param name="header">
+        /// The header.
+        /// </param>
+        public void SetupLogHeader(string header)
+        {
+            this.logHeader = header;
+            this.LogMessage(header, LogMessageType.Vital, LogLevel.Info);
+        }
+
+        /// <summary>
+        /// The disable.
+        /// </summary>
+        public void Disable()
+        {
+            this.isLoggingEnabled = false;
+        }
+
+        /// <summary>
+        /// Clear the log messages collection.
+        /// </summary>
+        public void Reset()
+        {
+            lock (this.lockObject)
+            {
+                this.logMessages.Clear();
+                this.logBuilder.Clear();
+                this.messageIndex = 0;
+               
+                try
+                {
+                    lock (this.FileWriterLock)
+                    {
+                        if (this.fileWriter != null)
+                        {
+                            this.fileWriter.Flush();
+                            this.fileWriter.Close();
+                            this.fileWriter.Dispose();
+                        }
+
+                        this.fileWriter = null;
+                    }
+                }
+                catch (Exception exc)
+                {
+                    Debug.WriteLine(exc);
+                }
+
+                if (this.fileWriter == null)
+                {
+                    this.isDiskLoggingEnabled = false;
+                    this.EnableLoggingToDisk(this.diskLogPath, this.deleteLogFirst);
+                }
+
+                if (!string.IsNullOrEmpty(this.logHeader))
+                {
+                    this.SetupLogHeader(this.logHeader);
+                }
+
+                this.OnLogReset();
+            }
+        }
+
+        /// <summary>
+        /// Helper method for logging content to disk
+        /// </summary>
+        /// <param name="msg">
+        /// Log message to write.
+        /// </param>
+        private void LogMessageToDisk(LogMessage msg)
+        {
+            if (!this.isDiskLoggingEnabled)
+            {
+                return;
+            }
+
+            try
+            {
+                lock (this.FileWriterLock)
+                {
+                    if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
+                    {
+                        this.fileWriter.WriteLine(msg.Content);
+                    }
+                }
+            }
+            catch (Exception exc)
+            {
+                Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
+            }
+        }
+
+        /// <summary>
+        /// Called when a log message is created.
+        /// </summary>
+        /// <param name="msg">
+        /// The Log Message
+        /// </param>
+        protected virtual void OnMessageLogged(LogMessage msg)
+        {
+            var onMessageLogged = this.MessageLogged;
+            if (onMessageLogged != null)
+            {
+                onMessageLogged.Invoke(this, new LogEventArgs(msg));
+            }
+        }
+
+        /// <summary>
+        /// Shutdown and Dispose of the File Writer.
+        /// </summary>
+        protected void ShutdownFileWriter()
+        {
+            try
+            {
+                lock (this.FileWriterLock)
+                {
+                    if (this.fileWriter != null)
+                    {
+                        this.fileWriter.Flush();
+                        this.fileWriter.Close();
+                        this.fileWriter.Dispose();
+                    }
+
+                    this.fileWriter = null;
+                }
+            }
+            catch (Exception exc)
+            {
+                Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
+            }
+        }
+
+        // Trigger the Event to notify any subscribers that the log has been reset.
+        protected virtual void OnLogReset()
+        {
+            this.LogReset?.Invoke(this, System.EventArgs.Empty);
+        }
+    }
+}
index c2e2b8f0a8da536a421869d7e81510b6a52e1d0c..a319ae385616b8cc7c487e6f20fe1f0eabbfb5b2 100644 (file)
@@ -17,21 +17,26 @@ namespace HandBrake.ApplicationServices.Services.Logging.Model
         /// <summary>\r
         /// The info.\r
         /// </summary>\r
-        info,\r
+        Info,\r
 \r
         /// <summary>\r
         /// The warning.\r
         /// </summary>\r
-        warning, \r
+        Warning, \r
 \r
         /// <summary>\r
         /// The error.\r
         /// </summary>\r
-        error,      \r
+        Error,      \r
         \r
         /// <summary>\r
         /// The debug.\r
         /// </summary>\r
-        debug, \r
+        Debug,\r
+        \r
+        /// <summary>\r
+        /// Trace Level Logging.\r
+        /// </summary>\r
+        Trace, \r
     }\r
 }\r
index 9179e2fa5cbefa772b8434c3e645016cc7ff741d..edf071ba1c4e6c12ee14e464c7ce672e4bfc5d66 100644 (file)
@@ -10,7 +10,7 @@
 namespace HandBrake.ApplicationServices.Services.Logging.Model\r
 {\r
     /// <summary>\r
-    /// The json message.\r
+    /// An Immutable Log Entry.\r
     /// </summary>\r
     public class LogMessage\r
     {\r
@@ -26,11 +26,15 @@ namespace HandBrake.ApplicationServices.Services.Logging.Model
         /// <param name="logLevel">\r
         /// The log level.\r
         /// </param>\r
-        public LogMessage(string content, LogMessageType messageType, LogLevel logLevel)\r
+        /// <param name="messageIndex">\r
+        /// The message Index.\r
+        /// </param>\r
+        public LogMessage(string content, LogMessageType messageType, LogLevel logLevel, long messageIndex)\r
         {\r
             this.Content = content;\r
             this.MessageType = messageType;\r
             this.LogLevel = logLevel;\r
+            this.MessageIndex = messageIndex;\r
         }\r
 \r
         /// <summary>\r
@@ -48,5 +52,10 @@ namespace HandBrake.ApplicationServices.Services.Logging.Model
         /// Gets the log level.\r
         /// </summary>\r
         public LogLevel LogLevel { get; private set; }\r
+\r
+        /// <summary>\r
+        /// Gets the message index.\r
+        /// </summary>\r
+        public long MessageIndex { get; private set; }\r
     }\r
 }\r
index df0ce0fc3dd3471c4a874b17211f81bc68d3545d..47302a8728f021572418f87bdd59a6de066a54bf 100644 (file)
@@ -14,10 +14,9 @@ namespace HandBrake.ApplicationServices.Services.Logging.Model
     /// </summary>\r
     public enum LogMessageType\r
     {\r
-        scanJson,\r
-        encodeJson,\r
-        anamorphicJson,\r
-        progressJson,\r
-        libhb,\r
+        ScanOrEncode,\r
+        API,\r
+        Progress,\r
+        Vital,\r
     }\r
 }\r
index 1acc9cccc4a6a0f376827ba1eb0441d5bd791d0d..12665c0620b726e1359c5ea038858637571f7144 100644 (file)
@@ -277,6 +277,15 @@ namespace HandBrake.ApplicationServices.Utilities
             return iso6392Codes;\r
         }\r
 \r
+        /// <summary>\r
+        /// The get language names.\r
+        /// </summary>\r
+        /// <param name="languageCodes">\r
+        /// The language codes.\r
+        /// </param>\r
+        /// <returns>\r
+        /// The <see cref="List"/>.\r
+        /// </returns>\r
         public static List<string> GetLanguageNames(IList<string> languageCodes)\r
         {\r
             // Translate to Iso Codes\r
index 4b4dd7b814247bd929b80d92a9075d8b268e464b..c2dd50a5494914fda15ba3ade5238c919f2e6042 100644 (file)
     <Compile Include="EventArgs\SettingChangedEventArgs.cs" />\r
     <Compile Include="Exceptions\GeneralApplicationException.cs" />\r
     <Compile Include="Extensions\StringExtensions.cs" />\r
+    <Compile Include="Helpers\LogManager.cs" />\r
     <Compile Include="Helpers\MP4Helper.cs" />\r
     <Compile Include="Helpers\TimeSpanHelper.cs" />\r
     <Compile Include="Helpers\Validate.cs" />\r
diff --git a/win/CS/HandBrakeWPF/Helpers/LogManager.cs b/win/CS/HandBrakeWPF/Helpers/LogManager.cs
new file mode 100644 (file)
index 0000000..4e883f8
--- /dev/null
@@ -0,0 +1,49 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="LogManager.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 log manager.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Helpers
+{
+    using System;
+    using System.IO;
+
+    using HandBrake.ApplicationServices.Interop;
+    using HandBrake.ApplicationServices.Services.Logging;
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;
+
+    using HandBrakeWPF.Utilities;
+
+    /// <summary>
+    /// Tempory Class to Initialise the logging.
+    /// </summary>
+    public static class LogManager
+    {
+        /// <summary>
+        /// The init.
+        /// </summary>
+        public static void Init()
+        {
+            ILog log = LogService.GetLogger();
+            string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
+            string logFile = Path.Combine(logDir, string.Format("activity_log{0}.txt", GeneralUtilities.ProcessId));
+            log.Enable();
+            log.SetupLogHeader(GeneralUtilities.CreateLogHeader().ToString());
+            log.EnableLoggingToDisk(logFile, true);
+            HandBrakeUtils.MessageLogged += HandBrakeUtils_MessageLogged;
+            HandBrakeUtils.ErrorLogged += HandBrakeUtils_ErrorLogged;
+        }
+
+        private static void HandBrakeUtils_ErrorLogged(object sender, HandBrake.ApplicationServices.Interop.EventArgs.MessageLoggedEventArgs e)
+        {
+        }
+
+        private static void HandBrakeUtils_MessageLogged(object sender, HandBrake.ApplicationServices.Interop.EventArgs.MessageLoggedEventArgs e)
+        {
+        }
+    }
+}
\ No newline at end of file
index 9ae0398ee214895f04daf7e62bc9ded2d58c2ce8..801a8c9cc832c5501ed45119d6ea9120c5d6663f 100644 (file)
@@ -13,11 +13,10 @@ namespace HandBrakeWPF.Services.Encode
     using System.Diagnostics;
     using System.Globalization;
     using System.IO;
-    using System.Text;
 
     using HandBrake.ApplicationServices.Model;
-
-    using HandBrakeWPF.Utilities;
+    using HandBrake.ApplicationServices.Services.Logging;
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;
 
     using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs;
     using EncodeCompletedStatus = HandBrakeWPF.Services.Encode.Interfaces.EncodeCompletedStatus;
@@ -31,38 +30,11 @@ namespace HandBrakeWPF.Services.Encode
     /// </summary>
     public class EncodeBase
     {
-        #region Private Variables
-
-        /// <summary>
-        /// A Lock for the filewriter
-        /// </summary>
-        private static readonly object FileWriterLock = new object();
-
-        /// <summary>
-        /// The Log File Header
-        /// </summary>
-        private readonly StringBuilder header;
-
-        /// <summary>
-        /// The Log Buffer
-        /// </summary>
-        private StringBuilder logBuffer;
-
-        /// <summary>
-        /// The Log file writer
-        /// </summary>
-        private StreamWriter fileWriter;
-
-        #endregion
-
         /// <summary>
         /// Initializes a new instance of the <see cref="EncodeBase"/> class.
         /// </summary>
         public EncodeBase()
-        {
-            this.logBuffer = new StringBuilder();
-            this.header = GeneralUtilities.CreateLogHeader();
-            this.LogIndex = 0;
+        {    
         }
 
         #region Events
@@ -91,39 +63,6 @@ namespace HandBrakeWPF.Services.Encode
         /// </summary>
         public bool IsEncoding { get; protected set; }
 
-        /// <summary>
-        /// Gets ActivityLog.
-        /// </summary>
-        public string ActivityLog
-        {
-            get
-            {
-                string noLog = "There is no log information to display." + Environment.NewLine + Environment.NewLine
-                 + "This window will only display logging information after you have started an encode." + Environment.NewLine
-                 + Environment.NewLine + "You can find previous log files in the log directory or by clicking the 'Open Log Directory' button above.";
-                
-                return string.IsNullOrEmpty(this.logBuffer.ToString())
-                           ? noLog
-                           : this.header + this.logBuffer.ToString();
-            }
-        }
-
-        /// <summary>
-        /// Gets the log index.
-        /// </summary>
-        public int LogIndex { get; private set; }
-
-        /// <summary>
-        /// Gets LogBuffer.
-        /// </summary>
-        public StringBuilder LogBuffer
-        {
-            get
-            {
-                return this.logBuffer;
-            }
-        }
-
         #endregion
 
         #region Invoke Events
@@ -156,8 +95,6 @@ namespace HandBrakeWPF.Services.Encode
             {
                 handler(this, e);
             }
-
-            this.LogIndex = 0; // Reset
         }
 
         /// <summary>
@@ -186,6 +123,9 @@ namespace HandBrakeWPF.Services.Encode
         /// <param name="destination">
         /// The Destination File Path
         /// </param>
+        /// <param name="isPreview">
+        /// The is Preview.
+        /// </param>
         /// <param name="configuration">
         /// The configuration.
         /// </param>
@@ -193,15 +133,12 @@ namespace HandBrakeWPF.Services.Encode
         {
             try
             {
-                string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
-                                "\\HandBrake\\logs";
-
-                string tempLogFile = Path.Combine(logDir, isPreview ? $"preview_encode_log{GeneralUtilities.ProcessId}.txt" : string.Format("last_encode_log{0}.txt", GeneralUtilities.ProcessId));
-
+                string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
                 string encodeDestinationPath = Path.GetDirectoryName(destination);
                 string destinationFile = Path.GetFileName(destination);
-                string encodeLogFile = destinationFile + " " +
-                                       DateTime.Now.ToString(CultureInfo.InvariantCulture).Replace("/", "-").Replace(":", "-") + ".txt";
+                string encodeLogFile = destinationFile + " " + DateTime.Now.ToString(CultureInfo.InvariantCulture).Replace("/", "-").Replace(":", "-") + ".txt";
+                ILog log = LogService.GetLogger();
+                string logContent = log.ActivityLog;
 
                 // Make sure the log directory exists.
                 if (!Directory.Exists(logDir))
@@ -210,19 +147,18 @@ namespace HandBrakeWPF.Services.Encode
                 }
 
                 // Copy the Log to HandBrakes log folder in the users applciation data folder.
-                File.Copy(tempLogFile, Path.Combine(logDir, encodeLogFile));
+                this.WriteFile(logContent, Path.Combine(logDir, encodeLogFile));
 
                 // Save a copy of the log file in the same location as the enocde.
                 if (configuration.SaveLogWithVideo)
                 {
-                    File.Copy(tempLogFile, Path.Combine(encodeDestinationPath, encodeLogFile));
+                    this.WriteFile(logContent, Path.Combine(encodeDestinationPath, encodeLogFile));
                 }
 
                 // Save a copy of the log file to a user specified location
                 if (Directory.Exists(configuration.SaveLogCopyDirectory) && configuration.SaveLogToCopyDirectory)
                 {
-                    File.Copy(
-                        tempLogFile, Path.Combine(configuration.SaveLogCopyDirectory, encodeLogFile));
+                    this.WriteFile(logContent, Path.Combine(configuration.SaveLogCopyDirectory, encodeLogFile));
                 }
             }
             catch (Exception exc)
@@ -232,116 +168,26 @@ namespace HandBrakeWPF.Services.Encode
         }
 
         /// <summary>
-        /// Setup the logging.
+        /// The write file.
         /// </summary>
-        protected void SetupLogging(bool isPreviewEncode)
-        {
-            this.ShutdownFileWriter();
-            string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
-            string logFile = Path.Combine(logDir, isPreviewEncode ? $"preview_last_encode_log{GeneralUtilities.ProcessId}.txt" : $"last_encode_log{GeneralUtilities.ProcessId}.txt");
-
-            try
-            {
-                this.logBuffer = new StringBuilder();
-
-                this.logBuffer.AppendLine();
-
-                // Clear the current Encode Logs)
-                if (File.Exists(logFile))
-                {
-                    File.Delete(logFile);
-                }
-
-                lock (FileWriterLock)
-                {
-                    this.fileWriter = new StreamWriter(logFile) { AutoFlush = true };
-                    this.fileWriter.WriteLine(this.header);
-                    this.fileWriter.WriteLine();
-                }
-            }
-            catch (Exception)
-            {
-                if (this.fileWriter != null)
-                {
-                    lock (FileWriterLock)
-                    {
-                        this.fileWriter.Flush();
-                        this.fileWriter.Close();
-                        this.fileWriter.Dispose();
-                    }                
-                }
-
-                throw;
-            }
-        }
-
-        /// <summary>
-        /// The service log message.
-        /// </summary>
-        /// <param name="message">
-        /// The message.
+        /// <param name="fileName">
+        /// The file name.
         /// </param>
-        protected void ServiceLogMessage(string message)
-        {
-            this.ProcessLogMessage(string.Format("# {0}", message));
-        }
-
-        /// <summary>
-        /// Process an Incomming Log Message.
-        /// </summary>
-        /// <param name="message">
-        /// The message.
+        /// <param name="content">
+        /// The content.
         /// </param>
-        protected void ProcessLogMessage(string message)
-        {
-            if (!string.IsNullOrEmpty(message))
-            {
-                try
-                {
-                    this.LogIndex = this.LogIndex + 1;
-
-                    lock (this.LogBuffer)
-                    {
-                        this.LogBuffer.AppendLine(message);
-                    }
-
-                    lock (FileWriterLock)
-                    {
-                        if (this.fileWriter != null && this.fileWriter.BaseStream.CanWrite)
-                        {
-                            this.fileWriter.WriteLine(message);
-                        }
-                    }
-                }
-                catch (Exception exc)
-                {
-                    Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
-                }
-            }
-        }
-
-        /// <summary>
-        /// Shutdown and Dispose of the File Writer.
-        /// </summary>
-        protected void ShutdownFileWriter()
+        private void WriteFile(string fileName, string content)
         {
             try
             {
-                lock (FileWriterLock)
+                using (StreamWriter fileWriter = new StreamWriter(fileName) { AutoFlush = true })
                 {
-                    if (this.fileWriter != null)
-                    {
-                        this.fileWriter.Flush();
-                        this.fileWriter.Close();
-                        this.fileWriter.Dispose();
-                    }
-
-                    this.fileWriter = null;
+                    fileWriter.WriteLineAsync(content);
                 }
             }
             catch (Exception exc)
             {
-                Debug.WriteLine(exc); // This exception doesn't warrent user interaction, but it should be logged
+                Debug.WriteLine(exc);
             }
         }
 
index 691df150013f423aea3b0757d82d21103b420e72..b9a5f0aff5ecfb65818ddcb76dda44460fd2475d 100644 (file)
@@ -64,16 +64,6 @@ namespace HandBrakeWPF.Services.Encode.Interfaces
         /// </summary>
         bool IsEncoding { get; }
 
-        /// <summary>
-        /// Gets ActivityLog.
-        /// </summary>
-        string ActivityLog { get; }
-
-        /// <summary>
-        /// Gets the log index. The current log row counter.
-        /// </summary>
-        int LogIndex { get; }
-
         /// <summary>
         /// Gets a value indicating whether is pasued.
         /// </summary>
index 4bf64e5e1d919d2fdb86a3c0b9bc00410649351f..e8b920c57af6b5b83a72910d97fcb606d57a8dd2 100644 (file)
@@ -16,6 +16,9 @@ namespace HandBrakeWPF.Services.Encode
     using HandBrake.ApplicationServices.Interop.EventArgs;
     using HandBrake.ApplicationServices.Interop.Interfaces;
     using HandBrake.ApplicationServices.Model;
+    using HandBrake.ApplicationServices.Services.Logging;
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;
+    using HandBrake.ApplicationServices.Services.Logging.Model;
 
     using HandBrakeWPF.Exceptions;
     using HandBrakeWPF.Services.Encode.Factories;
@@ -30,7 +33,7 @@ namespace HandBrakeWPF.Services.Encode
     {
         #region Private Variables
 
-        private static readonly object LogLock = new object();
+        private ILog log = LogService.GetLogger();
         private IHandBrakeInstance instance;
         private DateTime startTime;
         private EncodeTask currentTask;
@@ -70,8 +73,6 @@ namespace HandBrakeWPF.Services.Encode
 
                 // Create a new HandBrake instance
                 // Setup the HandBrake Instance
-                HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged;
-                HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged;
                 this.instance = task.IsPreviewEncode ? HandBrakeInstanceManager.GetPreviewInstance(configuration.Verbosity) : HandBrakeInstanceManager.GetEncodeInstance(configuration.Verbosity);
                 
                 this.instance.EncodeCompleted += this.InstanceEncodeCompleted;
@@ -79,11 +80,11 @@ namespace HandBrakeWPF.Services.Encode
 
                 this.IsEncoding = true;
                 this.isPreviewInstance = task.IsPreviewEncode;
-                this.SetupLogging(task.IsPreviewEncode);
 
                 // Verify the Destination Path Exists, and if not, create it.
                 this.VerifyEncodeDestinationPath(task);
 
+                this.log.Reset(); // Reset so we have a clean log for the start of the encode.
                 this.ServiceLogMessage("Starting Encode ...");
 
                 // Get an EncodeJob object for the Interop Library
@@ -97,7 +98,7 @@ namespace HandBrakeWPF.Services.Encode
                 this.IsEncoding = false;
 
                 this.ServiceLogMessage("Failed to start encoding ..." + Environment.NewLine + exc);
-                this.InvokeEncodeCompleted(new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source));
+                this.InvokeEncodeCompleted(new EventArgs.EncodeCompletedEventArgs(false, exc, "Unable to start encoding", task.Source));
             }
         }
 
@@ -149,40 +150,6 @@ namespace HandBrakeWPF.Services.Encode
 
         #region HandBrakeInstance Event Handlers.
 
-        /// <summary>
-        /// Log a message
-        /// </summary>
-        /// <param name="sender">
-        /// The sender.
-        /// </param>
-        /// <param name="e">
-        /// The MessageLoggedEventArgs.
-        /// </param>
-        private void HandBrakeInstanceErrorLogged(object sender, MessageLoggedEventArgs e)
-        {
-            lock (LogLock)
-            {
-                this.ProcessLogMessage(e.Message);
-            }
-        }
-
-        /// <summary>
-        /// Log a message
-        /// </summary>
-        /// <param name="sender">
-        /// The sender.
-        /// </param>
-        /// <param name="e">
-        /// The MessageLoggedEventArgs.
-        /// </param>
-        private void HandBrakeInstanceMessageLogged(object sender, MessageLoggedEventArgs e)
-        {
-            lock (LogLock)
-            {
-                this.ProcessLogMessage(e.Message);
-            }
-        }
-
         /// <summary>
         /// Encode Progress Event Handler
         /// </summary>
@@ -194,7 +161,7 @@ namespace HandBrakeWPF.Services.Encode
         /// </param>
         private void InstanceEncodeProgress(object sender, EncodeProgressEventArgs e)
         {
-           HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs args = new HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs
+            EventArgs.EncodeProgressEventArgs args = new EventArgs.EncodeProgressEventArgs
             {
                 AverageFrameRate = e.AverageFrameRate, 
                 CurrentFrameRate = e.CurrentFrameRate, 
@@ -221,22 +188,24 @@ namespace HandBrakeWPF.Services.Encode
         {
             this.IsEncoding = false;
             this.ServiceLogMessage("Encode Completed ...");
-
-            // Stop Logging.
-            HandBrakeUtils.MessageLogged -= this.HandBrakeInstanceMessageLogged;
-            HandBrakeUtils.ErrorLogged -= this.HandBrakeInstanceErrorLogged;
-            
+           
             // Handling Log Data 
             this.ProcessLogs(this.currentTask.Destination, this.isPreviewInstance, this.currentConfiguration);
 
-            // Cleanup
-            this.ShutdownFileWriter();
-
             // Raise the Encode Completed EVent.
             this.InvokeEncodeCompleted(
                 e.Error
-                    ? new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(false, null, string.Empty, this.currentTask.Destination)
-                    : new HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs(true, null, string.Empty, this.currentTask.Destination));
+                    ? new EventArgs.EncodeCompletedEventArgs(false, null, string.Empty, this.currentTask.Destination)
+                    : new EventArgs.EncodeCompletedEventArgs(true, null, string.Empty, this.currentTask.Destination));
+        }
+
+        /// <summary>
+        /// Service Log Message.
+        /// </summary>
+        /// <param name="message">Log message content</param>
+        protected void ServiceLogMessage(string message)
+        {
+            this.log.LogMessage(string.Format("# {0}", message), LogMessageType.ScanOrEncode, LogLevel.Info);
         }
         #endregion
     }
index 0af5f30ec3f9aa3225a5f898e45b6e2bb475755d..4336574aa3480eb63486dd3a04635989b751c397 100644 (file)
@@ -65,11 +65,6 @@ namespace HandBrakeWPF.Services.Scan.Interfaces
         /// </summary>
         bool IsScanning { get; }
 
-        /// <summary>
-        /// Gets ActivityLog.
-        /// </summary>
-        string ActivityLog { get; }
-
         /// <summary>
         /// Scan a Source Path.
         /// Title 0: scan all
index 3d9d475a1abce12dfbbff17474042e6935bd4d30..d72593cff0741cc986840e8c13fe53f849429465 100644 (file)
@@ -12,19 +12,18 @@ namespace HandBrakeWPF.Services.Scan
     using System;
     using System.Collections.Generic;
     using System.Diagnostics;
-    using System.IO;
-    using System.Text;
     using System.Windows.Media.Imaging;
 
     using HandBrake.ApplicationServices.Interop;
-    using HandBrake.ApplicationServices.Interop.EventArgs;
     using HandBrake.ApplicationServices.Interop.HbLib;
     using HandBrake.ApplicationServices.Interop.Interfaces;
     using HandBrake.ApplicationServices.Interop.Json.Scan;
     using HandBrake.ApplicationServices.Interop.Model;
     using HandBrake.ApplicationServices.Interop.Model.Preview;
     using HandBrake.ApplicationServices.Model;
-    using HandBrake.ApplicationServices.Utilities;
+    using HandBrake.ApplicationServices.Services.Logging;
+    using HandBrake.ApplicationServices.Services.Logging.Interfaces;
+    using HandBrake.ApplicationServices.Services.Logging.Model;
 
     using HandBrakeWPF.Properties;
     using HandBrakeWPF.Services.Encode.Model;
@@ -32,7 +31,6 @@ namespace HandBrakeWPF.Services.Scan
     using HandBrakeWPF.Services.Scan.EventArgs;
     using HandBrakeWPF.Services.Scan.Interfaces;
     using HandBrakeWPF.Services.Scan.Model;
-    using HandBrakeWPF.Utilities;
 
     using Chapter = HandBrakeWPF.Services.Scan.Model.Chapter;
     using ScanProgressEventArgs = HandBrake.ApplicationServices.Interop.EventArgs.ScanProgressEventArgs;
@@ -46,54 +44,10 @@ namespace HandBrakeWPF.Services.Scan
     {
         #region Private Variables
 
-        /// <summary>
-        /// Lock for the log file
-        /// </summary>
-        static readonly object LogLock = new object();
-
-        /// <summary>
-        /// Log data from HandBrakeInstance
-        /// </summary>
-        private readonly StringBuilder logging;
-
-        /// <summary>
-        /// The Log File Header
-        /// </summary>
-        private readonly StringBuilder header;
-
-        /// <summary>
-        /// The Current source scan path.
-        /// </summary>
+        private readonly ILog log = LogService.GetLogger();
         private string currentSourceScanPath;
-
-        /// <summary>
-        /// The log dir.
-        /// </summary>
-        private static string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs";
-
-        /// <summary>
-        /// The dvd info path.
-        /// </summary>
-        private string dvdInfoPath = Path.Combine(logDir, string.Format("last_scan_log{0}.txt", GeneralUtilities.ProcessId));
-
-        /// <summary>
-        /// The scan log.
-        /// </summary>
-        private StreamWriter scanLog;
-
-        /// <summary>
-        /// LibHB Instance
-        /// </summary>
         private IHandBrakeInstance instance;
-
-        /// <summary>
-        /// The post scan operation.
-        /// </summary>
         private Action<bool, Source> postScanOperation;
-
-        /// <summary>
-        /// Global to handle cancelled scans.
-        /// </summary>
         private bool isCancelled = false;
 
         #endregion
@@ -103,8 +57,6 @@ namespace HandBrakeWPF.Services.Scan
         /// </summary>
         public LibScan()
         {
-            this.logging = new StringBuilder();
-            this.header = GeneralUtilities.CreateLogHeader();
             this.IsScanning = false;
         }
 
@@ -134,21 +86,6 @@ namespace HandBrakeWPF.Services.Scan
         /// </summary>
         public bool IsScanning { get; private set; }
 
-        /// <summary>
-        /// Gets ActivityLog.
-        /// </summary>
-        public string ActivityLog
-        {
-            get
-            {
-                string noLog = "There is no log information to display." + Environment.NewLine + Environment.NewLine
-                                + "This window will only display logging information after you have scanned a source." + Environment.NewLine
-                                + Environment.NewLine + "You can find previous log files in the log directory or by clicking the 'Open Log Directory' button above.";
-
-                return string.IsNullOrEmpty(this.logging.ToString()) ? noLog : this.header + this.logging.ToString();
-            }
-        }
-
         #endregion
 
         #region Public Methods
@@ -176,12 +113,6 @@ namespace HandBrakeWPF.Services.Scan
             {
                 try
                 {
-                    lock (LogLock)
-                    {
-                        this.scanLog.Close();
-                        this.scanLog.Dispose();
-                        this.scanLog = null;
-                    }
                     this.instance.Dispose();
                 }
                 catch (Exception)
@@ -193,33 +124,7 @@ namespace HandBrakeWPF.Services.Scan
             // Handle the post scan operation.
             this.postScanOperation = postAction;
 
-            // Clear down the logging
-            this.logging.Clear();
-
-            try
-            {
-                // Make we don't pick up a stale last_scan_log_xyz.txt (and that we have rights to the file)
-                if (File.Exists(this.dvdInfoPath))
-                {
-                    File.Delete(this.dvdInfoPath);
-                }
-            }
-            catch (Exception exc)
-            {
-                Debug.WriteLine(exc);
-            }
-
-            if (!Directory.Exists(Path.GetDirectoryName(this.dvdInfoPath)))
-            {
-                Directory.CreateDirectory(Path.GetDirectoryName(this.dvdInfoPath));
-            }
-
-            // Create a new scan log.
-            this.scanLog = new StreamWriter(this.dvdInfoPath);
-
             // Create a new HandBrake Instance.
-            HandBrakeUtils.MessageLogged += this.HandBrakeInstanceMessageLogged;
-            HandBrakeUtils.ErrorLogged += this.HandBrakeInstanceErrorLogged;
             this.instance = HandBrakeInstanceManager.GetScanInstance(configuraiton.Verbosity);
             this.instance.ScanProgress += this.InstanceScanProgress;
             this.instance.ScanCompleted += this.InstanceScanCompleted;
@@ -238,16 +143,6 @@ namespace HandBrakeWPF.Services.Scan
                 this.ServiceLogMessage("Stopping Scan.");
                 this.IsScanning = false;
                 this.instance.StopScan();
-
-                lock (LogLock)
-                {
-                    if (this.scanLog != null)
-                    {
-                        this.scanLog.Close();
-                        this.scanLog.Dispose();
-                        this.scanLog = null;
-                    }
-                }
             }
             catch (Exception exc)
             {
@@ -339,8 +234,6 @@ namespace HandBrakeWPF.Services.Scan
         {
             try
             {
-                this.logging.Clear();
-
                 string source = sourcePath.ToString().EndsWith("\\") ? string.Format("\"{0}\\\\\"", sourcePath.ToString().TrimEnd('\\'))
                               : "\"" + sourcePath + "\"";
                 this.currentSourceScanPath = source;
@@ -362,8 +255,7 @@ namespace HandBrakeWPF.Services.Scan
                 this.ServiceLogMessage("Scan Failed ..." + Environment.NewLine + exc);
                 this.Stop();
 
-                if (this.ScanCompleted != null)
-                    this.ScanCompleted(this, new ScanCompletedEventArgs(false, exc, "An Error has occured in ScanService.ScanSource()", null));
+                this.ScanCompleted?.Invoke(this, new ScanCompletedEventArgs(false, exc, "An Error has occured in ScanService.ScanSource()", null));
             }
         }
 
@@ -385,22 +277,6 @@ namespace HandBrakeWPF.Services.Scan
             bool cancelled = this.isCancelled;
             this.isCancelled = false;
 
-            // Write the log file out before we start processing incase we crash.
-            try
-            {
-                if (this.scanLog != null)
-                {
-                    this.scanLog.Flush();
-                }
-            }
-            catch (Exception exc)
-            {
-                Debug.WriteLine(exc);
-            }
-
-            HandBrakeUtils.MessageLogged -= this.HandBrakeInstanceMessageLogged;
-            HandBrakeUtils.ErrorLogged -= this.HandBrakeInstanceErrorLogged;
-
             // TODO -> Might be a better place to fix this.
             string path = this.currentSourceScanPath;
             if (this.currentSourceScanPath.Contains("\""))
@@ -449,8 +325,8 @@ namespace HandBrakeWPF.Services.Scan
         {
             if (this.ScanStatusChanged != null)
             {
-                HandBrakeWPF.Services.Scan.EventArgs.ScanProgressEventArgs eventArgs =
-                    new HandBrakeWPF.Services.Scan.EventArgs.ScanProgressEventArgs
+                EventArgs.ScanProgressEventArgs eventArgs =
+                    new EventArgs.ScanProgressEventArgs
                         {
                             CurrentTitle = e.CurrentTitle,
                             Titles = e.Titles,
@@ -461,34 +337,6 @@ namespace HandBrakeWPF.Services.Scan
             }
         }
 
-        /// <summary>
-        /// Log a message
-        /// </summary>
-        /// <param name="sender">
-        /// The sender.
-        /// </param>
-        /// <param name="e">
-        /// The MessageLoggedEventArgs.
-        /// </param>
-        private void HandBrakeInstanceErrorLogged(object sender, MessageLoggedEventArgs e)
-        {
-            this.LogMessage(e.Message);
-        }
-
-        /// <summary>
-        /// Log a message
-        /// </summary>
-        /// <param name="sender">
-        /// The sender.
-        /// </param>
-        /// <param name="e">
-        /// The MessageLoggedEventArgs.
-        /// </param>
-        private void HandBrakeInstanceMessageLogged(object sender, MessageLoggedEventArgs e)
-        {
-            this.LogMessage(e.Message);
-        }
-
         /// <summary>
         /// Convert Interop Title objects to App Services Title object
         /// </summary>
@@ -586,25 +434,6 @@ namespace HandBrakeWPF.Services.Scan
             return titleList;
         }
 
-        /// <summary>
-        /// The log message.
-        /// </summary>
-        /// <param name="message">
-        /// The message.
-        /// </param>
-        private void LogMessage(string message)
-        {
-            lock (LogLock)
-            {
-                if (this.scanLog != null)
-                {
-                    this.scanLog.WriteLine(message);
-                }
-
-                this.logging.AppendLine(message);
-            }
-        }
-
         /// <summary>
         /// The service log message.
         /// </summary>
@@ -613,7 +442,7 @@ namespace HandBrakeWPF.Services.Scan
         /// </param>
         protected void ServiceLogMessage(string message)
         {
-            this.LogMessage(string.Format("# {0}", message));
+            this.log.LogMessage(string.Format("{0} # {1}{0}", Environment.NewLine, message), LogMessageType.ScanOrEncode, LogLevel.Info);
         }
         #endregion
     }
index 6c7a7a2c8ad121d0fbf58f99977e1dd78769c1f8..6aa1020d4f982a8f76310ed70c07cde45dc0ed98 100644 (file)
@@ -14,9 +14,5 @@ namespace HandBrakeWPF.ViewModels.Interfaces
     /// </summary>\r
     public interface ILogViewModel\r
     {\r
-        /// <summary>\r
-        /// Gets or sets the selected tab.\r
-        /// </summary>\r
-        int SelectedTab { get; set; }\r
     }\r
 }
\ No newline at end of file
index f9a26c1ed3bda658c601cad7542fa823480dc461..572d8a44088a6e26049496a52c2773150eac32c3 100644 (file)
@@ -11,15 +11,18 @@ namespace HandBrakeWPF.ViewModels
 {\r
     using System;\r
     using System.Diagnostics;\r
+    using System.Text;\r
     using System.Windows;\r
 \r
-    using HandBrakeWPF.Services.Scan.EventArgs;\r
-    using HandBrakeWPF.Services.Scan.Interfaces;\r
+    using Caliburn.Micro;\r
+\r
+    using HandBrake.ApplicationServices.Services.Logging;\r
+    using HandBrake.ApplicationServices.Services.Logging.EventArgs;\r
+    using HandBrake.ApplicationServices.Services.Logging.Model;\r
+\r
     using HandBrakeWPF.ViewModels.Interfaces;\r
 \r
-    using EncodeCompletedEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeCompletedEventArgs;\r
-    using EncodeProgressEventArgs = HandBrakeWPF.Services.Encode.EventArgs.EncodeProgressEventArgs;\r
-    using IEncode = HandBrakeWPF.Services.Encode.Interfaces.IEncode;\r
+    using ILog = HandBrake.ApplicationServices.Services.Logging.Interfaces.ILog;\r
 \r
     /// <summary>\r
     /// The Log View Model\r
@@ -28,83 +31,37 @@ namespace HandBrakeWPF.ViewModels
     {\r
         #region Private Fields\r
 \r
-        /// <summary>\r
-        /// Backing field for the encodeService service\r
-        /// </summary>\r
-        private readonly IEncode encodeService;\r
-\r
-        /// <summary>\r
-        /// Backing field for the Scan Service\r
-        /// </summary>\r
-        private readonly IScan scanService;\r
-\r
-        /// <summary>\r
-        /// The selected tab.\r
-        /// </summary>\r
-        private int selectedTab;\r
-\r
-        /// <summary>\r
-        /// The encode log index.\r
-        /// </summary>\r
-        private int encodeLogIndex;\r
+        private readonly ILog logService;\r
+        private StringBuilder log = new StringBuilder();\r
+        private long lastReadIndex;\r
 \r
         #endregion\r
 \r
         /// <summary>\r
         /// Initializes a new instance of the <see cref="LogViewModel"/> class.\r
         /// </summary>\r
-        /// <param name="encodeService">\r
-        /// The encode service.\r
-        /// </param>\r
-        /// <param name="scanService">\r
-        /// The scan service.\r
-        /// </param>\r
-        public LogViewModel(IEncode encodeService, IScan scanService)\r
+        public LogViewModel()\r
         {\r
-            this.encodeService = encodeService;\r
-            this.scanService = scanService;\r
+            this.logService = LogService.GetLogger();\r
             this.Title = "Log Viewer";\r
-            this.encodeLogIndex = 0;\r
-        }\r
-\r
-        /// <summary>\r
-        /// Gets or sets the selected tab.\r
-        /// </summary>\r
-        public int SelectedTab\r
-        {\r
-            get\r
-            {\r
-                return this.selectedTab;\r
-            }\r
-            set\r
-            {\r
-                this.selectedTab = value;\r
-                this.NotifyOfPropertyChange(() => this.SelectedTab);\r
-            }\r
         }\r
 \r
         /// <summary>\r
         /// Gets Log.\r
         /// </summary>\r
-        public string ScanLog\r
+        public string ActivityLog\r
         {\r
             get\r
             {\r
-                return this.scanService.ActivityLog;\r
+                return this.log.ToString();\r
             }\r
         }\r
 \r
         /// <summary>\r
-        /// Gets the encodelog.\r
+        /// The log message received.\r
         /// </summary>\r
-        public string EncodeLog\r
-        {\r
-            get\r
-            {\r
-                return this.encodeService.ActivityLog;\r
-            }\r
-        }\r
-\r
+        public event EventHandler<LogEventArgs> LogMessageReceived;\r
+    \r
         /// <summary>\r
         /// Open the Log file directory\r
         /// </summary>\r
@@ -121,7 +78,7 @@ namespace HandBrakeWPF.ViewModels
         /// </summary>\r
         public void CopyLog()\r
         {\r
-            Clipboard.SetDataObject(this.SelectedTab == 1 ? this.ScanLog : this.EncodeLog, true);\r
+            Clipboard.SetDataObject(this.ActivityLog, true);\r
         }\r
 \r
         /// <summary>\r
@@ -129,49 +86,26 @@ namespace HandBrakeWPF.ViewModels
         /// </summary>\r
         protected override void OnActivate()\r
         {\r
-            this.scanService.ScanCompleted += ScanServiceScanCompleted;\r
-            this.encodeService.EncodeCompleted += EncodeServiceEncodeCompleted;\r
-            this.encodeService.EncodeStatusChanged += this.EncodeServiceEncodeStatusChanged;\r
-            this.scanService.ScanStatusChanged += this.ScanServiceScanStatusChanged;\r
-            this.scanService.ScanStarted += this.scanService_ScanStared;\r
-            this.encodeService.EncodeStarted += this.encodeService_EncodeStarted;\r
-            base.OnActivate();\r
-\r
-            this.NotifyOfPropertyChange(() => this.ScanLog);\r
-            this.NotifyOfPropertyChange(() => this.EncodeLog);\r
-        }\r
-\r
-        /// <summary>\r
-        /// Scan Status has changed, update log window.\r
-        /// </summary>\r
-        /// <param name="sender">\r
-        /// The sender.\r
-        /// </param>\r
-        /// <param name="e">\r
-        /// The e.\r
-        /// </param>\r
-        private void ScanServiceScanStatusChanged(object sender, ScanProgressEventArgs e)\r
-        {\r
-            this.NotifyOfPropertyChange(() => this.ScanLog);\r
-        }\r
+            this.logService.MessageLogged += this.LogService_MessageLogged;\r
+            this.logService.LogReset += LogService_LogReset;\r
 \r
-        /// <summary>\r
-        /// Encode Status has changed, update log window\r
-        /// </summary>\r
-        /// <param name="sender">\r
-        /// The sender.\r
-        /// </param>\r
-        /// <param name="e">\r
-        /// The e.\r
-        /// </param>\r
-        private void EncodeServiceEncodeStatusChanged(object sender, EncodeProgressEventArgs e)\r
-        {\r
-            if (encodeLogIndex != this.encodeService.LogIndex || this.encodeService.LogIndex == -1)\r
+            // Refresh the Log Display\r
+            this.log.Clear();\r
+            foreach (LogMessage logMessage in this.logService.LogMessages)\r
             {\r
-                this.NotifyOfPropertyChange(() => this.EncodeLog);\r
+                this.log.AppendLine(logMessage.Content);\r
+                this.lastReadIndex = logMessage.MessageIndex;\r
+\r
+                if (this.lastReadIndex > logMessage.MessageIndex)\r
+                {\r
+                    throw new Exception("Log Message Index Error");\r
+                }\r
             }\r
 \r
-            encodeLogIndex = this.encodeService.LogIndex;\r
+            this.OnLogMessageReceived(null);\r
+            this.NotifyOfPropertyChange("ActivityLog");\r
+\r
+            base.OnActivate();\r
         }\r
 \r
         /// <summary>\r
@@ -182,18 +116,14 @@ namespace HandBrakeWPF.ViewModels
         /// </param>\r
         protected override void OnDeactivate(bool close)\r
         {\r
-            this.scanService.ScanCompleted -= ScanServiceScanCompleted;\r
-            this.encodeService.EncodeCompleted -= EncodeServiceEncodeCompleted;\r
-            this.encodeService.EncodeStatusChanged -= this.EncodeServiceEncodeStatusChanged;\r
-            this.scanService.ScanStatusChanged -= this.ScanServiceScanStatusChanged;\r
-            this.scanService.ScanStarted -= this.scanService_ScanStared;\r
-            this.encodeService.EncodeStarted -= this.encodeService_EncodeStarted;\r
+            this.logService.MessageLogged -= this.LogService_MessageLogged;\r
+            this.logService.LogReset -= this.LogService_LogReset;\r
 \r
             base.OnDeactivate(close);\r
         }\r
 \r
         /// <summary>\r
-        /// Scan Completed Event Handler.\r
+        /// The log service_ log reset.\r
         /// </summary>\r
         /// <param name="sender">\r
         /// The sender.\r
@@ -201,27 +131,28 @@ namespace HandBrakeWPF.ViewModels
         /// <param name="e">\r
         /// The e.\r
         /// </param>\r
-        private void ScanServiceScanCompleted(object sender, ScanCompletedEventArgs e)\r
+        private void LogService_LogReset(object sender, EventArgs e)\r
         {\r
-            this.NotifyOfPropertyChange(() => this.ScanLog);\r
-        }\r
+            this.log.Clear();\r
+            this.lastReadIndex = 0;\r
 \r
-        /// <summary>\r
-        /// Encode Completed Event Handler.\r
-        /// </summary>\r
-        /// <param name="sender">\r
-        /// The sender.\r
-        /// </param>\r
-        /// <param name="e">\r
-        /// The e.\r
-        /// </param>\r
-        private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e)\r
-        {\r
-            this.NotifyOfPropertyChange(() => this.EncodeLog);\r
+            foreach (LogMessage logMessage in this.logService.LogMessages)\r
+            {\r
+                this.log.AppendLine(logMessage.Content);\r
+                this.lastReadIndex = logMessage.MessageIndex;\r
+\r
+                if (this.lastReadIndex > logMessage.MessageIndex)\r
+                {\r
+                    throw new Exception("Log Message Index Error");\r
+                }\r
+            }\r
+\r
+            this.NotifyOfPropertyChange("ActivityLog");\r
+            this.OnLogMessageReceived(null);\r
         }\r
 \r
         /// <summary>\r
-        /// The encode service encode started.\r
+        /// The log service_ message logged.\r
         /// </summary>\r
         /// <param name="sender">\r
         /// The sender.\r
@@ -229,24 +160,34 @@ namespace HandBrakeWPF.ViewModels
         /// <param name="e">\r
         /// The e.\r
         /// </param>\r
-        private void encodeService_EncodeStarted(object sender, EventArgs e)\r
+        private void LogService_MessageLogged(object sender, LogEventArgs e)\r
         {\r
-            this.encodeLogIndex = -1; // Reset the log index.\r
-            this.SelectedTab = 0;\r
+            if (this.lastReadIndex < e.Log.MessageIndex)\r
+            {\r
+                Execute.OnUIThreadAsync(\r
+                    () =>\r
+                        {\r
+                            this.lastReadIndex = e.Log.MessageIndex;\r
+                            this.log.AppendLine(e.Log.Content);\r
+                            this.OnLogMessageReceived(e);\r
+                            this.NotifyOfPropertyChange("ActivityLog");\r
+                        });\r
+            }\r
         }\r
 \r
         /// <summary>\r
-        /// The scan service scan stared.\r
+        /// Trigger a faster / smoother way of updating the log window.\r
         /// </summary>\r
-        /// <param name="sender">\r
-        /// The sender.\r
-        /// </param>\r
         /// <param name="e">\r
         /// The e.\r
         /// </param>\r
-        private void scanService_ScanStared(object sender, EventArgs e)\r
+        protected virtual void OnLogMessageReceived(LogEventArgs e)\r
         {\r
-            this.SelectedTab = 1;\r
+            var onLogMessageReceived = this.LogMessageReceived;\r
+            if (onLogMessageReceived != null)\r
+            {\r
+                onLogMessageReceived.Invoke(this, e);\r
+            }\r
         }\r
     }\r
 }
\ No newline at end of file
index 0886768e7702921bba4af01ec3a5882fd57135e8..3f9bc72019ce0a9633a51ec5d306e0563ca408b5 100644 (file)
@@ -23,6 +23,8 @@ namespace HandBrakeWPF.ViewModels
     using Caliburn.Micro;\r
 \r
     using HandBrake.ApplicationServices.Interop;\r
+    using HandBrake.ApplicationServices.Interop.HbLib;\r
+    using HandBrake.ApplicationServices.Services.Logging;\r
     using HandBrake.ApplicationServices.Utilities;\r
 \r
     using HandBrakeWPF.Commands;\r
@@ -56,6 +58,8 @@ namespace HandBrakeWPF.ViewModels
 \r
     using Action = System.Action;\r
     using Execute = Caliburn.Micro.Execute;\r
+    using ILog = HandBrake.ApplicationServices.Services.Logging.Interfaces.ILog;\r
+    using LogManager = HandBrakeWPF.Helpers.LogManager;\r
 \r
     /// <summary>\r
     /// HandBrakes Main Window\r
@@ -226,6 +230,7 @@ namespace HandBrakeWPF.ViewModels
             // Setup Commands\r
             this.QueueCommand = new QueueCommands(this.QueueViewModel);\r
 \r
+            LogManager.Init();\r
             HandBrakeInstanceManager.Init();\r
         }\r
 \r
@@ -1277,14 +1282,11 @@ namespace HandBrakeWPF.ViewModels
 \r
             if (window != null)\r
             {\r
-                ILogViewModel logvm = (ILogViewModel)window.DataContext;\r
-                logvm.SelectedTab = this.IsEncoding ? 0 : 1;\r
                 window.Activate();\r
             }\r
             else\r
             {\r
                 ILogViewModel logvm = IoC.Get<ILogViewModel>();\r
-                logvm.SelectedTab = this.IsEncoding ? 0 : 1;\r
                 this.windowManager.ShowWindow(logvm);\r
             }\r
         }\r
index 64ca9da2d13607fb49cdd32c5212a4f8f0c617d5..878fd430a4cd0afd9003396f2a4b9ccca814434a 100644 (file)
 \r
             </ToolBar>\r
 \r
+            <TextBox Grid.Row="2" ScrollViewer.VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" x:Name="logText" />\r
 \r
-            <TabControl Grid.Row="2" SelectedIndex="{Binding SelectedTab}" Margin="0,3,0,0">\r
-                <TabItem>\r
-                    <TabItem.Header>\r
-                        <TextBlock Text="{x:Static Properties:ResourcesUI.LogView_EncodeLog}" Padding="4">\r
-                            <TextBlock.Style>\r
-                                <Style TargetType="TextBlock">\r
-                                    <Style.Triggers>\r
-                                        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="True">\r
-                                            <Setter Property="FontWeight" Value="Bold"/>\r
-                                        </DataTrigger>\r
-                                    </Style.Triggers>\r
-                                </Style>\r
-                            </TextBlock.Style>\r
-                        </TextBlock>\r
-                    </TabItem.Header>\r
-\r
-                    <TextBox\r
-                     AcceptsReturn="True"\r
-                     IsReadOnly="True"\r
-                     ScrollViewer.VerticalScrollBarVisibility="Visible"\r
-                     Text="{Binding EncodeLog, Mode=OneWay,  UpdateSourceTrigger=PropertyChanged}"\r
-                     TextWrapping="Wrap" />\r
-                </TabItem>\r
-\r
-                <TabItem>\r
-                    <TabItem.Header>\r
-                        <TextBlock Text="{x:Static Properties:ResourcesUI.LogView_ScanLog}" Padding="4">\r
-                            <TextBlock.Style>\r
-                                <Style TargetType="TextBlock">\r
-                                    <Style.Triggers>\r
-                                        <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=TabItem}}" Value="True">\r
-                                            <Setter Property="FontWeight" Value="Bold"/>\r
-                                        </DataTrigger>\r
-                                    </Style.Triggers>\r
-                                </Style>\r
-                            </TextBlock.Style>\r
-                        </TextBlock>\r
-                    </TabItem.Header>\r
-                    <TextBox AcceptsReturn="True" IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Visible" \r
-                             Text="{Binding ScanLog, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"\r
-                             TextWrapping="Wrap" />\r
-                </TabItem>\r
-\r
-            </TabControl>\r
         </Grid>\r
 \r
     </Grid>\r
index d0bdaf0ee6cc4afa7042ace05c685697f1788bf2..af07ae50991469ae054648eb0ea1cf19257c0fe0 100644 (file)
@@ -9,9 +9,13 @@
 \r
 namespace HandBrakeWPF.Views\r
 {\r
+    using System;\r
+    using System.Diagnostics;\r
     using System.Windows;\r
     using System.Windows.Controls;\r
 \r
+    using HandBrakeWPF.ViewModels;\r
+\r
     /// <summary>\r
     /// Interaction logic for LogView.xaml\r
     /// </summary>\r
@@ -22,7 +26,59 @@ namespace HandBrakeWPF.Views
         /// </summary>\r
         public LogView()\r
         {\r
-            InitializeComponent();\r
+            this.InitializeComponent();\r
+            this.DataContextChanged += this.LogView_DataContextChanged;\r
+        }\r
+\r
+        /// <summary>\r
+        /// The log view_ data context changed.\r
+        /// </summary>\r
+        /// <param name="sender">\r
+        /// The sender.\r
+        /// </param>\r
+        /// <param name="e">\r
+        /// The e.\r
+        /// </param>\r
+        private void LogView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)\r
+        {\r
+            LogViewModel vm = e.NewValue as LogViewModel;\r
+            if (vm != null)\r
+            {\r
+                this.logText.AppendText(vm.ActivityLog);\r
+                vm.LogMessageReceived += this.Vm_LogMessageReceived;\r
+            }\r
+        }\r
+\r
+        /// <summary>\r
+        /// The vm_ log message received.\r
+        /// </summary>\r
+        /// <param name="sender">\r
+        /// The sender.\r
+        /// </param>\r
+        /// <param name="e">\r
+        /// The e.\r
+        /// </param>\r
+        private void Vm_LogMessageReceived(object sender, HandBrake.ApplicationServices.Services.Logging.EventArgs.LogEventArgs e)\r
+        {\r
+            if (e == null)\r
+            {\r
+                LogViewModel vm = this.DataContext as LogViewModel;\r
+                if (vm != null)\r
+                {\r
+                    this.logText.Clear();\r
+                    this.logText.AppendText(vm.ActivityLog);\r
+                }\r
+                else\r
+                {\r
+                    Debug.WriteLine("Failed to Reset Log correctly.");\r
+                }\r
+            }\r
+            else\r
+            {\r
+                // This works better than Data Binding because of the scroll.\r
+                this.logText.AppendText(Environment.NewLine + e.Log.Content);\r
+                this.logText.ScrollToEnd();\r
+            }\r
         }\r
 \r
         /// <summary>\r