增加文件搜索插件标签搜索功能

This commit is contained in:
hewenfei 2022-04-28 15:49:51 +08:00
parent f76f8c8d14
commit 130c46508b
8 changed files with 125 additions and 27 deletions

View File

@ -37,6 +37,7 @@ public:
void clearAllConditions();
void clearKeyWords();
void clearSearchDir();
void clearFileLabel();
/**
* @brief

View File

@ -172,6 +172,7 @@ void SearchControllerPrivate::clearAllConditions()
{
clearKeyWords();
clearSearchDir();
clearFileLabel();
}
void SearchControllerPrivate::clearKeyWords()
@ -184,6 +185,11 @@ void SearchControllerPrivate::clearSearchDir()
m_searchDirs.clear();
}
void SearchControllerPrivate::clearFileLabel()
{
m_FileLabels.clear();
}
void SearchControllerPrivate::setPagination(unsigned int first, unsigned int maxResults)
{
m_first = first;
@ -337,6 +343,11 @@ void SearchController::clearSearchDir()
d->clearSearchDir();
}
void SearchController::clearFileLabel()
{
d->clearFileLabel();
}
void SearchController::setPagination(unsigned int first, unsigned int maxResults)
{
d->setPagination(first, maxResults);

View File

@ -52,6 +52,7 @@ public:
void clearAllConditions();
void clearKeyWords();
void clearSearchDir();
void clearFileLabel();
void setPagination(unsigned int first, unsigned int maxResults);
unsigned int first() const;

View File

@ -7,6 +7,7 @@
#include <QFile>
#include <QQueue>
#include <QDebug>
#include <gio/gio.h>
using namespace UkuiSearch;
FileSearchTask::FileSearchTask(QObject *parent)
@ -62,8 +63,9 @@ void FileSearchWorker::run()
searchDirs.removeDuplicates();
for (QString &dir : searchDirs) {
if (QFileInfo::exists(dir)) {
if (dir.endsWith("/")) {
dir = dir.mid(0, dir.length() - 1);
dir.remove(dir.length() - 1, 1);
}
QStringList blackListTmp = DirWatcher::getDirWatcher()->blackListOfDir(dir);
@ -72,6 +74,14 @@ void FileSearchWorker::run()
m_blackList.append(blackListTmp);
}
}
}
//过滤空标签
for (QString &label : m_searchController->getFileLabel()) {
if (!label.isEmpty()) {
m_labels.append(label);
}
}
bool finished = true;
//TODO 还需要判断是否为不能建立索引的目录
@ -80,6 +90,15 @@ void FileSearchWorker::run()
finished = searchWithIndex();
} else {
if (m_validDirectories.empty()) {
//TODO 使用全局的默认可搜索目录
if (QFileInfo::exists(QDir::homePath())) {
sendErrorMsg(QObject::tr("Warning, Can not find home path."));
return;
}
m_validDirectories.append(QDir::homePath());
m_blackList.append(DirWatcher::getDirWatcher()->blackListOfDir(QDir::homePath()));
}
qDebug() << "direct search";
finished = directSearch();
}
@ -182,7 +201,12 @@ bool FileSearchWorker::directSearch()
for (const auto &fileInfo : infoList) {
if (fileInfo.isDir() && !fileInfo.isSymLink()) {
QString newPath = fileInfo.absoluteFilePath();
if (m_blackList.contains(newPath)) {
bool inBlackList = std::any_of(m_blackList.begin(), m_blackList.end(), [&] (const QString &dir) {
return newPath.startsWith(dir + "/");
});
if (inBlackList) {
//在黑名单的路径忽略搜索
continue;
}
@ -203,6 +227,10 @@ bool FileSearchWorker::directSearch()
}
}
if (matched && !m_labels.empty()) {
matched = FileSearchFilter::checkFileLabel(fileInfo.absoluteFilePath(), m_labels);
}
if (m_searchController->beginSearchIdCheck(m_currentSearchId)) {
if (matched) {
ResultItem ri(m_currentSearchId, fileInfo.absoluteFilePath());
@ -224,20 +252,19 @@ bool FileSearchWorker::directSearch()
return true;
}
FileSearchFilter::FileSearchFilter(FileSearchWorker *parent) : parent(parent) {}
FileSearchFilter::FileSearchFilter(FileSearchWorker *parent) : m_parent(parent) {}
bool FileSearchFilter::operator ()(const Xapian::Document &doc) const
{
if (parent) {
if (m_parent) {
QString path = QString::fromStdString(doc.get_data());
bool isRecurse = parent->m_searchController->isRecurse();
bool inSearchDir = std::any_of(parent->m_validDirectories.begin(), parent->m_validDirectories.end(), [&](QString &dir) {
bool startWithDir = path.startsWith(dir);
if (!startWithDir) {
return false;
}
bool isRecurse = m_parent->m_searchController->isRecurse();
bool inSearchDir = true;
if (path.length() == dir.length()) {
if (!m_parent->m_validDirectories.empty()) {
inSearchDir = std::any_of(m_parent->m_validDirectories.begin(), m_parent->m_validDirectories.end(), [&](QString &dir) {
//限制搜索在该目录下
if (!path.startsWith(dir + "/")) {
return false;
}
@ -248,9 +275,46 @@ bool FileSearchFilter::operator ()(const Xapian::Document &doc) const
return true;
});
}
return inSearchDir;
bool hasLabel = true;
if (inSearchDir && !m_parent->m_labels.empty()) {
hasLabel = FileSearchFilter::checkFileLabel(path, m_parent->m_labels);
}
return inSearchDir && hasLabel;
}
return true;
}
bool FileSearchFilter::checkFileLabel(const QString &path, const QStringList &labels)
{
bool hasLabel = false;
GFile *file = g_file_new_for_path(path.toUtf8().constData());
if (file) {
GFileInfo *info = g_file_query_info(file, "metadata::*," G_FILE_ATTRIBUTE_ID_FILE, G_FILE_QUERY_INFO_NONE,
nullptr, nullptr);
if (info) {
gboolean hasKey = g_file_info_has_attribute(info, "metadata::peony-file-label-ids");
if (hasKey) {
char *fileLabels = g_file_info_get_attribute_as_string(info, "metadata::peony-file-label-ids");
if (fileLabels) {
QStringList fileLabelList = QString::fromUtf8(fileLabels).split("\n");
g_free(fileLabels);
hasLabel = std::any_of(fileLabelList.begin(), fileLabelList.end(), [&](QString &fileLabel) {
return labels.contains(fileLabel);
});
}
}
g_object_unref(info);
}
g_object_unref(file);
}
return hasLabel;
}

View File

@ -66,6 +66,7 @@ private:
size_t m_currentSearchId = 0;
QStringList m_validDirectories;
QStringList m_blackList;
QStringList m_labels;
};
class FileSearchFilter : public Xapian::MatchDecider {
@ -73,8 +74,16 @@ public:
explicit FileSearchFilter(FileSearchWorker *parent);
bool operator ()(const Xapian::Document &doc) const;
/**
* @brief path对应的文件是否包含labels中的标签
* @param path
* @param labels
* @return
*/
static bool checkFileLabel(const QString &path, const QStringList &labels);
private:
FileSearchWorker *parent = nullptr;
FileSearchWorker *m_parent = nullptr;
};
}

