增加文件搜索插件标签搜索功能
This commit is contained in:
parent
f76f8c8d14
commit
130c46508b
|
@ -37,6 +37,7 @@ public:
|
||||||
void clearAllConditions();
|
void clearAllConditions();
|
||||||
void clearKeyWords();
|
void clearKeyWords();
|
||||||
void clearSearchDir();
|
void clearSearchDir();
|
||||||
|
void clearFileLabel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 分页选项
|
* @brief 分页选项
|
||||||
|
|
|
@ -172,6 +172,7 @@ void SearchControllerPrivate::clearAllConditions()
|
||||||
{
|
{
|
||||||
clearKeyWords();
|
clearKeyWords();
|
||||||
clearSearchDir();
|
clearSearchDir();
|
||||||
|
clearFileLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchControllerPrivate::clearKeyWords()
|
void SearchControllerPrivate::clearKeyWords()
|
||||||
|
@ -184,6 +185,11 @@ void SearchControllerPrivate::clearSearchDir()
|
||||||
m_searchDirs.clear();
|
m_searchDirs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchControllerPrivate::clearFileLabel()
|
||||||
|
{
|
||||||
|
m_FileLabels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void SearchControllerPrivate::setPagination(unsigned int first, unsigned int maxResults)
|
void SearchControllerPrivate::setPagination(unsigned int first, unsigned int maxResults)
|
||||||
{
|
{
|
||||||
m_first = first;
|
m_first = first;
|
||||||
|
@ -337,6 +343,11 @@ void SearchController::clearSearchDir()
|
||||||
d->clearSearchDir();
|
d->clearSearchDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchController::clearFileLabel()
|
||||||
|
{
|
||||||
|
d->clearFileLabel();
|
||||||
|
}
|
||||||
|
|
||||||
void SearchController::setPagination(unsigned int first, unsigned int maxResults)
|
void SearchController::setPagination(unsigned int first, unsigned int maxResults)
|
||||||
{
|
{
|
||||||
d->setPagination(first, maxResults);
|
d->setPagination(first, maxResults);
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
void clearAllConditions();
|
void clearAllConditions();
|
||||||
void clearKeyWords();
|
void clearKeyWords();
|
||||||
void clearSearchDir();
|
void clearSearchDir();
|
||||||
|
void clearFileLabel();
|
||||||
|
|
||||||
void setPagination(unsigned int first, unsigned int maxResults);
|
void setPagination(unsigned int first, unsigned int maxResults);
|
||||||
unsigned int first() const;
|
unsigned int first() const;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
using namespace UkuiSearch;
|
using namespace UkuiSearch;
|
||||||
FileSearchTask::FileSearchTask(QObject *parent)
|
FileSearchTask::FileSearchTask(QObject *parent)
|
||||||
|
@ -62,14 +63,23 @@ void FileSearchWorker::run()
|
||||||
searchDirs.removeDuplicates();
|
searchDirs.removeDuplicates();
|
||||||
|
|
||||||
for (QString &dir : searchDirs) {
|
for (QString &dir : searchDirs) {
|
||||||
if (dir.endsWith("/")) {
|
if (QFileInfo::exists(dir)) {
|
||||||
dir = dir.mid(0, dir.length() - 1);
|
if (dir.endsWith("/")) {
|
||||||
}
|
dir.remove(dir.length() - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList blackListTmp = DirWatcher::getDirWatcher()->blackListOfDir(dir);
|
QStringList blackListTmp = DirWatcher::getDirWatcher()->blackListOfDir(dir);
|
||||||
if (!blackListTmp.contains(dir)) {
|
if (!blackListTmp.contains(dir)) {
|
||||||
m_validDirectories.append(dir);
|
m_validDirectories.append(dir);
|
||||||
m_blackList.append(blackListTmp);
|
m_blackList.append(blackListTmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//过滤空标签
|
||||||
|
for (QString &label : m_searchController->getFileLabel()) {
|
||||||
|
if (!label.isEmpty()) {
|
||||||
|
m_labels.append(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +90,15 @@ void FileSearchWorker::run()
|
||||||
finished = searchWithIndex();
|
finished = searchWithIndex();
|
||||||
|
|
||||||
} else {
|
} 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";
|
qDebug() << "direct search";
|
||||||
finished = directSearch();
|
finished = directSearch();
|
||||||
}
|
}
|
||||||
|
@ -182,7 +201,12 @@ bool FileSearchWorker::directSearch()
|
||||||
for (const auto &fileInfo : infoList) {
|
for (const auto &fileInfo : infoList) {
|
||||||
if (fileInfo.isDir() && !fileInfo.isSymLink()) {
|
if (fileInfo.isDir() && !fileInfo.isSymLink()) {
|
||||||
QString newPath = fileInfo.absoluteFilePath();
|
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;
|
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 (m_searchController->beginSearchIdCheck(m_currentSearchId)) {
|
||||||
if (matched) {
|
if (matched) {
|
||||||
ResultItem ri(m_currentSearchId, fileInfo.absoluteFilePath());
|
ResultItem ri(m_currentSearchId, fileInfo.absoluteFilePath());
|
||||||
|
@ -224,33 +252,69 @@ bool FileSearchWorker::directSearch()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSearchFilter::FileSearchFilter(FileSearchWorker *parent) : parent(parent) {}
|
FileSearchFilter::FileSearchFilter(FileSearchWorker *parent) : m_parent(parent) {}
|
||||||
|
|
||||||
bool FileSearchFilter::operator ()(const Xapian::Document &doc) const
|
bool FileSearchFilter::operator ()(const Xapian::Document &doc) const
|
||||||
{
|
{
|
||||||
if (parent) {
|
if (m_parent) {
|
||||||
QString path = QString::fromStdString(doc.get_data());
|
QString path = QString::fromStdString(doc.get_data());
|
||||||
bool isRecurse = parent->m_searchController->isRecurse();
|
bool isRecurse = m_parent->m_searchController->isRecurse();
|
||||||
bool inSearchDir = std::any_of(parent->m_validDirectories.begin(), parent->m_validDirectories.end(), [&](QString &dir) {
|
bool inSearchDir = true;
|
||||||
bool startWithDir = path.startsWith(dir);
|
|
||||||
if (!startWithDir) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.length() == dir.length()) {
|
if (!m_parent->m_validDirectories.empty()) {
|
||||||
return false;
|
inSearchDir = std::any_of(m_parent->m_validDirectories.begin(), m_parent->m_validDirectories.end(), [&](QString &dir) {
|
||||||
}
|
//限制搜索在该目录下
|
||||||
|
if (!path.startsWith(dir + "/")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isRecurse) {
|
if (!isRecurse) {
|
||||||
//去除搜索路径后,是否包含 "/"
|
//去除搜索路径后,是否包含 "/"
|
||||||
return !path.midRef((dir.length() + 1), (path.length() - dir.length() - 1)).contains("/");
|
return !path.midRef((dir.length() + 1), (path.length() - dir.length() - 1)).contains("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ private:
|
||||||
size_t m_currentSearchId = 0;
|
size_t m_currentSearchId = 0;
|
||||||
QStringList m_validDirectories;
|
QStringList m_validDirectories;
|
||||||
QStringList m_blackList;
|
QStringList m_blackList;
|
||||||
|
QStringList m_labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileSearchFilter : public Xapian::MatchDecider {
|
class FileSearchFilter : public Xapian::MatchDecider {
|
||||||
|
@ -73,8 +74,16 @@ public:
|
||||||
explicit FileSearchFilter(FileSearchWorker *parent);
|
explicit FileSearchFilter(FileSearchWorker *parent);
|
||||||
bool operator ()(const Xapian::Document &doc) const;
|
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:
|
private:
|
||||||
FileSearchWorker *parent = nullptr;
|
FileSearchWorker *m_parent = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
void clearAllConditions();
|
void clearAllConditions();
|
||||||
void clearKeyWords();
|
void clearKeyWords();
|
||||||
void clearSearchDir();
|
void clearSearchDir();
|
||||||
|
void clearFileLabel();
|
||||||
void setPagination(unsigned int first, unsigned int maxResults);
|
void setPagination(unsigned int first, unsigned int maxResults);
|
||||||
|
|
||||||
size_t startSearch(SearchType searchtype, QString customSearchType = QString());
|
size_t startSearch(SearchType searchtype, QString customSearchType = QString());
|
||||||
|
|
|
@ -100,6 +100,11 @@ void UkuiSearchTaskPrivate::clearSearchDir()
|
||||||
m_searchCotroller->clearSearchDir();
|
m_searchCotroller->clearSearchDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UkuiSearchTaskPrivate::clearFileLabel()
|
||||||
|
{
|
||||||
|
m_searchCotroller->clearFileLabel();
|
||||||
|
}
|
||||||
|
|
||||||
void UkuiSearchTaskPrivate::setPagination(unsigned int first, unsigned int maxResults)
|
void UkuiSearchTaskPrivate::setPagination(unsigned int first, unsigned int maxResults)
|
||||||
{
|
{
|
||||||
m_searchCotroller->setPagination(first, maxResults);
|
m_searchCotroller->setPagination(first, maxResults);
|
||||||
|
@ -184,6 +189,11 @@ void UkuiSearchTask::clearSearchDir()
|
||||||
d->clearSearchDir();
|
d->clearSearchDir();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UkuiSearchTask::clearFileLabel()
|
||||||
|
{
|
||||||
|
d->clearFileLabel();
|
||||||
|
}
|
||||||
|
|
||||||
void UkuiSearchTask::setPagination(unsigned int first, unsigned int maxResults)
|
void UkuiSearchTask::setPagination(unsigned int first, unsigned int maxResults)
|
||||||
{
|
{
|
||||||
d->setPagination(first, maxResults);
|
d->setPagination(first, maxResults);
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
void clearAllConditions();
|
void clearAllConditions();
|
||||||
void clearKeyWords();
|
void clearKeyWords();
|
||||||
void clearSearchDir();
|
void clearSearchDir();
|
||||||
|
void clearFileLabel();
|
||||||
void setPagination(unsigned int first, unsigned int maxResults);
|
void setPagination(unsigned int first, unsigned int maxResults);
|
||||||
|
|
||||||
size_t startSearch(SearchType searchtype, QString customSearchType = QString());
|
size_t startSearch(SearchType searchtype, QString customSearchType = QString());
|
||||||
|
|
Loading…
Reference in New Issue