diff --git a/frontend/model/best-list-model.cpp b/frontend/model/best-list-model.cpp index a336043..cad96a6 100644 --- a/frontend/model/best-list-model.cpp +++ b/frontend/model/best-list-model.cpp @@ -97,9 +97,12 @@ const bool &BestListModel::isExpanded() void BestListModel::appendInfo(const QString &pluginId, const SearchPluginIface::ResultInfo &info) { - if (m_resourceTypes.contains(info.resourceType)) { - return; + for (const auto& item : m_items) { + if (info.actionKey == item->info().actionKey && info.resourceType == item->info().resourceType) { + return; + } + } } else { m_resourceTypes.append(info.resourceType); } diff --git a/libsearch/CMakeLists.txt b/libsearch/CMakeLists.txt index 92ae7b8..e285378 100644 --- a/libsearch/CMakeLists.txt +++ b/libsearch/CMakeLists.txt @@ -30,7 +30,8 @@ set(LIBUKUI_SEARCH_PC_PKGS uchardet kysdk-systime kysdk-datacollect - kylin-ai-base) + kylin-ai-base + ) foreach(PC_LIB IN ITEMS ${LIBUKUI_SEARCH_PC_PKGS}) pkg_check_modules(${PC_LIB} REQUIRED IMPORTED_TARGET ${PC_LIB}) @@ -105,6 +106,8 @@ set(LIBUKUI_SEARCH_SRC searchinterface/ukui-search-task.cpp searchinterface/ukui-search-task.h settingsearch/settings-search-plugin.cpp settingsearch/settings-search-plugin.h websearch/web-search-plugin.cpp websearch/web-search-plugin.h + aisearch/ai-search-plugin.cpp aisearch/ai-search-plugin.h + thumbnail-creator.cpp thumbnail-creator.h icon-loader.cpp icon-loader.h data-collecter.cpp data-collecter.h @@ -158,6 +161,7 @@ include_directories( searchinterface/searchtasks settingsearch websearch + aisearch ) target_compile_definitions(${PROJECT_NAME} PRIVATE diff --git a/libsearch/aisearch/ai-search-plugin.cpp b/libsearch/aisearch/ai-search-plugin.cpp new file mode 100644 index 0000000..de360e2 --- /dev/null +++ b/libsearch/aisearch/ai-search-plugin.cpp @@ -0,0 +1,340 @@ +/* + * + * Copyright (C) 2024, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: baijunjie + * + */ + +#include "ai-search-plugin.h" +#include "file-utils.h" +#include "thumbnail-creator.h" +#include "file-indexer-config.h" +#include +#include +#include +#include +#include +#include + +using namespace UkuiSearch; +size_t AiSearchPlugin::uniqueSymbolAi = 0; +QMutex AiSearchPlugin::mutex; +static const int THUMBNAIL_HEIGHT = 247; +static const int THUMBNAIL_WIDTH = 352; +bool AiSearch::s_failed = false; +DataManagementSession AiSearch::s_session = nullptr; +QMutex AiSearch::s_sessionMutex; + +AiSearchPlugin::AiSearchPlugin(QObject *parent) : QObject(parent) +{ + SearchPluginIface::Actioninfo open { 0, tr("Open")}; + SearchPluginIface::Actioninfo OpenPath {1, tr("Open path")}; + SearchPluginIface::Actioninfo CopyPath { 2, tr("Copy Path")}; + m_actionInfo << open << OpenPath << CopyPath; + m_pool.setMaxThreadCount(1); + m_thumbnailPool.setMaxThreadCount(1); + m_pool.setExpiryTimeout(1000); + m_timer = new QTimer(this); + m_timer->setInterval(500); + connect(m_timer, &QTimer::timeout, this, [ = ] { + if (FileIndexerConfig::getInstance()->isAiIndexEnable()) { + auto aiSearch = new AiSearch(m_searchResult, uniqueSymbolAi, m_keyword); + m_pool.start(aiSearch); + m_timer->stop(); + } + }); + initDetailPage(); +} + +const QString AiSearchPlugin::name() +{ + return "Ai Search"; +} + +const QString AiSearchPlugin::description() +{ + return tr("Ai Search"); +} + +QString AiSearchPlugin::getPluginName() +{ + return tr("Ai Search"); +} + +void AiSearchPlugin::KeywordSearch(QString keyword, DataQueue *searchResult) +{ + mutex.lock(); + uniqueSymbolAi++; + mutex.unlock(); + m_keyword = keyword; + m_searchResult = searchResult; + m_timer->start(); +} + +void AiSearchPlugin::stopSearch() +{ + mutex.lock(); + ++uniqueSymbolAi; + mutex.unlock(); + m_thumbnailPool.clear(); + m_pool.clear(); + m_timer->stop(); +} + +QList AiSearchPlugin::getActioninfo(int type) +{ + Q_UNUSED(type) + return m_actionInfo; +} + +void AiSearchPlugin::openAction(int actionkey, QString key, int type) +{ + Q_UNUSED(type) + //TODO add some return message here. + switch (actionkey) { + case 0: + if(FileUtils::openFile(key) == -1) { + QMessageBox msgBox(m_detailPage); + msgBox.setModal(true); + msgBox.addButton(tr("OK"), QMessageBox::YesRole); + msgBox.setIcon(QMessageBox::Information); + msgBox.setText(tr("Can not get a default application for opening %1.").arg(key)); + msgBox.exec(); + } + break; + case 1: + FileUtils::openFile(key, true); + break; + case 2: + FileUtils::copyPath(key); + default: + break; + } +} + +QWidget *AiSearchPlugin::detailPage(const SearchPluginIface::ResultInfo &ri) +{ + if(ri.actionKey == m_currentActionKey) { + return m_detailPage; + } + auto creator = new ThumbnailCreator(ri.actionKey, QSize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT), m_detailPage->window()->devicePixelRatio()); + connect(creator, &ThumbnailCreator::ready, this, [&, ri](const QString& uri, const QImage &image){ + if(uri != m_currentActionKey) { + return; + } + QPixmap pixmap = QPixmap::fromImage(image); + if(!pixmap.isNull()) { + m_iconLabel->setPixmap(pixmap); + m_detailLyt->setContentsMargins(8, (THUMBNAIL_HEIGHT - pixmap.height()) / 2 + 8, 16, 0); + } else { + m_iconLabel->setPixmap(ri.icon.pixmap(120, 120)); + } + }, Qt::QueuedConnection); + m_thumbnailPool.start(creator); + m_iconLabel->setPixmap(ri.icon.pixmap(120, 120)); + m_detailLyt->setContentsMargins(8, 50, 16, 0); + m_currentActionKey = ri.actionKey; + + QFontMetrics fontMetrics = m_nameLabel->fontMetrics(); + QString showName = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号 + m_nameLabel->setText(FileUtils::setAllTextBold(showName)); + if(QString::compare(showName, ri.name)) { + m_nameLabel->setToolTip(ri.name); + } else { + m_nameLabel->setToolTip(""); + } + m_pluginLabel->setText(tr("File")); + + m_pathLabel2->setText(m_pathLabel2->fontMetrics().elidedText(m_currentActionKey, Qt::ElideRight, m_pathLabel2->width())); + m_pathLabel2->setToolTip(m_currentActionKey); + QString modTimeText = ri.description.at(1).value; + m_timeLabel2->setText(modTimeText); + return m_detailPage; +} + +void AiSearchPlugin::initDetailPage() +{ + m_detailPage = new QWidget(); + m_detailPage->setFixedWidth(360); + m_detailPage->setAttribute(Qt::WA_TranslucentBackground); + m_detailLyt = new QVBoxLayout(m_detailPage); + m_detailLyt->setContentsMargins(8, 0, 16, 0); + m_iconLabel = new QLabel(m_detailPage); + m_iconLabel->setAlignment(Qt::AlignCenter); + m_iconLabel->setMinimumHeight(120); + + m_nameFrame = new QFrame(m_detailPage); + m_nameFrameLyt = new QHBoxLayout(m_nameFrame); + m_nameFrame->setLayout(m_nameFrameLyt); + m_nameFrameLyt->setContentsMargins(8, 0, 0, 0); + m_nameLabel = new QLabel(m_nameFrame); + m_nameLabel->setMaximumWidth(280); + m_pluginLabel = new QLabel(m_nameFrame); + m_pluginLabel->setEnabled(false); + m_nameFrameLyt->addWidget(m_nameLabel); + m_nameFrameLyt->addStretch(); + m_nameFrameLyt->addWidget(m_pluginLabel); + + m_line_1 = new SeparationLine(m_detailPage); + + m_pathFrame = new QFrame(m_detailPage); + m_pathFrameLyt = new QHBoxLayout(m_pathFrame); + m_pathLabel1 = new QLabel(m_pathFrame); + m_pathLabel2 = new QLabel(m_pathFrame); + m_pathLabel1->setText(tr("Path")); + m_pathLabel2->setFixedWidth(240); + m_pathLabel2->setAlignment(Qt::AlignRight); + m_pathFrameLyt->addWidget(m_pathLabel1); + m_pathFrameLyt->addStretch(); + m_pathFrameLyt->addWidget(m_pathLabel2); + + m_timeFrame = new QFrame(m_detailPage); + m_timeFrameLyt = new QHBoxLayout(m_timeFrame); + m_timeLabel1 = new QLabel(m_timeFrame); + m_timeLabel2 = new QLabel(m_timeFrame); + m_timeLabel2->setAlignment(Qt::AlignRight); + m_timeLabel1->setText(tr("Last time modified")); + m_timeFrameLyt->addWidget(m_timeLabel1); + m_timeFrameLyt->addStretch(); + m_timeFrameLyt->addWidget(m_timeLabel2); + + m_line_2 = new SeparationLine(m_detailPage); + + m_actionFrame = new QFrame(m_detailPage); + m_actionFrameLyt = new QVBoxLayout(m_actionFrame); + m_actionFrameLyt->setContentsMargins(8, 0, 0, 0); + m_actionLabel1 = new ActionLabel(tr("Open"), m_currentActionKey, m_actionFrame); + m_actionLabel2 = new ActionLabel(tr("Open path"), m_currentActionKey, m_actionFrame); + m_actionLabel3 = new ActionLabel(tr("Copy path"), m_currentActionKey, m_actionFrame); + + m_actionFrameLyt->addWidget(m_actionLabel1); + m_actionFrameLyt->addWidget(m_actionLabel2); + m_actionFrameLyt->addWidget(m_actionLabel3); + m_actionFrame->setLayout(m_actionFrameLyt); + + m_detailLyt->addWidget(m_iconLabel); + m_detailLyt->addWidget(m_nameFrame); + m_detailLyt->addWidget(m_line_1); + m_detailLyt->addWidget(m_pathFrame); + m_detailLyt->addWidget(m_timeFrame); + m_detailLyt->addWidget(m_line_2); + m_detailLyt->addWidget(m_actionFrame); + m_detailPage->setLayout(m_detailLyt); + m_detailLyt->addStretch(); + + connect(m_actionLabel1, &ActionLabel::actionTriggered, [ & ](){ + if(FileUtils::openFile(m_currentActionKey) == -1) { + QMessageBox msgBox(m_detailPage); + msgBox.setModal(true); + msgBox.addButton(tr("OK"), QMessageBox::YesRole); + msgBox.setIcon(QMessageBox::Information); + msgBox.setText(tr("Can not get a default application for opening %1.").arg(m_currentActionKey)); + msgBox.exec(); + } + }); + connect(m_actionLabel2, &ActionLabel::actionTriggered, [ & ](){ + FileUtils::openFile(m_currentActionKey, true); + }); + connect(m_actionLabel3, &ActionLabel::actionTriggered, [ & ](){ + FileUtils::copyPath(m_currentActionKey); + }); +} + +AiSearchPlugin::~AiSearchPlugin() +{ + m_pool.clear(); + m_thumbnailPool.clear(); + m_thumbnailPool.waitForDone(); + m_pool.waitForDone(); + AiSearch::destroySession(); +} + +AiSearch::AiSearch(DataQueue *searchResult, size_t uniqueSymbol, const QString &keyword) +{ + m_searchResult = searchResult; + m_uniqueSymbol = uniqueSymbol; + m_keyword = keyword; +} + +void AiSearch::run() +{ + this->keywordSearch(); +} + +void AiSearch::keywordSearch() +{ + if (!AiSearch::createSession()) { + return; + } + QJsonObject keyword; + keyword.insert(QStringLiteral("text"), m_keyword); + char* results = nullptr; + data_management_similarity_search(s_session, QJsonDocument(keyword).toJson().data(), &results); + for (const auto &aResult : QJsonDocument::fromJson(results).array()) { + if (aResult.isObject()) { + SearchPluginIface::ResultInfo ri; + if (createResultInfo(ri, aResult.toObject().value("filepath").toString())) { + AiSearchPlugin::mutex.lock(); + if (m_uniqueSymbol == AiSearchPlugin::uniqueSymbolAi) { + m_searchResult->enqueue(ri); + AiSearchPlugin::mutex.unlock(); + } else { + AiSearchPlugin::mutex.unlock(); + break; + } + } + } + } + data_management_free_search_result(s_session, results); +} + +bool AiSearch::createResultInfo(SearchPluginIface::ResultInfo &ri, const QString &path) +{ + QFileInfo info(path); + if(!info.exists()) { + return false; + } + ri.icon = FileUtils::getFileIcon(QUrl::fromLocalFile(path).toString(), false); + ri.name = info.fileName().replace("\r", " ").replace("\n", " "); + ri.toolTip = info.fileName(); + ri.resourceType = QStringLiteral("file"); + ri.description = QVector() \ + << SearchPluginIface::DescriptionInfo{"Path:", path} \ + << SearchPluginIface::DescriptionInfo{"Modified time:", info.lastModified().toString("yyyy/MM/dd hh:mm:ss")}; + ri.actionKey = path; + return true; +} + +AiSearch::~AiSearch() {} + +bool AiSearch::createSession() { + QMutexLocker locker(&s_sessionMutex); + if (!s_session || s_failed) { + if (data_management_create_session(&s_session, DataManagementType::SYS_SEARCH, getuid()) != DataManagementResult::DATA_MANAGEMENT_SUCCESS) { + s_failed = true; + qWarning() << "===Create data management session failed!===" << s_session; + return false; + } + } + return true; +} + +void AiSearch::destroySession() { + if (data_management_destroy_session(s_session) != DataManagementResult::DATA_MANAGEMENT_SUCCESS) { + qWarning() << "===fail to destroy session==="; + } +} diff --git a/libsearch/aisearch/ai-search-plugin.h b/libsearch/aisearch/ai-search-plugin.h new file mode 100644 index 0000000..35f02a1 --- /dev/null +++ b/libsearch/aisearch/ai-search-plugin.h @@ -0,0 +1,130 @@ +/* + * + * Copyright (C) 2024, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: baijunjie + * + */ + +#ifndef UKUI_SEARCH_AISEARCHPLUGIN_H +#define UKUI_SEARCH_AISEARCHPLUGIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "action-label.h" +#include "separation-line.h" +#include "search-plugin-iface.h" +#include "icon-loader.h" +#include "kylin-ai/ai-base/datamanagement.h" + +namespace UkuiSearch { +class LIBSEARCH_EXPORT AiSearchPlugin : public QObject, public SearchPluginIface { + Q_OBJECT + +public: + explicit AiSearchPlugin(QObject *parent = nullptr); + ~AiSearchPlugin() override; + PluginType pluginType() override { return PluginType::SearchPlugin; } + const QString name() override; + const QString description() override; + const QIcon icon() override { return IconLoader::loadIconQt(""); } + void setEnable(bool enable) override { m_enable = enable; } + bool isEnable() override { return m_enable; } + QString getPluginName() override; + + void KeywordSearch(QString keyword, DataQueue *searchResult) override; + + void stopSearch() override; + + QList getActioninfo(int type) override; + + void openAction(int actionkey, QString key, int type) override; + + QWidget *detailPage(const ResultInfo &ri) override; + + static size_t uniqueSymbolAi; + static QMutex mutex; + +private: + void initDetailPage(); + QString m_currentActionKey; + QWidget *m_detailPage; + QVBoxLayout *m_detailLyt = nullptr; + QLabel *m_iconLabel = nullptr; + QFrame *m_nameFrame = nullptr; + QHBoxLayout *m_nameFrameLyt = nullptr; + QLabel *m_nameLabel = nullptr; + QLabel *m_pluginLabel = nullptr; + SeparationLine *m_line_1 = nullptr; + QFrame *m_pathFrame = nullptr; + QLabel *m_pathLabel1 = nullptr; + QLabel *m_pathLabel2 = nullptr; + QHBoxLayout *m_pathFrameLyt = nullptr; + QFrame *m_timeFrame = nullptr; + QLabel *m_timeLabel1 = nullptr; + QLabel *m_timeLabel2 = nullptr; + QHBoxLayout *m_timeFrameLyt = nullptr; + + SeparationLine *m_line_2 = nullptr; + QFrame *m_actionFrame = nullptr; + QVBoxLayout *m_actionFrameLyt = nullptr; + ActionLabel *m_actionLabel1 = nullptr; + ActionLabel *m_actionLabel2 = nullptr; + ActionLabel *m_actionLabel3 = nullptr; + + QVBoxLayout * m_actionLyt = nullptr; + + bool m_enable = true; + QList m_actionInfo; + QThreadPool m_pool; + QThreadPool m_thumbnailPool; + DataManagementSession m_session; + QTimer *m_timer = nullptr; + QString m_keyword; + DataQueue *m_searchResult; +}; + +class AiSearch : public QRunnable { +public: + explicit AiSearch(DataQueue *searchResult, size_t uniqueSymbol, const QString& keyword); + ~AiSearch() override; + static bool createSession(); + static void destroySession(); + static DataManagementSession s_session; + static bool s_failed; + static QMutex s_sessionMutex; +protected: + void run() override; +private: + void keywordSearch(); + bool createResultInfo(SearchPluginIface::ResultInfo &ri, const QString& path); + + DataQueue *m_searchResult = nullptr; + size_t m_uniqueSymbol; + QString m_keyword; + +}; +} +#endif //UKUI_SEARCH_AISEARCHPLUGIN_H diff --git a/libsearch/appsearch/app-search-plugin.cpp b/libsearch/appsearch/app-search-plugin.cpp index e2bc217..b9e4189 100644 --- a/libsearch/appsearch/app-search-plugin.cpp +++ b/libsearch/appsearch/app-search-plugin.cpp @@ -403,7 +403,7 @@ bool AppSearchPlugin::installAppAction(const QString & name) //AppSearch::AppSearch(DataQueue *searchResult, DataQueue* appSearchResults, UkuiSearchTask *appSearchTask, QString keyword, size_t uniqueSymbol) //{ // this->setAutoDelete(true); -// m_search_result = searchResult; +// m_searchResult = searchResult; // m_appSearchResults = appSearchResults; // m_appSearchTask = appSearchTask; // m_appSearchTask->clearKeyWords(); @@ -440,7 +440,7 @@ bool AppSearchPlugin::installAppAction(const QString & name) //// m_appSearchResults->clear(); //// break; //// } -// m_search_result->enqueue(ri); +// m_searchResult->enqueue(ri); // } else { // is_empty = true; // } @@ -464,7 +464,7 @@ bool AppSearchPlugin::installAppAction(const QString & name) //bool AppSearch::isUniqueSymbolChanged() //{ -// QMutexLocker locker(&AppSearchPlugin::m_mutex); +// QMutexLocker locker(&AppSearchPlugin::mutex); // if (m_uniqueSymbol != AppSearchPlugin::uniqueSymbol) { // qDebug() << "uniqueSymbol changged, app search finished!"; // return true; diff --git a/libsearch/appsearch/app-search-plugin.h b/libsearch/appsearch/app-search-plugin.h index 114f323..c7bb518 100644 --- a/libsearch/appsearch/app-search-plugin.h +++ b/libsearch/appsearch/app-search-plugin.h @@ -110,7 +110,7 @@ private: // size_t m_uniqueSymbol; // UkuiSearchTask *m_appSearchTask = nullptr; // DataQueue* m_appSearchResults = nullptr; -// DataQueue *m_search_result = nullptr; +// DataQueue *m_searchResult = nullptr; //}; } diff --git a/libsearch/index/file-search-plugin.cpp b/libsearch/index/file-search-plugin.cpp index 5ebb5ee..0d7c599 100644 --- a/libsearch/index/file-search-plugin.cpp +++ b/libsearch/index/file-search-plugin.cpp @@ -29,6 +29,7 @@ #include "libkydate.h" #include "data-collecter.h" #include "file-reader.h" +#include "thumbnail-creator.h" #define OCR_ICONLABLE_WITH 352 #define OCR_ICONLABLE_HEIGHT 247 @@ -799,16 +800,4 @@ void FileContentSearchPlugin::initDetailPage() // return nullptr; //} -ThumbnailCreator::ThumbnailCreator(const QString &url, const QSize &targetSize, qreal dpr, QObject *parent): QObject(parent) -{ - setAutoDelete(true); - m_url = url; - m_targetSize = targetSize; - m_dpr = dpr; -} - -void ThumbnailCreator::run() -{ - Q_EMIT ready(m_url, FileReader::getInstance()->getThumbnail(m_url, m_targetSize, m_dpr)); -} #include "file-search-plugin.moc" diff --git a/libsearch/index/file-search-plugin.h b/libsearch/index/file-search-plugin.h index 385539c..e253735 100644 --- a/libsearch/index/file-search-plugin.h +++ b/libsearch/index/file-search-plugin.h @@ -205,23 +205,6 @@ private: QThreadPool m_pool; QThreadPool m_thumbnailPool; }; -class ThumbnailCreator : public QObject, public QRunnable -{ - Q_OBJECT -public: - explicit ThumbnailCreator(const QString &url, const QSize &targetSize, qreal dpr, QObject *parent = nullptr); - -protected: - void run() override; - -Q_SIGNALS: - void ready(QString url, const QImage &image); - -private: - QString m_url; - QSize m_targetSize; - qreal m_dpr; -}; } diff --git a/libsearch/pluginmanage/search-plugin-manager.cpp b/libsearch/pluginmanage/search-plugin-manager.cpp index a8eef46..d0ff138 100644 --- a/libsearch/pluginmanage/search-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-plugin-manager.cpp @@ -24,6 +24,7 @@ #include "settings-search-plugin.h" #include "note-search-plugin.h" #include "web-search-plugin.h" +#include "ai-search-plugin.h" #define PLUGIN_ORDER_SETTINGS QDir::homePath() + "/.config/org.ukui/ukui-search/ukui-search-plugin-order.conf" #define PLUGINS_INFO_GROUP "PluginsInfo" @@ -34,6 +35,8 @@ #define PLUGIN_EXTERNAL_VALUE "External" #define PLUGIN_PATH_VALUE "Path" #define PLUGIN_FIX_VALUE "FixPos" +static const QString SETTINGS_VERSION_KEY = "Version"; +static const QString SETTINGS_VERSION = "1.0"; using namespace UkuiSearch; @@ -42,6 +45,7 @@ SearchPluginManager::SearchPluginManager(QObject *parent) { Q_UNUSED(parent) initOrderSettings(); + registerPlugin(new AiSearchPlugin); registerPlugin(new AppSearchPlugin); registerPlugin(new NoteSearchPlugin); registerPlugin(new SettingsSearchPlugin); @@ -458,9 +462,16 @@ SearchPluginManager::~SearchPluginManager() void SearchPluginManager::initOrderSettings() { m_orderSettings = new QSettings(PLUGIN_ORDER_SETTINGS, QSettings::IniFormat, this); + bool needRefresh(false); m_orderSettings->beginGroup(PLUGINS_INFO_GROUP); if (m_orderSettings->childGroups().isEmpty()) { + needRefresh = true; + } else if (m_orderSettings->value(SETTINGS_VERSION_KEY).toString() != SETTINGS_VERSION) { + m_orderSettings->setValue(SETTINGS_VERSION_KEY, SETTINGS_VERSION); + needRefresh = true; + } + if (needRefresh) { bool isFixed(false); for (int i = 0; i < m_defaultPluginOrder.size(); i++) { QString pluginName = m_defaultPluginOrder.at(i); @@ -477,4 +488,4 @@ void SearchPluginManager::initOrderSettings() } } m_orderSettings->endGroup(); -} +} \ No newline at end of file diff --git a/libsearch/pluginmanage/search-plugin-manager.h b/libsearch/pluginmanage/search-plugin-manager.h index d441ffa..f7f4737 100644 --- a/libsearch/pluginmanage/search-plugin-manager.h +++ b/libsearch/pluginmanage/search-plugin-manager.h @@ -32,6 +32,7 @@ class SearchPluginManager : public QObject Q_OBJECT QStringList m_defaultPluginOrder = { + "Ai Search", "Applications Search", "Note Search", "Settings Search", diff --git a/libsearch/thumbnail-creator.cpp b/libsearch/thumbnail-creator.cpp new file mode 100644 index 0000000..c4cf566 --- /dev/null +++ b/libsearch/thumbnail-creator.cpp @@ -0,0 +1,38 @@ +/* + * + * Copyright (C) 2024, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: baijunjie + * + */ + +#include "thumbnail-creator.h" +#include "file-reader.h" + +using namespace UkuiSearch; + +ThumbnailCreator::ThumbnailCreator(const QString &url, const QSize &targetSize, qreal dpr, QObject *parent): QObject(parent) +{ + setAutoDelete(true); + m_url = url; + m_targetSize = targetSize; + m_dpr = dpr; +} + +void ThumbnailCreator::run() +{ + Q_EMIT ready(m_url, FileReader::getInstance()->getThumbnail(m_url, m_targetSize, m_dpr)); +} \ No newline at end of file diff --git a/libsearch/thumbnail-creator.h b/libsearch/thumbnail-creator.h new file mode 100644 index 0000000..4ba33c8 --- /dev/null +++ b/libsearch/thumbnail-creator.h @@ -0,0 +1,50 @@ +/* + * + * Copyright (C) 2024, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: baijunjie + * + */ + +#ifndef UKUI_SEARCH_THUMBNAILCREATOR_H +#define UKUI_SEARCH_THUMBNAILCREATOR_H + +#include +#include +#include + +namespace UkuiSearch { +class ThumbnailCreator : public QObject, public QRunnable +{ +Q_OBJECT +public: + explicit ThumbnailCreator(const QString &url, const QSize &targetSize, qreal dpr, QObject *parent = nullptr); + +protected: + void run() override; + +Q_SIGNALS: + void ready(QString url, const QImage &image); + +private: + QString m_url; + QSize m_targetSize; + qreal m_dpr; +}; +} + + +#endif //UKUI_SEARCH_THUMBNAILCREATOR_H