/// <summary>
        ///
        /// </summary>
        /// <param name="cl"></param>
        private void LogFile_MultiSearchInitiated(ControlLog cl, List <SearchCriteria> searches)
        {
            this.cancellationTokenSource = new CancellationTokenSource();
            SetProcessingState(false);

            cl.SearchMulti(searches, cancellationTokenSource.Token, config.NumContextLines);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LogFile_ExportInitiated(ControlLog cl, bool all)
        {
            SaveFileDialog sfd = new SaveFileDialog();

            sfd.Filter   = "All Files|*.*";
            sfd.FileName = "*.*";
            sfd.Title    = "Select export file";

            if (sfd.ShowDialog() == false)
            {
                return;
            }

            this.cancellationTokenSource = new CancellationTokenSource();
            SetProcessingState(false);

            if (all == true)
            {
                cl.Export(sfd.FileName, cancellationTokenSource.Token);
            }
            else
            {
                cl.ExportSelected(sfd.FileName, cancellationTokenSource.Token);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MnuToolsMultiStringSearch_Click(object sender, RoutedEventArgs e)
        {
            ControlLog cl = (ControlLog)((TabItem)tabMain.SelectedItem).Content;

            cl.ShowMultiSearch();

            //LogFile lf = logs[tabControl.SelectedTab.Tag.ToString()];

            //using (FormSearch f = new FormSearch(lf.Searches))
            //{
            //    DialogResult dr = f.ShowDialog(this);
            //    if (dr == DialogResult.Cancel)
            //    {
            //        return;
            //    }

            //    // Clear any existing filter ID's as we will only show the multi-string search
            //    lf.FilterIds.Clear();
            //    lf.Searches.Reset();
            //    foreach (SearchCriteria sc in f.NewSearches)
            //    {
            //        // Add the ID so that any matches show up straight away
            //        lf.FilterIds.Add(sc.Id);
            //        lf.Searches.Add(sc);
            //    }

            //    this.processing = true;
            //    this.hourGlass = new HourGlass(this);
            //    SetProcessingState(false);
            //    statusProgress.Visible = true;
            //    this.cancellationTokenSource = new CancellationTokenSource();
            //    lf.SearchMulti(f.NewSearches, cancellationTokenSource.Token, config.NumContextLines);
            //}
        }
 /// <summary>
 ///
 /// </summary>
 /// <param name="cl"></param>
 /// <param name="fileName"></param>
 /// <param name="duration"></param>
 /// <param name="cancelled"></param>
 private void LogFile_ExportComplete(ControlLog cl, string fileName, TimeSpan duration, bool cancelled)
 {
     Dispatcher.Invoke(() =>
     {
         this.cancellationTokenSource.Dispose();
         SetProcessingState(true);
         UpdateStatusLabel("Export complete # Duration: " + duration + " (" + fileName + ")");
     });
 }
        /// <summary>
        ///
        /// </summary>
        private void LogFile_SearchComplete(ControlLog cl, string fileName, TimeSpan duration, long matches, int numTerms, bool cancelled)
        {
            Dispatcher.Invoke(() =>
            {
                // Update the list
                cl.ItemsSource = null;
                cl.ItemsSource = cl.Lines;

                UpdateStatusLabel("Matched " + matches + " lines (Search Terms: " + numTerms + ") # Duration: " + duration + " (" + fileName + ")");
                this.cancellationTokenSource.Dispose();
                SetProcessingState(true);
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private void LoadFile(string filePath, bool newTab)
        {
            SetProcessingState(false);
            this.cancellationTokenSource = new CancellationTokenSource();

            if (newTab == true)
            {
                ControlLog cl = new ControlLog(this.config)
                {
                    ViewMode = Global.ViewMode.Standard,
                };

                cl.ProgressUpdate       += LogFile_LoadProgress;
                cl.LoadComplete         += LogFile_LoadComplete;
                cl.SearchComplete       += LogFile_SearchComplete;
                cl.ExportInitiated      += LogFile_ExportInitiated;
                cl.ExportComplete       += LogFile_ExportComplete;;
                cl.LoadError            += LogFile_LoadError;
                cl.MultiSearchInitiated += LogFile_MultiSearchInitiated;
                cl.DragEnter            += LogFile_DragEnter;
                cl.Drop += LogFile_Drop;

                TabItem ti = new TabItem
                {
                    Content = cl,
                    Header  = Path.GetFileName(filePath),
                    Tag     = cl.Guid,
                    ToolTip = filePath
                };

                tabMain.Items.Add(ti);
                tabMain.SelectedIndex = tabMain.Items.Count - 1;

                cl.Load(filePath, cancellationTokenSource.Token);
            }
            else
            {
                if (tabMain.SelectedItem == null)
                {
                    MessageBox.Show("Cannot identify current tab", Application.ResourceAssembly.GetName().Name, MessageBoxButton.OK, MessageBoxImage.Exclamation);
                    return;
                }

                ControlLog cl = (ControlLog)((TabItem)tabMain.SelectedItem).Content;
                ((TabItem)tabMain.SelectedItem).ToolTip = filePath;
                cl.Dispose();
                cl.Load(filePath, cancellationTokenSource.Token);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MnuFileClose_Click(object sender, RoutedEventArgs e)
        {
            if (tabMain.SelectedItem == null)
            {
                MessageBox.Show("Cannot identify current tab", Application.ResourceAssembly.GetName().Name, MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            TabItem ti = (TabItem)tabMain.SelectedItem;

            ti.Header  = "...";
            ti.ToolTip = "";
            ControlLog cl = (ControlLog)ti.Content;

            cl.Dispose();
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="cl"></param>
        /// <param name="fileName"></param>
        /// <param name="duration"></param>
        /// <param name="cancelled"></param>
        private void LogFile_LoadComplete(ControlLog cl, string fileName, TimeSpan duration, bool cancelled)
        {
            Dispatcher.Invoke(() =>
            {
                // Update the UI
                cl.ItemsSource = cl.Lines;
                cl.UpdateColumnWidths();
                tabMain.UpdateLayout();

                // Enable the menu items that only apply if a file is open
                mnuFileClose.IsEnabled = true;
                mnuFileOpen.IsEnabled  = true;

                UpdateStatusLabel(cl.Lines.Count + " Lines # Duration: " + duration + " (" + fileName + ")");
                this.cancellationTokenSource.Dispose();
                SetProcessingState(true);
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private void SearchFile()
        {
            ControlLog cl = (ControlLog)((TabItem)tabMain.SelectedItem).Content;

            SearchCriteria sc = new SearchCriteria();

            sc.Type    = (Global.SearchType)comboType.SelectedIndex;
            sc.Pattern = txtSearch.Text;
            sc.Id      = cl.Searches.Add(sc, (bool)toolBtnCumulative.IsChecked);

            if (sc.Id == 0)
            {
                MessageBox.Show("Search pattern already exists", Application.ResourceAssembly.GetName().Name, MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            // Add the ID so that any matches show up straight away
            cl.FilterIds.Add(sc.Id);

            SetProcessingState(false);
            this.cancellationTokenSource = new CancellationTokenSource();
            cl.Search(sc, (bool)toolBtnCumulative.IsChecked, cancellationTokenSource.Token, config.NumContextLines);
        }