/* frmActivityWindow.cs $ This file is part of the HandBrake source code. Homepage: . It may be used under the terms of the GNU General Public License. */ namespace Handbrake { using System; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; using System.Windows.Forms; using HandBrake.ApplicationServices.Services.Interfaces; using Handbrake.Functions; using Model; using Timer = System.Threading.Timer; /// /// The Activity Log Window /// public partial class frmActivityWindow : Form { /* Private Variables */ /// /// The Encode Object /// private readonly IEncode encode; /// /// The Scan Object /// private readonly IScan scan; /// /// The current position in the log file /// private int position; /// /// A Timer for this window /// private Timer windowTimer; /// /// The Type of log that the window is currently dealing with /// private ActivityLogMode mode; /* Constructor */ /// /// Initializes a new instance of the class. /// /// /// The encode. /// /// /// The scan. /// public frmActivityWindow(IEncode encode, IScan scan) { InitializeComponent(); this.encode = encode; this.scan = scan; this.position = 0; // Listen for Scan and Encode Starting Events scan.ScanStared += scan_ScanStared; encode.EncodeStarted += encode_EncodeStarted; } /* Delegates */ /// /// A callback function for updating the ui /// /// /// The text. /// private delegate void SetTextCallback(StringBuilder text); /// /// Clear text callback /// private delegate void SetTextClearCallback(); /// /// Set mode callback /// /// /// The set mode. /// private delegate void SetModeCallback(ActivityLogMode setMode); /* Private Methods */ /// /// Set the window to scan mode /// /// /// The set Mode. /// private void SetMode(ActivityLogMode setMode) { if (IsHandleCreated) { if (rtf_actLog.InvokeRequired) { IAsyncResult invoked = BeginInvoke(new SetModeCallback(SetMode), new object[] { setMode }); EndInvoke(invoked); } else { Reset(); this.mode = setMode; Array values = Enum.GetValues(typeof(ActivityLogMode)); Properties.Settings.Default.ActivityWindowLastMode = (int)values.GetValue(Convert.ToInt32(setMode)); Properties.Settings.Default.Save(); this.Text = mode == ActivityLogMode.Scan ? "Activity Window (Scan Log)" : "Activity Window (Encode Log)"; if (mode == ActivityLogMode.Scan) { scan.ScanCompleted += stopWindowRefresh; encode.EncodeCompleted -= stopWindowRefresh; } else { scan.ScanCompleted -= stopWindowRefresh; encode.EncodeCompleted += stopWindowRefresh; } // Start a fresh window timer windowTimer = new Timer(new TimerCallback(LogMonitor), null, 1000, 1000); } } } /// /// On Window load, start a new timer /// /// /// The sender. /// /// /// The EventArgs. /// private void ActivityWindowLoad(object sender, EventArgs e) { try { // Set the inital log file. if (encode.IsEncoding) { this.logSelector.SelectedIndex = 1; } else if (scan.IsScanning) { this.logSelector.SelectedIndex = 0; } else { // Otherwise, use the last mode the window was in. ActivityLogMode activitLogMode = (ActivityLogMode)Enum.ToObject(typeof(ActivityLogMode), Properties.Settings.Default.ActivityWindowLastMode); this.logSelector.SelectedIndex = activitLogMode == ActivityLogMode.Scan ? 0 : 1; } } catch (Exception exc) { Main.ShowExceptiowWindow("Error during load.", exc.ToString()); } } /// /// Set the Log window to encode mode when an encode starts. /// /// /// The sender. /// /// /// The e. /// private void encode_EncodeStarted(object sender, EventArgs e) { SetMode(ActivityLogMode.Encode); } /// /// Set the log widow to scan mode when a scan starts /// /// /// The sender. /// /// /// The e. /// private void scan_ScanStared(object sender, EventArgs e) { SetMode(ActivityLogMode.Scan); } /// /// Stop refreshing the window when no scanning or encoding is happening. /// /// /// The sender. /// /// /// The e. /// private void stopWindowRefresh(object sender, EventArgs e) { windowTimer.Dispose(); Reset(); LogMonitor(null); } /// /// Append new text to the window /// /// /// The n. /// private void LogMonitor(object n) { AppendWindowText(GetLog()); } /// /// New Code for getting the Activity log from the Services rather than reading a file. /// /// /// The StringBuilder containing a log /// private StringBuilder GetLog() { StringBuilder appendText = new StringBuilder(); try { if (this.mode == ActivityLogMode.Scan) { if (scan == null || scan.ActivityLog == string.Empty) { appendText.AppendFormat("Waiting for the log to be generated ...\n"); position = 0; ClearWindowText(); return appendText; } using (StringReader reader = new StringReader(scan.ActivityLog)) { LogReader(reader, appendText); } } else { if (encode == null || encode.ActivityLog == string.Empty) { appendText.AppendFormat("Waiting for the log to be generated ...\n"); position = 0; ClearWindowText(); return appendText; } using (StringReader reader = new StringReader(encode.ActivityLog)) { LogReader(reader, appendText); } } } catch (Exception exc) { windowTimer.Dispose(); Main.ShowExceptiowWindow("GetLog() Error.", exc.ToString()); } return appendText; } /// /// Reads the log data from a Scan or Encode object /// /// /// The reader. /// /// /// The append text. /// private void LogReader(StringReader reader, StringBuilder appendText) { string line; int i = 1; while ((line = reader.ReadLine()) != null) { if (i > position) { appendText.AppendLine(line); position++; } i++; } } /// /// Append text to the RTF box /// /// /// The text. /// private void AppendWindowText(StringBuilder text) { try { if (IsHandleCreated) { if (rtf_actLog.InvokeRequired) { IAsyncResult invoked = BeginInvoke(new SetTextCallback(AppendWindowText), new object[] { text }); EndInvoke(invoked); } else lock (rtf_actLog) rtf_actLog.AppendText(text.ToString()); // Stop the refresh process if log has finished. if (text.ToString().Contains("HandBrake has Exited")) { windowTimer.Dispose(); } } } catch (Exception) { return; } } /// /// Clear the contents of the log window /// private void ClearWindowText() { try { if (IsHandleCreated) { if (rtf_actLog.InvokeRequired) { IAsyncResult invoked = BeginInvoke(new SetTextClearCallback(ClearWindowText)); EndInvoke(invoked); } else lock (rtf_actLog) rtf_actLog.Clear(); } } catch (Exception) { return; } } /// /// Reset Everything /// private void Reset() { if (windowTimer != null) windowTimer.Dispose(); position = 0; ClearWindowText(); windowTimer = new Timer(new TimerCallback(LogMonitor), null, 1000, 1000); } /* Menus and Buttons */ /// /// Copy log to clipboard /// /// /// The sender. /// /// /// The e. /// private void MnuCopyLogClick(object sender, EventArgs e) { Clipboard.SetDataObject(rtf_actLog.SelectedText != string.Empty ? rtf_actLog.SelectedText : rtf_actLog.Text, true); } /// /// Open the log folder /// /// /// The sender. /// /// /// The e. /// private void MnuOpenLogFolderClick(object sender, EventArgs e) { string logDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\HandBrake\\logs"; string windir = Environment.GetEnvironmentVariable("WINDIR"); Process prc = new Process { StartInfo = { FileName = windir + @"\explorer.exe", Arguments = logDir } }; prc.Start(); } /// /// Copy the log /// /// /// The sender. /// /// /// The e. /// private void BtnCopyClick(object sender, EventArgs e) { Clipboard.SetDataObject(rtf_actLog.SelectedText != string.Empty ? rtf_actLog.SelectedText : rtf_actLog.Text, true); } /// /// Change the Log file in the viewer /// /// The Sender /// The EventArgs private void LogSelectorClick(object sender, EventArgs e) { this.SetMode((string)this.logSelector.SelectedItem == "Scan Log" ? ActivityLogMode.Scan : ActivityLogMode.Encode); } /* Overrides */ /// /// override onclosing /// /// /// The e. /// protected override void OnClosing(CancelEventArgs e) { scan.ScanStared -= scan_ScanStared; encode.EncodeStarted -= encode_EncodeStarted; scan.ScanCompleted -= stopWindowRefresh; encode.EncodeCompleted -= stopWindowRefresh; windowTimer.Dispose(); e.Cancel = true; this.Dispose(); base.OnClosing(e); } } }