diff --git a/src/plugins/codeeditor/statusbar/encodecombobox.cpp b/src/plugins/codeeditor/statusbar/encodecombobox.cpp index 0c1fad048..7baa756e7 100644 --- a/src/plugins/codeeditor/statusbar/encodecombobox.cpp +++ b/src/plugins/codeeditor/statusbar/encodecombobox.cpp @@ -6,6 +6,7 @@ #include "utils/editorutils.h" #include +#include #ifdef DTKWIDGET_CLASS_DPaletteHelper #include #else @@ -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() diff --git a/src/plugins/find/gui/searchresultitemdelegate.cpp b/src/plugins/find/gui/searchresultitemdelegate.cpp index 7fd6d1d6c..d80c7c63d 100644 --- a/src/plugins/find/gui/searchresultitemdelegate.cpp +++ b/src/plugins/find/gui/searchresultitemdelegate.cpp @@ -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) @@ -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, @@ -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; @@ -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 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()); } @@ -538,3 +527,32 @@ void SearchResultItemDelegate::drawIcon(QPainter *painter, const QStyleOptionVie painter->drawPixmap(qRound(x), qRound(y), px); } + +QPair> SearchResultItemDelegate::adjustContent(const QModelIndex &index, + const QString &originalText, + const QList &formatList) const +{ + auto adjustFormatRange = [&](int offset) { + QList 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) }; +} diff --git a/src/plugins/find/gui/searchresultitemdelegate.h b/src/plugins/find/gui/searchresultitemdelegate.h index 43264ab46..c104c6dcc 100644 --- a/src/plugins/find/gui/searchresultitemdelegate.h +++ b/src/plugins/find/gui/searchresultitemdelegate.h @@ -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> adjustContent(const QModelIndex &index, + const QString &originalText, + const QList &formatList) const; }; #endif // SEARCHRESULTITEMDELEGATE_H diff --git a/src/plugins/find/gui/searchresultmodel.cpp b/src/plugins/find/gui/searchresultmodel.cpp index f78101575..44628bb88 100644 --- a/src/plugins/find/gui/searchresultmodel.cpp +++ b/src/plugins/find/gui/searchresultmodel.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include DWIDGET_USE_NAMESPACE @@ -105,9 +107,11 @@ 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 &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(); @@ -115,22 +119,11 @@ QString SearchResultModel::findGroup(const QModelIndex &index) const void SearchResultModel::appendResult(const FindItemList &list) { - QMap 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 SearchResultModel::allResult() const diff --git a/src/plugins/find/gui/searchresultmodel.h b/src/plugins/find/gui/searchresultmodel.h index f4820b2d9..273c94b9c 100644 --- a/src/plugins/find/gui/searchresultmodel.h +++ b/src/plugins/find/gui/searchresultmodel.h @@ -8,6 +8,7 @@ #include "constants.h" #include +#include class SearchResultModel : public QAbstractItemModel { diff --git a/src/plugins/find/maincontroller/worker/searchreplaceworker.cpp b/src/plugins/find/maincontroller/worker/searchreplaceworker.cpp index 440278247..4ced584b3 100644 --- a/src/plugins/find/maincontroller/worker/searchreplaceworker.cpp +++ b/src/plugins/find/maincontroller/worker/searchreplaceworker.cpp @@ -386,17 +386,22 @@ void SearchReplaceWorker::replace(const ReplaceParams ¶ms) 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); } }