void ThreadSearchLoggerList::OnSearchBegin(const ThreadSearchFindData& findData)
{
    m_TotalLinesFound = 0;
    m_MadeVisible = false;

    if ( m_ThreadSearchPlugin.GetDeletePreviousResults() )
    {
        Clear();
        m_IndexOffset = 0;
    }
    else
    {
        m_IndexManager.Reset();
        long index = m_pListLog->GetItemCount();
        m_pListLog->InsertItem(index, wxString::Format(_("=> %s"), findData.GetFindText().c_str()));
        m_pListLog->SetItem(index, 1, _("========="));
        m_pListLog->SetItem(index, 2, _("==="));
        m_pListLog->SetItem(index, 3, _("============"));
        m_pListLog->SetItemData(index, 1);

        wxListItem info;
        info.SetStateMask(wxLIST_MASK_STATE);
        info.SetId(index);
        info.SetState(wxLIST_STATE_SELECTED);
        m_pListLog->SetItem(info);

        m_IndexOffset = m_pListLog->GetItemCount();
        m_pListLog->EnsureVisible(index);
    }

    m_SortColumn = -1;
    m_Ascending = true;
}
ThreadSearchThread::ThreadSearchThread(ThreadSearchView*           pThreadSearchView,
                                       const ThreadSearchFindData& findData)
{
    m_pThreadSearchView = pThreadSearchView;
    m_FindData          = findData;

    // If wxDIR_IGNORE is used, we don't recurse in sub directories during directory search
    m_DefaultDirResult  = (findData.GetRecursiveSearch() == true) ? wxDIR_CONTINUE : wxDIR_IGNORE;

    // File patterns separator is ';'
    m_Masks             = GetArrayFromString(m_FindData.GetSearchMask());
    if ( m_Masks.GetCount() == 0 )
    {
        m_Masks.Add(_T("*"));
    }
    m_pTextFileSearcher = TextFileSearcher::BuildTextFileSearcher(findData.GetFindText(),
                                                                  findData.GetMatchCase(),
                                                                  findData.GetStartWord(),
                                                                  findData.GetMatchWord(),
                                                                  findData.GetRegEx());
    if (!m_pTextFileSearcher)
    {
        ThreadSearchEvent event(wxEVT_THREAD_SEARCH_ERROR, -1);
        event.SetString(_("TextFileSearcher could not be instantiated."));

        // Using wxPostEvent, we avoid multi-threaded memory violation.
        wxPostEvent( m_pThreadSearchView,event);
    }
    ConfigManager* pCfg = Manager::Get()->GetConfigManager(_T("ThreadSearch"));
    m_ShowFileMissingError=pCfg->ReadBool(wxT("/ShowFileMissingError"),true);
    m_ShowCantOpenFileError=pCfg->ReadBool(wxT("/ShowCantOpenFileError"),true);

}
void ThreadSearchView::ThreadedSearch(const ThreadSearchFindData& aFindData)
{
    // We don't search empty patterns
    if ( aFindData.GetFindText() != wxEmptyString )
    {
        ThreadSearchFindData findData(aFindData);

        // Prepares logger
        m_pLogger->OnSearchBegin(aFindData);

        // Two steps thread creation
        m_pFindThread = new ThreadSearchThread(this, findData);
        if ( m_pFindThread != NULL )
        {
            if ( m_pFindThread->Create() == wxTHREAD_NO_ERROR )
            {
                // Thread execution
                if ( m_pFindThread->Run() != wxTHREAD_NO_ERROR )
                {
                    m_pFindThread->Delete();
                    m_pFindThread = NULL;
                    cbMessageBox(_("Failed to run search thread"));
                }
                else
                {
                    // Update combo box search history
                    AddExpressionToSearchCombos(findData.GetFindText(), findData.GetSearchPath(),
                                                findData.GetSearchMask());
                    UpdateSearchButtons(true, cancel);
                    EnableControls(false);

                    // Starts the timer used to managed events sent by m_pFindThread
                    m_Timer.Start(TIMER_PERIOD, wxTIMER_CONTINUOUS);
                }
            }
            else
            {
                // Error
                m_pFindThread->Delete();
                m_pFindThread = NULL;
                cbMessageBox(_("Failed to create search thread (2)"));
            }
        }
        else
        {
            // Error
            cbMessageBox(_("Failed to create search thread (1)"));
        }
    }
    else
    {
        // Error
        cbMessageBox(_("Search expression is empty !"));
    }
}