Commit 6de3698a authored by Kåre Särs's avatar Kåre Särs
Browse files

Move the calculation of the pre/post context to the search workers

The logic behind that is that it potentially uses less memory, but the
timing differences are negligible. Updating the match marks takes
almost the same amount of time as the actual searching in an open file.

The multi line post-context calculation is now also corrected.
parent f0534420
......@@ -103,8 +103,6 @@ int MatchModel::matchFileRow(const QUrl& fileUrl) const
return m_matchFileIndexHash.value(fileUrl, -1);
}
static const int totalContectLen = 150;
/** This function is used to add a match to a new file */
void MatchModel::addMatches(const QUrl &fileUrl, const QVector<KateSearchMatch> &searchMatches)
{
......@@ -134,31 +132,7 @@ void MatchModel::addMatches(const QUrl &fileUrl, const QVector<KateSearchMatch>
int matchIndex = m_matchFiles[fileIndex].matches.size();
beginInsertRows(createIndex(fileIndex, 0 , FileItemId), matchIndex, matchIndex + searchMatches.size()-1);
for (const auto &sMatch: searchMatches) {
MatchModel::Match match;
match.matchLen = sMatch.matchLen;
match.range = sMatch.matchRange;
int matchStartColumn = match.range.start().column();
int matchEndColumn = match.range.end().column();
int contextLen = totalContectLen - sMatch.matchLen;
int preLength = qMin(contextLen/3, matchStartColumn);
int postLength = contextLen - preLength;
match.preMatchStr = sMatch.lineContent.mid(matchStartColumn-preLength, preLength);
if (matchStartColumn > preLength) match.preMatchStr.prepend(QLatin1String("..."));
match.postMatchStr = sMatch.lineContent.mid(matchEndColumn, postLength);
if (matchEndColumn+postLength < sMatch.lineContent.size()-1) {
qDebug() << matchEndColumn << postLength << matchEndColumn+postLength << sMatch.lineContent.size();
match.postMatchStr.append(QLatin1String("..."));
}
match.matchStr = sMatch.lineContent.mid(matchStartColumn, sMatch.matchLen);
m_matchFiles[fileIndex].matches.append(match);
}
m_matchFiles[fileIndex].matches += searchMatches;
endInsertRows();
}
......@@ -169,7 +143,7 @@ void MatchModel::setMatchColors(const QColor &foreground, const QColor &backgrou
m_replaceHighlightColor = replaseBackground;
}
MatchModel::Match *MatchModel::matchFromIndex(const QModelIndex &matchIndex)
KateSearchMatch *MatchModel::matchFromIndex(const QModelIndex &matchIndex)
{
if (!isMatch(matchIndex)) {
qDebug() << "Not a valid match index";
......@@ -436,7 +410,7 @@ QString MatchModel::infoHtmlString() const
int checkedTotal = 0;
for (const auto &matchFile: qAsConst(m_matchFiles)) {
matchesTotal += matchFile.matches.size();
checkedTotal += std::count_if(matchFile.matches.begin(), matchFile.matches.end(), [](const MatchModel::Match &match) {return match.checked;} );
checkedTotal += std::count_if(matchFile.matches.begin(), matchFile.matches.end(), [](const KateSearchMatch &match) {return match.checked;} );
}
if (m_searchState == Searching) {
......@@ -488,7 +462,11 @@ QString MatchModel::fileToHtmlString(const MatchFile &matchFile) const
QString MatchModel::matchToHtmlString(const Match &match) const
{
QString pre =match.preMatchStr.toHtmlEscaped();
QString pre = match.preMatchStr;
if (match.preMatchStr.size() == PreContextLen) {
pre.replace(0, 3, QLatin1String("..."));
}
pre = pre.toHtmlEscaped();
QString matchStr = match.matchStr;
matchStr.replace(QLatin1Char('\n'), QStringLiteral("\\n"));
......@@ -504,7 +482,16 @@ QString MatchModel::matchToHtmlString(const Match &match) const
matchStr += QStringLiteral("<span style=\"background-color:%1; color:%2;\">%3</span>")
.arg(m_replaceHighlightColor.name(), m_foregroundColor.name(), replaceStr);
}
QString post = match.postMatchStr.toHtmlEscaped();
QString post = match.postMatchStr;
int nlIndex = post.indexOf(QLatin1Char('\n'));
if (nlIndex != -1) {
post = post.mid(0, nlIndex);
}
if (post.size() == PostContextLen) {
post.replace(PostContextLen-3, 3, QLatin1String("..."));
}
post = post.toHtmlEscaped();
// (line:col)[space][space] ...Line text pre [highlighted match] Line text post....
QString displayText = QStringLiteral("(<b>%1:%2</b>) &nbsp;")
......@@ -525,7 +512,7 @@ QString MatchModel::infoToPlainText() const
int checkedTotal = 0;
for (const auto &matchFile: qAsConst(m_matchFiles)) {
matchesTotal += matchFile.matches.size();
checkedTotal += std::count_if(matchFile.matches.begin(), matchFile.matches.end(), [](const MatchModel::Match &match) {return match.checked;} );
checkedTotal += std::count_if(matchFile.matches.begin(), matchFile.matches.end(), [](const KateSearchMatch &match) {return match.checked;} );
}
if (m_searchState == Searching) {
......@@ -782,8 +769,6 @@ QVariant MatchModel::data(const QModelIndex &index, int role) const
return match.range.end().line();
case EndColumnRole:
return match.range.end().column();
case MatchLenRole:
return match.matchLen;
case PreMatchRole:
return match.preMatchStr;
case MatchRole:
......@@ -876,7 +861,7 @@ bool MatchModel::setData(const QModelIndex &itemIndex, const QVariant &, int rol
// we toggle the current value
matches[row].checked = !matches[row].checked;
int checkedCount = std::count_if(matches.begin(), matches.end(), [](const MatchModel::Match &match) {return match.checked;});
int checkedCount = std::count_if(matches.begin(), matches.end(), [](const KateSearchMatch &match) {return match.checked;});
if (checkedCount == matches.size()) {
m_matchFiles[rootRow].checkState = Qt::Checked;
......
......@@ -22,19 +22,19 @@
/**
* data holder for one match in one file
* used to transfer multiple matches at once via signals to avoid heavy costs for files with a lot of matches
* used to transfer and hold multiple matches at once via signals to avoid heavy costs for files with a lot of matches
*/
class KateSearchMatch
{
public:
QString lineContent;
int matchLen;
KTextEditor::Range matchRange;
QString preMatchStr;
QString matchStr;
QString postMatchStr;
QString replaceText;
KTextEditor::Range range;
bool checked;
};
Q_DECLARE_METATYPE(KateSearchMatch)
class MatchModel : public QAbstractItemModel
{
......@@ -54,7 +54,6 @@ public:
StartColumnRole,
EndLineRole,
EndColumnRole,
MatchLenRole,
PreMatchRole,
MatchRole,
PostMatchRole,
......@@ -64,17 +63,13 @@ public:
};
Q_ENUM(MatchDataRoles)
private:
struct Match {
KTextEditor::Range range;
int matchLen = 0;
QString preMatchStr;
QString matchStr;
QString postMatchStr;
QString replaceText;
bool checked = true;
};
static constexpr int PreContextLen = 80;
static constexpr int PostContextLen = 100;
typedef KateSearchMatch Match;
private:
struct MatchFile {
QUrl fileUrl;
QVector<Match> matches;
......@@ -186,4 +181,7 @@ private:
};
Q_DECLARE_METATYPE(KateSearchMatch)
#endif
......@@ -120,11 +120,13 @@ void SearchDiskFiles::searchSingleLineRegExp(const QString &fileName)
while (column != -1 && !match.captured().isEmpty()) {
if (m_cancelSearch)
break;
// limit line length in the treeview
if (line.length() > 1024)
line = line.left(1024);
matches.push_back(KateSearchMatch{line, match.capturedLength(), KTextEditor::Range{i, column, i, column + match.capturedLength()}});
int endColumn = column + match.capturedLength();
int preContextStart = qMax(0, column-MatchModel::PreContextLen);
QString preContext = line.mid(preContextStart, column-preContextStart);
QString postContext = line.mid(endColumn, MatchModel::PostContextLen);
matches.push_back(KateSearchMatch{preContext, match.captured(), postContext, QString(), KTextEditor::Range{i, column, i, column + match.capturedLength()}, true});
match = m_regExp.match(line, column + match.capturedLength());
column = match.capturedStart();
......@@ -196,7 +198,13 @@ void SearchDiskFiles::searchMultiLineRegExp(const QString &fileName)
int endLine = line + match.captured().count(QLatin1Char('\n'));
int lastNL = match.captured().lastIndexOf(QLatin1Char('\n'));
int endColumn = lastNL == -1 ? startColumn + match.captured().length() : match.captured().length() - lastNL - 1;
matches.push_back(KateSearchMatch{fullDoc.mid(lineStart[line], column - lineStart[line]) + match.captured(), match.capturedLength(), KTextEditor::Range{line, startColumn, endLine, endColumn}});
int preContextStart = qMax(lineStart[line], column-MatchModel::PreContextLen);
QString preContext = fullDoc.mid(preContextStart, column-preContextStart);
QString postContext = fullDoc.mid(column + match.captured().length(), MatchModel::PostContextLen);
matches.push_back(KateSearchMatch{preContext, match.captured(), postContext, QString(), KTextEditor::Range{line, startColumn, endLine, endColumn}, true});
match = tmpRegExp.match(fullDoc, column + match.capturedLength());
column = match.capturedStart();
m_matchCount++;
......
......@@ -119,8 +119,17 @@ int SearchOpenFiles::searchSingleLineRegExp(KTextEditor::Document *doc, const QR
QRegularExpressionMatch match;
match = regExp.match(doc->line(line));
column = match.capturedStart();
while (column != -1 && !match.captured().isEmpty()) {
matches.push_back(KateSearchMatch{doc->line(line), match.capturedLength(), KTextEditor::Range{line, column, line, column + match.capturedLength()}});
int endColumn = column + match.capturedLength();
int preContextStart = qMax(0, column-MatchModel::PreContextLen);
const QString &lineStr = doc->line(line);
QString preContext = lineStr.mid(preContextStart, column-preContextStart);
QString postContext = lineStr.mid(endColumn, MatchModel::PostContextLen);
matches.push_back(KateSearchMatch{preContext, match.captured(), postContext, QString(),
KTextEditor::Range{line, column, line, column + match.capturedLength()}, true});
match = regExp.match(doc->line(line), column + match.capturedLength());
column = match.capturedStart();
}
......@@ -193,7 +202,13 @@ int SearchOpenFiles::searchMultiLineRegExp(KTextEditor::Document *doc, const QRe
int lastNL = match.captured().lastIndexOf(QLatin1Char('\n'));
int endColumn = lastNL == -1 ? startColumn + match.captured().length() : match.captured().length() - lastNL - 1;
matches.push_back(KateSearchMatch{doc->line(startLine).left(column - m_lineStart[startLine]) + match.captured(), match.capturedLength(), KTextEditor::Range{startLine, startColumn, endLine, endColumn}});
int preContextStart = qMax(0, startColumn-MatchModel::PreContextLen);
QString preContext = doc->line(startLine).mid(preContextStart, startColumn-preContextStart);
QString postContext = doc->line(endLine).mid(endColumn, MatchModel::PostContextLen);
matches.push_back(
KateSearchMatch{preContext, match.captured(), postContext, QString(),
KTextEditor::Range{startLine, startColumn, endLine, endColumn}, true});
match = tmpRegExp.match(m_fullDoc, column + match.capturedLength());
column = match.capturedStart();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment