Skip to content

Commit

Permalink
fix: [find] improve search result display and parsing
Browse files Browse the repository at this point in the history
Enhance search result handling and display in multiple aspects:
- Add content truncation for large search results to prevent parsing issues
- Optimize search result text display with proper trimming and formatting
- Improve regex pattern for parsing search results with non-greedy matching
- Add content side length limit for better readability
- Refactor result model to handle data updates more efficiently

The changes focus on improving stability and user experience when handling large search results, while maintaining performance.

Log: fix search result display and parsing issues
  • Loading branch information
Kakueeen committed Dec 9, 2024
1 parent 7d53433 commit a48aa42
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 43 deletions.
3 changes: 3 additions & 0 deletions src/plugins/codeeditor/statusbar/encodecombobox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "utils/editorutils.h"

#include <DStyle>
#include <DGuiApplicationHelper>
#ifdef DTKWIDGET_CLASS_DPaletteHelper
#include <DPaletteHelper>
#else
Expand Down Expand Up @@ -49,6 +50,8 @@ void EncodeComboBox::initConnection()
if (curEncodeName != action->text())
Q_EMIT encodeChanged(action->text());
});
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged,
this, [this] { toolBtn->setIcon(createIcon()); });
}

void EncodeComboBox::initMenuData()
Expand Down
54 changes: 36 additions & 18 deletions src/plugins/find/gui/searchresultitemdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ inline constexpr int SpacePadding { 8 };
inline constexpr int LineNumberWidth { 40 };
inline constexpr int OptionButtonSize { 20 };
inline constexpr int CountNumberSize { 20 };
inline constexpr int ContentSideMaxLength { 100 };

SearchResultItemDelegate::SearchResultItemDelegate(QAbstractItemView *parent)
: DStyledItemDelegate(parent)
Expand Down Expand Up @@ -390,7 +391,9 @@ void SearchResultItemDelegate::drawContextItem(QPainter *painter, const QStyleOp
}
formats << createFormatRange(opt, column, matchedLength, {}, background);
}
drawDisplay(painter, option, textRect, context, formats);

auto [adjustedText, adjustedFormats] = adjustContent(index, context, formats);
drawDisplay(painter, option, textRect, adjustedText, adjustedFormats);
}

void SearchResultItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect,
Expand All @@ -402,11 +405,6 @@ void SearchResultItemDelegate::drawDisplay(QPainter *painter, const QStyleOption
painter->setPen(option.palette.color(QPalette::Normal, QPalette::Text));
}

// Remove leading spaces
QString displayText = text.trimmed();
if (displayText.isEmpty())
return;

const QStyleOptionViewItem opt = option;

const QWidget *widget = option.widget;
Expand All @@ -420,21 +418,12 @@ void SearchResultItemDelegate::drawDisplay(QPainter *painter, const QStyleOption
QTextLayout textLayout;
textLayout.setTextOption(textOption);
textLayout.setFont(option.font);
textLayout.setText(displayText);

// Adjust offsets in formatList
int offset = text.indexOf(displayText);
QList<QTextLayout::FormatRange> adjustedFormats = formatList;
if (offset != 0) {
for (auto &format : adjustedFormats) {
format.start -= offset;
}
}
textLayout.setFormats(adjustedFormats.toVector());
textLayout.setText(text);
textLayout.setFormats(formatList.toVector());

QSizeF textLayoutSize = doTextLayout(&textLayout, textRect.width());
if (textRect.width() < textLayoutSize.width()) {
displayText = option.fontMetrics.elidedText(displayText, Qt::ElideRight, textRect.width());
QString displayText = option.fontMetrics.elidedText(text, Qt::ElideRight, textRect.width());
textLayout.setText(displayText);
doTextLayout(&textLayout, textRect.width());
}
Expand Down Expand Up @@ -538,3 +527,32 @@ void SearchResultItemDelegate::drawIcon(QPainter *painter, const QStyleOptionVie

painter->drawPixmap(qRound(x), qRound(y), px);
}

QPair<QString, QList<QTextLayout::FormatRange>> SearchResultItemDelegate::adjustContent(const QModelIndex &index,
const QString &originalText,
const QList<QTextLayout::FormatRange> &formatList) const
{
auto adjustFormatRange = [&](int offset) {
QList<QTextLayout::FormatRange> adjustedFormats;
std::transform(formatList.cbegin(), formatList.cend(), std::back_inserter(adjustedFormats),
[&](const QTextLayout::FormatRange &format) {
return QTextLayout::FormatRange { format.start - offset, format.length, format.format };
});
return adjustedFormats;
};

const auto &matchedLength = index.data(MatchedLengthRole).toInt();
const auto &keywordOffset = index.data(ColumnRole).toInt();
const auto &replaceText = index.data(ReplaceTextRole).toString();
int replaceOffset = keywordOffset + matchedLength;

int leftStart = std::max(0, keywordOffset - ContentSideMaxLength);
int rightEnd = std::min(originalText.length(), replaceOffset + replaceText.length() + ContentSideMaxLength);

QString adjustedText = originalText.mid(leftStart, rightEnd - leftStart);
int offset = leftStart;
auto resultText = adjustedText.trimmed();
offset += adjustedText.indexOf(resultText);

return { resultText, adjustFormatRange(offset) };
}
3 changes: 3 additions & 0 deletions src/plugins/find/gui/searchresultitemdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class SearchResultItemDelegate : public DTK_WIDGET_NAMESPACE::DStyledItemDelegat
QTextLayout::FormatRange createFormatRange(const QStyleOptionViewItem &option, int start, int length,
const QColor &foreground, const QColor &background) const;
void drawIcon(QPainter *painter, const QStyleOptionViewItem &option, const QIcon &icon, const QRect &rect) const;
QPair<QString, QList<QTextLayout::FormatRange>> adjustContent(const QModelIndex &index,
const QString &originalText,
const QList<QTextLayout::FormatRange> &formatList) const;
};

