Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions src/dde-grand-search-daemon/searcher/file/filesearchutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Q_DECLARE_LOGGING_CATEGORY(logDaemon)

using namespace GrandSearch;

MatchedItem FileSearchUtils::packItem(const QString &fileName, const QString &searcher, const QStringList &keywords, const QString &matchedContext)
MatchedItem FileSearchUtils::packItem(const QString &fileName, const QString &searcher, const QStringList &keywords)
{
qCDebug(logDaemon) << "Packing file item - File:" << fileName << "Searcher:" << searcher;
QFileInfo fileInfo(fileName);
Expand All @@ -29,7 +29,7 @@ MatchedItem FileSearchUtils::packItem(const QString &fileName, const QString &se
item.type = mimeType.name();
item.icon = mimeType.iconName();
item.searcher = searcher;
item.extra = QVariant::fromValue(extraData(fileInfo, keywords, matchedContext));
item.extra = QVariant::fromValue(extraData(fileInfo, keywords));

qCDebug(logDaemon) << "Item packed successfully - Name:" << item.name
<< "Type:" << item.type << "Icon:" << item.icon;
Expand Down Expand Up @@ -200,7 +200,7 @@ FileSearchUtils::SearchInfo FileSearchUtils::parseContent(const QString &content
return info;
}

QVariantHash FileSearchUtils::extraData(const QFileInfo &info, const QStringList &keywords, const QString &matchedContext)
QVariantHash FileSearchUtils::extraData(const QFileInfo &info, const QStringList &keywords)
{
qCDebug(logDaemon) << "Generating tailer data for file:" << info.absoluteFilePath();

Expand All @@ -223,17 +223,6 @@ QVariantHash FileSearchUtils::extraData(const QFileInfo &info, const QStringList
if (!keywords.isEmpty())
hash.insert(GRANDSEARCH_PROPERTY_ITEM_KEYWORDS, keywords);

if (!matchedContext.isEmpty()) {
QString context = matchedContext;
// 去除首尾的省略符号
if (context.startsWith("…"))
context = context.mid(1);
if (context.endsWith("…"))
context.chop(1);
if (!context.isEmpty())
hash.insert(GRANDSEARCH_PROPERTY_ITEM_MATCHEDCONTEXT, context);
}

hash.insert(GRANDSEARCH_PROPERTY_ITEM_TAILER, datas);
return hash;
}
Expand Down
4 changes: 2 additions & 2 deletions src/dde-grand-search-daemon/searcher/file/filesearchutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class FileSearchUtils
QList<Group> groupList; // 搜索类目表
};

static MatchedItem packItem(const QString &fileName, const QString &searcher, const QStringList &keywords = QStringList(), const QString &matchedContext = "");
static MatchedItem packItem(const QString &fileName, const QString &searcher, const QStringList &keywords = QStringList());
static QString groupKey(Group group);
static Group getGroupByName(const QString &fileName);
static Group getGroupBySuffix(const QString &suffix);
static Group getGroupByGroupName(const QString &groupName);
static SearchInfo parseContent(const QString &content);
static QVariantHash extraData(const QFileInfo &info, const QStringList &keywords, const QString &matchedContext);
static QVariantHash extraData(const QFileInfo &info, const QStringList &keywords);
static QStringList buildDFMSearchFileTypes(const QList<Group> &groupList);
static bool isPinyin(const QString &str);
static bool hasWildcard(const QString &str);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ bool FullTextWorkerPrivate::doSearch()

ContentOptionsAPI contentOptions(options);
contentOptions.setMaxPreviewLength(100);
contentOptions.setFullTextRetrievalEnabled(false); // 关闭全文获取,高亮改为客户端延迟加载
contentOptions.setFilenameContentMixedAndSearchEnabled(true);

engine->setSearchOptions(options);
Expand Down Expand Up @@ -105,11 +106,8 @@ bool FullTextWorkerPrivate::processResults(const SearchResultExpected &result)

m_tmpSearchResults << filePath;

// Get highlighted content preview
SearchResult mutableResult = const_cast<SearchResult &>(file);
ContentResultAPI contentResult(mutableResult);
QString highlightedContent = contentResult.highlightedContent();
MatchedItem item = FileSearchUtils::packItem(filePath, q->name(), keywords, highlightedContent);
// 高亮内容改为客户端延迟加载,不再在搜索阶段提取
MatchedItem item = FileSearchUtils::packItem(filePath, q->name(), keywords);

// Set higher weight so frontend dedup prefers content results over filename results
QVariantHash extra = item.extra.toHash();
Expand Down
8 changes: 3 additions & 5 deletions src/dde-grand-search-daemon/searcher/ocr/ocrtextworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,8 @@ bool OcrTextWorkerPrivate::processSearchResults(const DFMSEARCH::SearchResultExp

m_tmpSearchResults << filePath;

// Get OCR content and store in extra field
DFMSEARCH::SearchResult mutableResult = const_cast<DFMSEARCH::SearchResult &>(file);
OcrTextResultAPI ocrResult(const_cast<SearchResult &>(mutableResult));
QString ocrContent = ocrResult.highlightedContent();
GrandSearch::MatchedItem item = FileSearchUtils::packItem(filePath, q->name(), m_keywords, ocrContent);
// 高亮内容改为客户端延迟加载,不再在搜索阶段提取
GrandSearch::MatchedItem item = FileSearchUtils::packItem(filePath, q->name(), m_keywords);

{
QMutexLocker lk(&m_mutex);
Expand Down Expand Up @@ -160,6 +157,7 @@ bool OcrTextWorkerPrivate::searchByDFMSearch()
// Configure OCR options
OcrTextOptionsAPI ocrOptions(options);
ocrOptions.setMaxPreviewLength(50);
ocrOptions.setFullTextRetrievalEnabled(false); // 关闭全文获取,高亮改为客户端延迟加载
// Enable filename-OCR content mixed search
ocrOptions.setFilenameOcrContentMixedAndSearchEnabled(true);

Expand Down
4 changes: 4 additions & 0 deletions src/grand-search/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ find_package(${QT_NS} COMPONENTS
DBus
Network
REQUIRED)
find_package(dfm${DTK_VERSION_MAJOR}-search REQUIRED)

set(DBUSSRC
# dbus接口
Expand Down Expand Up @@ -228,6 +229,8 @@ set(CONTACTSSRC
set(UTILSSRC
utils/utils.h
utils/utils.cpp
utils/highlightprovider.h
utils/highlightprovider.cpp
utils/previewpluginconf.h
utils/filestatisticsthread.h
utils/filestatisticsthread.cpp
Expand Down Expand Up @@ -287,6 +290,7 @@ target_link_libraries(${BIN_NAME} PRIVATE
${Qt_LIBS}
${DTK_LIBS}
${GIO_LIB_LIBRARIES}
dfm${DTK_VERSION_MAJOR}-search
)

set(SRCS_SETTING
Expand Down
8 changes: 8 additions & 0 deletions src/grand-search/gui/exhibition/exhibitionwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ void ExhibitionWidget::clearData()
m_vLine->hide();
}

void ExhibitionWidget::setSearchKeyword(const QString &keyword)
{
Q_ASSERT(m_matchWidget);

qCDebug(logGrandSearch) << "Setting search keyword for highlight:" << keyword;
m_matchWidget->setSearchKeyword(keyword);
}

void ExhibitionWidget::onSelectNextItem()
{
if (this->isHidden()) {
Expand Down
6 changes: 6 additions & 0 deletions src/grand-search/gui/exhibition/exhibitionwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@

void clearData();

/**
* @brief 设置搜索关键词,传播到 MatchWidget 以管理高亮任务
* @param keyword 搜索关键词
*/
void setSearchKeyword(const QString &keyword);

public slots:

Check warning on line 40 in src/grand-search/gui/exhibition/exhibitionwidget.h

View workflow job for this annotation

GitHub Actions / cppcheck

There is an unknown macro here somewhere. Configuration is required. If slots is a macro then please configure it.
void onSelectNextItem();
void onSelectPreviousItem();
void onHandleItem();
Expand Down
6 changes: 6 additions & 0 deletions src/grand-search/gui/exhibition/matchresult/groupwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ void GroupWidget::setGroupName(const QString &groupName)
AC_SET_ACCESSIBLE_NAME(m_listView, groupName);
}

void GroupWidget::setSearchKeyword(const QString &keyword)
{
Q_ASSERT(m_listView);
m_listView->setSearchKeyword(keyword);
}

void GroupWidget::appendMatchedItems(const MatchedItems &newItems, const QString &searchGroupName)
{
Q_UNUSED(searchGroupName)
Expand Down
6 changes: 6 additions & 0 deletions src/grand-search/gui/exhibition/matchresult/groupwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ class GroupWidget : public Dtk::Widget::DWidget
void setSearchGroupName(const QString &searchGroupName);
QString searchGroupName() const;

/**
* @brief 设置当前搜索关键词,传播到列表视图以管理高亮任务
* @param keyword 搜索关键词
*/
void setSearchKeyword(const QString &keyword);

void setGroupName(const QString &groupName);
QString groupName() const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
#include "grandsearchlistview.h"
#include "grandsearchlistmodel.h"
#include "grandsearchlistdelegate.h"
#include "utils/utils.h"

Check warning on line 8 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "utils/utils.h" not found.
#include "utils/highlightprovider.h"

Check warning on line 9 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "utils/highlightprovider.h" not found.
#include "global/matcheditem.h"

Check warning on line 10 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "global/matcheditem.h" not found.
#include "global/builtinsearch.h"

Check warning on line 11 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "global/builtinsearch.h" not found.
#include "global/accessibility/acintelfunctions.h"

Check warning on line 12 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "global/accessibility/acintelfunctions.h" not found.
#include "thumbnail/thumbnail.h"

Check warning on line 13 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "thumbnail/thumbnail.h" not found.

#include <dfm-search/dsearch_global.h>

Check warning on line 15 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <dfm-search/dsearch_global.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <DGuiApplicationHelper>

Check warning on line 17 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DGuiApplicationHelper> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <DStandardPaths>

Check warning on line 18 in src/grand-search/gui/exhibition/matchresult/listview/grandsearchlistview.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DStandardPaths> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <QDebug>
#include <QFileInfo>
Expand Down Expand Up @@ -170,6 +174,15 @@
m_model->clear();
}

void GrandSearchListView::setSearchKeyword(const QString &keyword)
{
// 关键词改变时,丢弃所有旧的高亮任务
if (!m_currentKeyword.isEmpty()) {
HighlightProvider::instance()->cancelTask(m_currentKeyword);
}
m_currentKeyword = keyword;
}

void GrandSearchListView::updatePreviewItemState(const bool preview)
{
m_isPreviewItem = preview;
Expand Down Expand Up @@ -286,6 +299,9 @@
if (ThumbnailProvider::instance()->isSupported(mimetype)) {
ThumbnailProvider::instance()->requestThumbnail(item.item, mimetype, GrandSearch::ThumbnailSize::Large);
}

// 异步请求高亮内容(仅对全文搜索和OCR搜索)
requestHighlightContent(item, true);
}
}

Expand Down Expand Up @@ -330,3 +346,85 @@
}
}
}

void GrandSearchListView::requestHighlightContent(const MatchedItem &item, bool highPriority)
{
// 仅对全文搜索和 OCR 搜索请求高亮内容
if (item.searcher != GRANDSEARCH_CLASS_FILE_FULLTEXT
&& item.searcher != GRANDSEARCH_CLASS_OCR_TEXT) {
return;
}

if (m_currentKeyword.isEmpty() || item.item.isEmpty()) {
return;
}

QVariantHash extraHash = item.extra.toHash();

// 如果已经有 matchedContext,不需要再请求
if (extraHash.contains(GRANDSEARCH_PROPERTY_ITEM_MATCHEDCONTEXT)
&& !extraHash.value(GRANDSEARCH_PROPERTY_ITEM_MATCHEDCONTEXT).toString().isEmpty()) {
return;
}

// 从 item.extra 中获取实际搜索关键词(daemon 可能对用户输入做了转换/扩展)
QStringList keywords = extraHash.value(GRANDSEARCH_PROPERTY_ITEM_KEYWORDS, QStringList()).toStringList();
if (keywords.isEmpty()) {
return;
}

// 根据 searcher 类型确定 searchType
int searchType = 0;
if (item.searcher == GRANDSEARCH_CLASS_FILE_FULLTEXT) {
searchType = static_cast<int>(DFMSEARCH::SearchType::Content);
} else if (item.searcher == GRANDSEARCH_CLASS_OCR_TEXT) {
searchType = static_cast<int>(DFMSEARCH::SearchType::Ocr);
}

// 将关键词列表用空格连接为单个字符串,传给 fetchHighlight
HighlightProvider::instance()->requestHighlight(
m_currentKeyword, item.item, keywords.first(), searchType, highPriority);
}

void GrandSearchListView::onHighlightReady(const QString &keyword, const QString &filePath, const QString &content)
{
Q_UNUSED(keyword)
if (content.isEmpty()) {
return;
}

updateHighlight(filePath, content);
}

void GrandSearchListView::updateHighlight(const QString &filePath, const QString &content)
{
if (filePath.isEmpty() || content.isEmpty()) {
return;
}

// 遍历所有项,找到匹配的文件路径
for (int row = 0; row < m_model->rowCount(); ++row) {
QModelIndex index = m_model->index(row, 0);
if (!index.isValid()) {
continue;
}

QVariant data = m_model->data(index, DATA_ROLE);
if (!data.isValid()) {
continue;
}

MatchedItem item = data.value<MatchedItem>();
if (item.item == filePath) {
// 更新 extra hash 中的 matchedContext
QVariantHash extraHash = item.extra.toHash();
extraHash.insert(GRANDSEARCH_PROPERTY_ITEM_MATCHEDCONTEXT, content);
item.extra = extraHash;

QVariant searchMeta;
searchMeta.setValue(item);
m_model->setData(index, searchMeta, DATA_ROLE);
break;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,23 @@ class GrandSearchListView : public Dtk::Widget::DListView
void updatePreviewItemState(const bool preview);
bool isPreviewItem() const;

/**
* @brief 设置当前搜索关键词并清理旧的高亮任务
* @param keyword 新的搜索关键词
*/
void setSearchKeyword(const QString &keyword);

public slots:
void onSetThemeType(int type);

/**
* @brief 处理高亮内容获取完成(由 MatchWidget 统一连接信号后路由调用)
* @param keyword 搜索关键词(taskId)
* @param filePath 文件路径
* @param content 高亮内容
*/
void onHighlightReady(const QString &keyword, const QString &filePath, const QString &content);

signals:
void sigCurrentItemChanged(const MatchedItem &item);
void sigItemClicked();
Expand Down Expand Up @@ -78,6 +92,20 @@ private slots:
*/
void updateThumbnail(const QString &filePath, const QPixmap &thumbnail);

/**
* @brief 更新指定文件路径对应的项的高亮内容
* @param filePath 文件路径
* @param content 高亮内容
*/
void updateHighlight(const QString &filePath, const QString &content);

/**
* @brief 请求指定项的高亮内容(如果尚未请求)
* @param item 搜索结果项
* @param highPriority 是否为高优先级(可见区域)
*/
void requestHighlightContent(const MatchedItem &item, bool highPriority = false);

private:
GrandSearchListModel *m_model = nullptr;
GrandSearchListDelegate *m_delegate = nullptr;
Expand All @@ -86,6 +114,7 @@ private slots:
MatchedItems m_matchedItems;

bool m_isPreviewItem = false;
QString m_currentKeyword; // 当前搜索关键词,用于高亮任务管理
};

}
Expand Down
Loading
Loading