I'm trying to write a search box, containing find/find previous/find next to interact with a QScintilla textEditor widget. I therefore wrote to methods, one for highlighting all matching words and then select first occurance, one for unselecting/unhighlighting them.
First run seams to do as it should, but if I repeat the search with another keyword, both the old and the new keyword are shown.
Here's my code fragment:
//
// search & replace:
// do_search_and_replace() - search for matching word
//
void MainWindow::do_search_and_replace(QString action_str)
{
int line, index;
qDebug() << "do_search_and_replace()";
// just to be sure...
if(action_str.isEmpty())
action_str == "0";
int action_nr = action_str.toInt(); // convert argument to int, so we can switch() on it...
text = ui->lineEdit_find->text();
docText = ui->textEdit->text();
qDebug() << "action_nr: " << action_nr;
//
// first part: Mark all occurances of search term
//
if (!( text.isEmpty() ))
{
qDebug() << text;
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE, 0, QsciScintilla::INDIC_FULLBOX);
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,0, QColor(Qt::darkBlue));
int end = docText.lastIndexOf(text);
int cur = -1;
if(end != -1)
{
ui->textEdit->getCursorPosition(&line, &index);
qDebug() << "line: " << line << " index: " << index;
while(cur != end)
{
cur = docText.indexOf(text,cur+1);
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE,cur,
text.length());
}
}
} // END text.isEmpty(), END mark ALL
//
// second part: Find firs occurance of search term
//
bool use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward;
use_regular_expression = false;
is_case_sensitive = ui->checkBox_CaseSensitive->isChecked();
match_whole_word_only = ui->checkBox_WholeWords->isChecked();
use_wrap = true;
search_forward = ui->radioButton_Forward->isChecked();
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE, 0, QsciScintilla::INDIC_FULLBOX);
//ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,0, QColor(Qt::darkBlue));
bool found = ui->textEdit->findFirst(text, use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward);
qDebug() << "START: found = " << found;
while(found)
{
ui->textEdit->getCursorPosition(&line, &index);
qDebug() << "line: " << line << " index: " << index;
qDebug() << text;
// pattern: found = findFirst(pattern, use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward)
//found = ui->textEdit->findFirst(text, use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward);
if(found)
{
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, line, text.length());
int start = ui->textEdit->positionFromLineIndex(line, index);
int end = ui->textEdit->positionFromLineIndex(line, index + text.length());
qDebug() << "line: " << line << " start: " << start << " end: " << end;
// found = ui->textEdit->findNext();
// ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORFILLRANGE, line, text.length());
}
found = false;
}
}
//
// unselect selected stuff
//
void MainWindow::reset_searchResult()
{
int line, index;
qDebug() << "in: reset_searchResult()";
//QString text = ui->lineEdit_find->text();
text.clear();
docText.clear();
//
// first part: Mark all occurances of search term
//
if (( text.isEmpty() ))
{
qDebug() << text;
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE, 0, QsciScintilla::INDIC_PLAIN);
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,0, QColor(Qt::white));
//docText = text;
docText = ui->lineEdit_find->text();
int end = docText.lastIndexOf(text);
int cur = -1;
if(end != -1)
{
ui->textEdit->getCursorPosition(&line, &index);
qDebug() << "line: " << line << " index: " << index;
while(cur != end)
{
cur = docText.indexOf(text,cur+1);
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORALLONFOR,cur, text.length());
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE,cur, text.length());
}
}
} // END text.isEmpty(), END mark ALL
//
// second part: Find firs occurance of search term
//
bool use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward;
use_regular_expression = false;
is_case_sensitive = ui->checkBox_CaseSensitive->isChecked();
match_whole_word_only = ui->checkBox_WholeWords->isChecked();
use_wrap = true;
search_forward = ui->radioButton_Forward->isChecked();
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETSTYLE, 0, QsciScintilla::INDIC_PLAIN);
//ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICSETFORE,0, QColor(Qt::darkBlue));
bool found = ui->textEdit->findFirst(text, use_regular_expression, is_case_sensitive, match_whole_word_only, use_wrap, search_forward);
qDebug() << "START: found = " << found;
while(found)
{
ui->textEdit->getCursorPosition(&line, &index);
if(found)
{
ui->textEdit->SendScintilla(QsciScintillaBase::SCI_INDICATORCLEARRANGE, line, text.length());
int start = ui->textEdit->positionFromLineIndex(line, index);
int end = ui->textEdit->positionFromLineIndex(line, index + text.length());
qDebug() << "line: " << line << " start: " << start << " end: " << end;
}
found = false;
}
}
I'm pretty sure this isn't the best code ever written, but all I can afford... ;)
Maybe someone who is fit with QScintilla can correct my attempts or provide me with a working search & highlight example that can be called multiple times without keeping the old results?
Thanks in advance, people!
Perhaps it's easier than you think, assume that you used QsciScintilla
instance for your ui->textEdit :
#define MY_MARKER_ID 0
void MainWindow::clearMarkers()
{
int lastLine = ui->textEdit->lines() - 1;
ui->textEdit->clearIndicatorRange( 0, 0, lastLine, ui->textEdit->text( lastLine ).length() - 1, MY_MARKER_ID );
}