void QuickFindBar::DoSearch(size_t searchFlags, int posToSearchFrom) { if(!m_sci || m_sci->GetLength() == 0 || m_findWhat->GetValue().IsEmpty()) return; // Clear all search markers if desired if (EditorConfigST::Get()->GetOptions()->GetClearHighlitWordsOnFind()) { m_sci->SetIndicatorCurrent(MARKER_WORD_HIGHLIGHT); m_sci->IndicatorClearRange(0, m_sci->GetLength()); } m_flags = DoGetSearchFlags(); wxString find = m_findWhat->GetValue(); wchar_t* pinput = DoGetSearchStringPtr(); if(!pinput) return; int start = -1, stop = -1; m_sci->GetSelection(&start, &stop); bool fwd = searchFlags & kSearchForward; bool addSelection = searchFlags & kSearchMultiSelect; bool incr = searchFlags & kSearchIncremental; int offset; if(posToSearchFrom != wxNOT_FOUND) { offset = posToSearchFrom; } else { offset = (!fwd || incr) ? start : stop; } int flags = m_flags | (fwd ? 0 : wxSD_SEARCH_BACKWARD); int pos = 0, len = 0; if(!StringFindReplacer::Search(pinput, offset, find.wc_str(), flags, pos, len)) { offset = fwd ? 0 : wxStrlen(pinput) - 1; if(!StringFindReplacer::Search(pinput, offset, find.wc_str(), flags, pos, len)) { m_findWhat->SetBackgroundColour(wxT("PINK")); m_findWhat->Refresh(); return; } } m_findWhat->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); m_findWhat->Refresh(); if(addSelection && m_sci->GetSelections()) { m_sci->AddSelection(pos, pos + len); } else { m_sci->ClearSelections(); m_sci->SetSelection(pos, pos + len); } // Ensure that the found string is visible (i.e. its line isn't folded away) // and that the user can see it without having to scroll int line = m_sci->LineFromPosition(pos); if(line >= 0) { m_sci->EnsureVisible(line); m_sci->EnsureCaretVisible(); } }
void QuickFindBar::OnHighlightMatches(wxFlatButtonEvent& e) { bool checked = e.IsChecked(); LEditor* editor = dynamic_cast<LEditor*>(m_sci); if(checked && editor) { int flags = DoGetSearchFlags(); wxString findwhat = m_findWhat->GetValue(); if(!m_sci || m_sci->GetLength() == 0 || findwhat.IsEmpty()) return; // Do we have at least one match? if(m_sci->FindText(0, m_sci->GetLastPosition(), findwhat, flags) == wxNOT_FOUND) return; m_sci->ClearSelections(); m_sci->SetCurrentPos(0); m_sci->SetSelectionEnd(0); m_sci->SetSelectionStart(0); editor->SetFindBookmarksActive(true); editor->DelAllMarkers(smt_find_bookmark); while(true) { m_sci->SearchAnchor(); if(m_sci->SearchNext(flags, findwhat) != wxNOT_FOUND) { int selStart, selEnd; m_sci->GetSelection(&selStart, &selEnd); m_sci->SetIndicatorCurrent(MARKER_WORD_HIGHLIGHT); m_sci->IndicatorFillRange(selStart, selEnd - selStart); m_sci->MarkerAdd(m_sci->LineFromPosition(selStart), smt_find_bookmark); // Clear the selection so the next 'SearchNext' will search forward m_sci->SetCurrentPos(selEnd); m_sci->SetSelectionEnd(selEnd); m_sci->SetSelectionStart(selEnd); } else { break; } } } else { if(editor) { editor->DelAllMarkers(smt_find_bookmark); editor->SetFindBookmarksActive(false); } } clMainFrame::Get()->SelectBestEnvSet(); // Updates the statusbar display }
void QuickFindBar::DoMarkAll() { if(!m_sci || m_sci->GetLength() == 0 || m_findWhat->GetValue().IsEmpty()) return; clGetManager()->SetStatusMessage(wxEmptyString); m_sci->SetIndicatorCurrent(MARKER_WORD_HIGHLIGHT); m_sci->IndicatorClearRange(0, m_sci->GetLength()); wxString find = m_findWhat->GetValue(); bool fwd = true; int flags = DoGetSearchFlags(); // Since scintilla uses a non POSIX way of handling the regex paren // fix them if(flags & wxSTC_FIND_REGEXP) { DoFixRegexParen(find); } // Ensure that we have at least one match before we continue if(m_sci->FindText(0, m_sci->GetLastPosition(), find, flags) == wxNOT_FOUND) { clGetManager()->SetStatusMessage(_("No match found"), 1); return; } // We got at least one match m_sci->SetCurrentPos(0); m_sci->SetSelectionEnd(0); m_sci->SetSelectionStart(0); m_sci->ClearSelections(); m_sci->SearchAnchor(); std::vector<std::pair<int, int> > matches; // pair of matches selStart+selEnd int pos = m_sci->SearchNext(flags, find); while(pos != wxNOT_FOUND) { std::pair<int, int> match; m_sci->GetSelection(&match.first, &match.second); m_sci->SetCurrentPos(match.second); m_sci->SetSelectionStart(match.second); m_sci->SetSelectionEnd(match.second); m_sci->SearchAnchor(); pos = m_sci->SearchNext(flags, find); matches.push_back(match); } if(matches.empty()) { clGetManager()->SetStatusMessage(_("No match found"), 1); return; } // add selections m_sci->ClearSelections(); for(size_t i = 0; i < matches.size(); ++i) { if(i == 0) { m_sci->SetSelection(matches.at(i).first, matches.at(i).second); m_sci->SetMainSelection(0); DoEnsureLineIsVisible(m_sci->LineFromPosition(matches.at(0).first)); } else { m_sci->AddSelection(matches.at(i).first, matches.at(i).second); } } Show(false); wxString message; message << _("Found and selected ") << matches.size() << _(" matches"); clGetManager()->SetStatusMessage(message, 2); m_sci->SetMainSelection(0); }
void QuickFindBar::OnReplace(wxCommandEvent& event) { wxUnusedVar(event); if(!m_sci) return; wxString findwhat = m_findWhat->GetValue(); if(findwhat.IsEmpty()) return; wxString findWhatSciVersion = findwhat; DoFixRegexParen(findWhatSciVersion); // No selection? if(m_sci->GetSelections() == 0) { DoSearch(kSearchForward); return; } // No selection? if(m_sci->GetSelections() != 1) { DoSearch(kSearchForward); return; } // did we got a match? if(m_sci->GetSelections() != 1) return; int selStart, selEnd; m_sci->GetSelection(&selStart, &selEnd); if(selStart == selEnd) { // not a real selection DoSearch(kSearchForward); return; } // Ensure that the selection matches our search pattern size_t searchFlags = DoGetSearchFlags(); if(m_sci->FindText(selStart, selEnd, searchFlags & wxSTC_FIND_REGEXP ? findWhatSciVersion : findwhat, searchFlags) == wxNOT_FOUND) { // we got a selection, but it does not match our search return; } wxString selectedText = m_sci->GetTextRange(selStart, selEnd); #ifndef __WXMAC__ int re_flags = wxRE_ADVANCED; #else int re_flags = wxRE_DEFAULT; #endif wxString replaceWith = m_replaceWith->GetValue(); if(!replaceWith.IsEmpty()) { clConfig::Get().AddQuickFindReplaceItem(replaceWith); DoUpdateReplaceHistory(); } size_t replacementLen = replaceWith.length(); if(searchFlags & wxSTC_FIND_REGEXP) { // Regular expresson search if(!(searchFlags & wxSTC_FIND_MATCHCASE)) { re_flags |= wxRE_ICASE; } wxRegEx re(findwhat, re_flags); if(re.IsValid() && re.Matches(selectedText)) { re.Replace(&selectedText, replaceWith); // Keep the replacement length replacementLen = selectedText.length(); // update the view m_sci->Replace(selStart, selEnd, selectedText); } else { return; } } else { // Normal search and replace m_sci->Replace(selStart, selEnd, replaceWith); } // Clear the selection m_sci->ClearSelections(); m_sci->SetCurrentPos(selStart + replacementLen); // Trigger another search DoSearch(kSearchForward); }
void QuickFindBar::DoSearch(size_t searchFlags) { if(!m_sci || m_sci->GetLength() == 0 || m_findWhat->GetValue().IsEmpty()) return; clGetManager()->SetStatusMessage(wxEmptyString); // Clear all search markers if desired if(EditorConfigST::Get()->GetOptions()->GetClearHighlitWordsOnFind()) { m_sci->SetIndicatorCurrent(MARKER_WORD_HIGHLIGHT); m_sci->IndicatorClearRange(0, m_sci->GetLength()); } wxString find = m_findWhat->GetValue(); bool fwd = searchFlags & kSearchForward; int flags = DoGetSearchFlags(); // Since scintilla uses a non POSIX way of handling the paren // fix them if(flags & wxSTC_FIND_REGEXP) { DoFixRegexParen(find); } int curpos = m_sci->GetCurrentPos(); int start = wxNOT_FOUND; int end = wxNOT_FOUND; m_sci->GetSelection(&start, &end); if((end != wxNOT_FOUND) && fwd) { if(m_sci->FindText(start, end, find, flags) != wxNOT_FOUND) { // Incase we searching forward and the current selection matches the search string // Clear the selection and set the caret position to the end of the selection m_sci->SetCurrentPos(end); m_sci->SetSelectionEnd(end); m_sci->SetSelectionStart(end); } } int pos = wxNOT_FOUND; if(fwd) { m_sci->SearchAnchor(); pos = m_sci->SearchNext(flags, find); if(pos == wxNOT_FOUND) { clGetManager()->SetStatusMessage(_("Wrapped past end of file"), 1); m_sci->SetCurrentPos(0); m_sci->SetSelectionEnd(0); m_sci->SetSelectionStart(0); m_sci->SearchAnchor(); pos = m_sci->SearchNext(flags, find); } } else { m_sci->SearchAnchor(); pos = m_sci->SearchPrev(flags, find); if(pos == wxNOT_FOUND) { clGetManager()->SetStatusMessage(_("Wrapped past end of file"), 1); int lastPos = m_sci->GetLastPosition(); m_sci->SetCurrentPos(lastPos); m_sci->SetSelectionEnd(lastPos); m_sci->SetSelectionStart(lastPos); m_sci->SearchAnchor(); pos = m_sci->SearchPrev(flags, find); } } if(pos == wxNOT_FOUND) { // Restore the caret position m_sci->SetCurrentPos(curpos); m_sci->ClearSelections(); CallAfter(&QuickFindBar::DoSetCaretAtEndOfText); return; } DoEnsureLineIsVisible(); CallAfter(&QuickFindBar::DoSetCaretAtEndOfText); }
void QuickFindBar::DoMarkAll(bool useIndicators) { if(!m_sci) return; LEditor* editor = dynamic_cast<LEditor*>(m_sci); if(!editor) return; wxString findWhat = m_findWhat->GetValue(); if(findWhat.IsEmpty()) { return; } // Save the caret position long savedPos = m_sci->GetCurrentPos(); size_t flags = DoGetSearchFlags(); int pos(0); int match_len(0); // remove reverse search flags &= ~wxSD_SEARCH_BACKWARD; int offset(0); wchar_t* pinput = DoGetSearchStringPtr(); if(!pinput) return; int fixed_offset(0); // Clear markers editor->DelAllMarkers(smt_find_bookmark); // set the active indicator to be 1 editor->SetIndicatorCurrent(1); size_t count(0); int firstMatchPos(wxNOT_FOUND); while(StringFindReplacer::Search(pinput, offset, findWhat.wc_str(), flags, pos, match_len)) { int matchStart = fixed_offset + pos; int matchEnd = matchStart + match_len; if(useIndicators) { editor->MarkerAdd(editor->LineFromPosition(fixed_offset + pos), smt_find_bookmark); // add indicator as well editor->IndicatorFillRange(fixed_offset + pos, match_len); } else { // Use multiple selections if(count) { // we already have the main selection, add secondary selections editor->AddSelection(matchStart, matchEnd); } else { // clear and set the first selection editor->ClearSelections(); editor->SetSelection(matchStart, matchEnd); firstMatchPos = matchStart; } } ++count; offset = pos + match_len; } // Restore the caret if(useIndicators) { editor->SetCurrentPos(savedPos); editor->EnsureCaretVisible(); } if(firstMatchPos != wxNOT_FOUND) { editor->SetMainSelection(0); editor->SetLineVisible(editor->LineFromPos(firstMatchPos)); } if(!useIndicators) { // Hide the bar Show(false); } }