View File

@ -27,6 +27,7 @@ public:
void clearAllConditions();
void clearKeyWords();
void clearSearchDir();
void clearFileLabel();
void setPagination(unsigned int first, unsigned int maxResults);
size_t startSearch(SearchType searchtype, QString customSearchType = QString());

View File

@ -100,6 +100,11 @@ void UkuiSearchTaskPrivate::clearSearchDir()
m_searchCotroller->clearSearchDir();
}
void UkuiSearchTaskPrivate::clearFileLabel()
{
m_searchCotroller->clearFileLabel();
}
void UkuiSearchTaskPrivate::setPagination(unsigned int first, unsigned int maxResults)
{
m_searchCotroller->setPagination(first, maxResults);
@ -184,6 +189,11 @@ void UkuiSearchTask::clearSearchDir()
d->clearSearchDir();
}
void UkuiSearchTask::clearFileLabel()
{
d->clearFileLabel();
}
void UkuiSearchTask::setPagination(unsigned int first, unsigned int maxResults)
{
d->setPagination(first, maxResults);

View File

@ -24,6 +24,7 @@ public:
void clearAllConditions();
void clearKeyWords();
void clearSearchDir();
void clearFileLabel();
void setPagination(unsigned int first, unsigned int maxResults);
size_t startSearch(SearchType searchtype, QString customSearchType = QString());