void ThreadSearchView::OnQuickOptions(wxCommandEvent &event)
{
    ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
    bool hasChange = false;
    if (event.GetId() == controlIDs.Get(ControlIDs::idOptionWholeWord))
    {
        findData.SetMatchWord(event.IsChecked());
        hasChange = true;
    }
    else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionStartWord))
    {
        findData.SetStartWord(event.IsChecked());
        hasChange = true;
    }
    else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionMatchCase))
    {
        findData.SetMatchCase(event.IsChecked());
        hasChange = true;
    }
    else if (event.GetId() == controlIDs.Get(ControlIDs::idOptionRegEx))
    {
        findData.SetRegEx(event.IsChecked());
        hasChange = true;
    }
    if (hasChange)
    {
        m_ThreadSearchPlugin.SetFindData(findData);
        UpdateOptionsButtonImage(findData);
    }
}
void ThreadSearchView::OnCboSearchExprEnter(wxCommandEvent &/*event*/)
{
    // Event handler used when user clicks on enter after typing
    // in combo box text control.
    // Runs a multi threaded search.
    ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
    findData.SetFindText(m_pCboSearchExpr->GetValue());
    ThreadedSearch(findData);
}
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;
}
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 !"));
    }
}
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 ThreadSearch::RunThreadSearch(const wxString& text, bool isCtxSearch/*=false*/)
{
    if ( !IsAttached() )
        return;

    ThreadSearchFindData findData = m_FindData;

    // User may prefer to set default options for contextual search
    if ( (isCtxSearch == true) && (m_UseDefValsForThreadSearch == true) )
    {
        findData.SetMatchCase(true);
        findData.SetMatchWord(true);
        findData.SetStartWord(false);
        findData.SetRegEx    (false);
    }

    // m_SearchedWord was set in BuildModuleMenu
    findData.SetFindText(text);

    // Displays m_pThreadSearchView in manager
    m_pViewManager->ShowView(true);

    // Runs the search through a worker thread
    m_pThreadSearchView->ThreadedSearch(findData);
}
void ThreadSearchView::set_properties()
{
    const wxString &prefix = GetToolbarImagePrefix();

    // begin wxGlade: ThreadSearchView::set_properties
    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
    m_pCboSearchExpr->SetMinSize(wxSize(180, -1));
    m_pBtnSearch->SetToolTip(_("Search in files"));
    m_pBtnSearch->SetBitmapDisabled(wxBitmap(prefix + wxT("findfdisabled.png"), wxBITMAP_TYPE_PNG));
    m_pBtnSearch->SetSize(m_pBtnSearch->GetBestSize());
    m_pBtnOptions->SetToolTip(_("Options"));
    m_pBtnOptions->SetBitmapDisabled(wxBitmap(prefix + wxT("optionsdisabled.png"), wxBITMAP_TYPE_PNG));
    m_pBtnOptions->SetSize(m_pBtnOptions->GetBestSize());
    m_pBtnShowDirItems->SetToolTip(_("Show dir Items"));
    m_pBtnShowDirItems->SetBitmapDisabled(wxBitmap(prefix + wxT("showdirdisabled.png"), wxBITMAP_TYPE_PNG));
    m_pBtnShowDirItems->SetSize(m_pBtnShowDirItems->GetBestSize());
    m_pPnlPreview->SetMinSize(wxSize(25, -1));
    // end wxGlade

    m_pSearchPreview->SetReadOnly(true);

    ThreadSearchFindData findData;
    m_ThreadSearchPlugin.GetFindData(findData);

    m_pPnlDirParams->SetSearchDirHidden(findData.GetHiddenSearch());
    m_pPnlDirParams->SetSearchDirRecursively(findData.GetRecursiveSearch());
    m_pPnlDirParams->SetSearchDirPath(findData.GetSearchPath());
    m_pPnlDirParams->SetSearchMask(findData.GetSearchMask());

    m_pPnlSearchIn->SetSearchInOpenFiles(findData.MustSearchInOpenFiles());
    m_pPnlSearchIn->SetSearchInTargetFiles(findData.MustSearchInTarget());
    m_pPnlSearchIn->SetSearchInProjectFiles(findData.MustSearchInProject());
    m_pPnlSearchIn->SetSearchInWorkspaceFiles(findData.MustSearchInWorkspace());
    m_pPnlSearchIn->SetSearchInDirectory(findData.MustSearchInDirectory());

    UpdateOptionsButtonImage(findData);
}
void ThreadSearchView::OnBtnSearchClick(wxCommandEvent &/*event*/)
{
    // User clicked on Search/Cancel
    // m_ThreadSearchEventsArray is shared by two threads, we
    // use m_MutexSearchEventsArray to have a safe access.
    // As button action depends on m_ThreadSearchEventsArray,
    // we lock the mutex to process it correctly.
    if ( m_MutexSearchEventsArray.Lock() == wxMUTEX_NO_ERROR )
    {
        int nbEvents = m_ThreadSearchEventsArray.GetCount();
        m_MutexSearchEventsArray.Unlock();
        if ( m_pFindThread != NULL )
        {
            // A threaded search is running...
            UpdateSearchButtons(false);
            StopThread();
        }
        else if ( nbEvents > 0 )
        {
            // A threaded search has run but the events array is
            // not completely processed...
            UpdateSearchButtons(false);
            if ( ClearThreadSearchEventsArray() == false )
            {
                cbMessageBox(_("Failed to clear events array."), _("Error"), wxICON_ERROR);
            }
        }
        else
        {
            // We start the thread search
            ThreadSearchFindData findData = m_ThreadSearchPlugin.GetFindData();
            findData.SetFindText(m_pCboSearchExpr->GetValue());
            ThreadedSearch(findData);
        }
    }
}
void ThreadSearchView::UpdateOptionsButtonImage(const ThreadSearchFindData &findData)
{
    const wxString name = GetToolbarImagePrefix()
                        + (findData.IsOptionEnabled() ? wxT("optionsactive.png") : wxT("options.png"));

    {
        const double scaleFactor = cbGetContentScaleFactor(*m_pBtnOptions);
        wxBitmap bitmap=cbLoadBitmapScaled(name, wxBITMAP_TYPE_PNG, scaleFactor);
        m_pBtnOptions->SetBitmapLabel(bitmap);
    }

    if (m_pToolBar)
    {
        const double scaleFactor = cbGetContentScaleFactor(*m_pToolBar);
        wxBitmap bitmap=cbLoadBitmapScaled(name, wxBITMAP_TYPE_PNG, scaleFactor);
        m_pToolBar->SetToolNormalBitmap(controlIDs.Get(ControlIDs::idBtnOptions), bitmap);
    }
}