#endif // SEARCHRESULTITEMDELEGATE_H
27 changes: 10 additions & 17 deletions src/plugins/find/gui/searchresultmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <DFileIconProvider>

#include <QRegularExpression>
#include <QTimer>
#include <QDebug>

DWIDGET_USE_NAMESPACE

Expand Down Expand Up @@ -105,32 +107,23 @@ FindItem *SearchResultModel::findItem(const QModelIndex &index) const
QString SearchResultModel::findGroup(const QModelIndex &index) const
{
if (index.isValid() && !index.parent().isValid() && index.column() == 0 && index.row() >= 0) {
const QList<QString> &keys = resultData.keys();
if (index.row() < keys.count())
return keys.at(index.row());
if (index.row() < resultData.count()) {
auto it = resultData.begin();
std::advance(it, index.row());
return it.key();
}
}

return QString();
}

void SearchResultModel::appendResult(const FindItemList &list)
{
QMap<QString, FindItemList> result;
beginResetModel();
for (const auto &item : list) {
if (!resultData.contains(item.filePathName)) {
if (result.contains(item.filePathName)) {
addItem(item.filePathName, result[item.filePathName]);
result.clear();
}
addGroup(item.filePathName);
result[item.filePathName].append(item);
} else {
result[item.filePathName].append(item);
}
resultData[item.filePathName].append(item);
}

for (auto iter = result.begin(); iter != result.end(); ++iter)
addItem(iter.key(), iter.value());
endResetModel();
}

QMap<QString, FindItemList> SearchResultModel::allResult() const
Expand Down
1 change: 1 addition & 0 deletions src/plugins/find/gui/searchresultmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "constants.h"

#include <QAbstractItemModel>
#include <QMutex>

class SearchResultModel : public QAbstractItemModel
{
Expand Down
21 changes: 13 additions & 8 deletions src/plugins/find/maincontroller/worker/searchreplaceworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,17 +386,22 @@ void SearchReplaceWorker::replace(const ReplaceParams &params)

void SearchReplaceWorker::handleReadSearchResult(const QString &keyword, SearchFlags flags)
{
const auto resultLineRegex = QRegularExpression(R"((.+):([0-9]+):(.+))", QRegularExpression::NoPatternOption);
static auto resultLineRegex = QRegularExpression(R"((.+?):([0-9]+?):(.+))", QRegularExpression::NoPatternOption);
while (d->resultCount < MaxResultCount && d->process->canReadLine()) {
const auto &line = d->process->readLine();
const auto &lineText = d->process->readLine();
QRegularExpressionMatch regMatch;
if ((regMatch = resultLineRegex.match(line)).hasMatch()) {
// When the content of `lineText` is too large, parsing issues may occur,
// so we truncate it to 1000 characters for parsing.
if ((regMatch = resultLineRegex.match(lineText.mid(0, 1000))).hasMatch()) {
auto name = regMatch.captured(1);
auto line = regMatch.captured(2).toInt();
auto context = regMatch.captured(3);

flags.testFlag(SearchRegularExpression) ? d->parseResultWithRegExp(name, keyword, context, line, flags)
: d->parseResultWithoutRegExp(name, keyword, context, line, flags);
auto lineNumb = regMatch.captured(2).toInt();
auto index = regMatch.capturedStart(3);
auto context = lineText.mid(index);
if (context.endsWith('\n'))
context.chop(1);

flags.testFlag(SearchRegularExpression) ? d->parseResultWithRegExp(name, keyword, context, lineNumb, flags)
: d->parseResultWithoutRegExp(name, keyword, context, lineNumb, flags);
}
}

Expand Down

0 comments on commit a48aa42

Please sign in to comment.