From a88bdf25d77b3e189fc68437bbdb0cc3ffca9251 Mon Sep 17 00:00:00 2001 From: iaom <18504285112@163.com> Date: Thu, 17 Jun 2021 14:08:55 +0800 Subject: [PATCH] Add app search plugin. --- frontend/main.cpp | 2 +- libsearch/appsearch/app-search-plugin.cpp | 207 ++++++++++++++++++ libsearch/appsearch/app-search-plugin.h | 55 +++++ libsearch/appsearch/appsearch.pri | 2 + libsearch/index/file-search-plugin.cpp | 6 +- libsearch/index/file-search-plugin.h | 6 +- .../plugininterface/search-plugin-iface.h | 2 +- .../pluginmanage/search-plugin-manager.cpp | 2 + .../libukui-search/libukui-search_zh_CN.ts | 42 ++++ 9 files changed, 316 insertions(+), 8 deletions(-) create mode 100644 libsearch/appsearch/app-search-plugin.cpp create mode 100644 libsearch/appsearch/app-search-plugin.h diff --git a/frontend/main.cpp b/frontend/main.cpp index d23f675..df3571b 100644 --- a/frontend/main.cpp +++ b/frontend/main.cpp @@ -283,7 +283,7 @@ int main(int argc, char *argv[]) { QObject::connect(&app, &QtSingleApplication::messageReceived, w, &MainWindow::bootOptionsFilter); // Start app search thread - AppMatch::getAppMatch()->start(); +// AppMatch::getAppMatch()->start(); // NEW_TODO // Set threads which in global thread pool expiry time in 5ms, some prolems here diff --git a/libsearch/appsearch/app-search-plugin.cpp b/libsearch/appsearch/app-search-plugin.cpp new file mode 100644 index 0000000..254ea43 --- /dev/null +++ b/libsearch/appsearch/app-search-plugin.cpp @@ -0,0 +1,207 @@ +#include "app-search-plugin.h" +#include +using namespace Zeeker; +size_t AppSearchPlugin::uniqueSymbol = 0; +QMutex AppSearchPlugin::m_mutex; +AppSearchPlugin::AppSearchPlugin(QObject *parent) : QObject(parent) +{ + SearchPluginIface::Actioninfo open { 0, tr("Open")}; + SearchPluginIface::Actioninfo addtoDesktop { 1, tr("Add Shortcut to Desktop")}; + SearchPluginIface::Actioninfo addtoPanel { 2, tr("Add Shortcut to Panel")}; + SearchPluginIface::Actioninfo install { 0, tr("Install")}; + m_actionInfo_installed << open << addtoDesktop << addtoPanel; + m_actionInfo_not_installed << install; + AppMatch::getAppMatch()->start(); + m_pool.setMaxThreadCount(2); + m_pool.setExpiryTimeout(1000); +} + +const QString AppSearchPlugin::name() +{ + return tr("Applications Search"); +} + +const QString AppSearchPlugin::description() +{ + return tr("Applications Search"); +} + +QString AppSearchPlugin::getPluginName() +{ + return tr("Applications Search"); +} + +void AppSearchPlugin::KeywordSearch(QString keyword, DataQueue *searchResult) +{ + m_mutex.lock(); + ++uniqueSymbol; + m_mutex.unlock(); + AppSearch *appsearch = new AppSearch(searchResult, keyword, uniqueSymbol); + m_pool.start(appsearch); +} + +QList AppSearchPlugin::getActioninfo(int type) +{ + switch (type) { + case 0: + return m_actionInfo_installed; + break; + case 1: + return m_actionInfo_not_installed; + break; + default: + return QList(); + break; + } +} + +void AppSearchPlugin::openAction(int actionkey, QString key, int type) +{ + switch (type) { + case 0: + switch (actionkey) { + case 0: + if(!launch(key)) { + qWarning() << "Fail to launch:" << key; + } + break; + case 1: + if(!addDesktopShortcut(key)) { + qWarning() << "Fail to add Desktop Shortcut:" << key; + } + break; + case 2: + if(!addPanelShortcut(key)) { + qWarning() << "Fail to add Panel Shortcut:" << key; + } + break; + default: + break; + } + break; + case 1: + if(!installAppAction(key)) { + qWarning() << "Fail to install:" << key; + } + break; + default: + break; + } +} + +bool AppSearchPlugin::launch(const QString &path) +{ + GDesktopAppInfo * desktopAppInfo = g_desktop_app_info_new_from_filename(path.toLocal8Bit().data()); + bool res = static_cast(g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr)); + g_object_unref(desktopAppInfo); + return res; +} +bool AppSearchPlugin::addPanelShortcut(const QString& path) { + QDBusInterface iface("com.ukui.panel.desktop", + "/", + "com.ukui.panel.desktop", + QDBusConnection::sessionBus()); + if(iface.isValid()) { + QDBusReply isExist = iface.call("CheckIfExist", path); + if(isExist) { + qWarning() << "qDebug: Add shortcut to panel failed, because it is already existed!"; + return false; + } + QDBusReply ret = iface.call("AddToTaskbar", path); + qDebug() << "qDebug: Add shortcut to panel successed!"; + return true; + } + return false; +} + +bool AppSearchPlugin::addDesktopShortcut(const QString& path) { + QString dirpath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + QFileInfo fileInfo(path); + QString desktopfn = fileInfo.fileName(); + QFile file(path); + QString newName = QString(dirpath + "/" + desktopfn); + bool ret = file.copy(QString(dirpath + "/" + desktopfn)); + if(ret) { + QProcess process; + process.startDetached(QString("chmod a+x %1").arg(newName)); + return true; + } + return false; +} + +bool AppSearchPlugin::installAppAction(const QString & name) { + QDBusInterface * interface = new QDBusInterface("com.kylin.softwarecenter", + "/com/kylin/softwarecenter", + "com.kylin.utiliface", + QDBusConnection::sessionBus()); + + if(interface->isValid()) { + //软件商店已打开,直接跳转 + interface->call("show_search_result", name); + bool reply = QDBusReply(interface->call(QString("show_search_result"), name)); + return reply; + } else { + //软件商店未打开,打开软件商店下载此软件 + qDebug() << "Softwarecenter has not been launched, now launch it." << name; + QProcess process; + return process.startDetached(QString("kylin-software-center -find %1").arg(name)); + } +} + +AppSearch::AppSearch(DataQueue *searchResult, const QString &keyword, size_t uniqueSymbol) +{ + this->setAutoDelete(true); + m_search_result = searchResult; + m_keyword = keyword; + m_uniqueSymbol = uniqueSymbol; +} + +AppSearch::~AppSearch() +{ +} + +void AppSearch::run() +{ + //These weird code is mean to be compatible with the old version UI. + AppMatch::getAppMatch()->startMatchApp(m_keyword, m_installed_apps, m_not_installed_apps); + QMapIterator i(m_installed_apps); + while (i.hasNext()) { + i.next(); + SearchPluginIface::ResultInfo ri; + if(!QIcon::fromTheme(i.value().at(1)).isNull()) { + ri.icon = QIcon::fromTheme(i.value().at(1)); + }else { + ri.icon = QIcon(":/res/icons/desktop.png"); + } + ri.name = i.key().app_name; + ri.actionKey = i.value().at(0); + ri.type = 0; //0 means installed apps. + if (m_uniqueSymbol == AppSearchPlugin::uniqueSymbol) { + m_search_result->enqueue(ri); + } else { + break; + } + } + QMapIterator in(m_not_installed_apps); + while (in.hasNext()) { + in.next(); + SearchPluginIface::ResultInfo ri; + if(!QIcon(in.value().at(1)).isNull()) { + ri.icon = QIcon(in.value().at(1)); + }else { + ri.icon = QIcon(":/res/icons/desktop.png"); + } + ri.name = in.key().app_name; + SearchPluginIface::DescriptionInfo di; + di.key = QString(tr("Application Description:")); + di.value = in.value().at(3); + ri.description.append(di); + ri.actionKey = in.value().at(2); + ri.type = 1; //1 means not installed apps. + if (m_uniqueSymbol == AppSearchPlugin::uniqueSymbol) { + m_search_result->enqueue(ri); + } else { + break; + } + } +} diff --git a/libsearch/appsearch/app-search-plugin.h b/libsearch/appsearch/app-search-plugin.h new file mode 100644 index 0000000..de4ed31 --- /dev/null +++ b/libsearch/appsearch/app-search-plugin.h @@ -0,0 +1,55 @@ +#ifndef APPSEARCHPLUGIN_H +#define APPSEARCHPLUGIN_H + +#include +#include "search-plugin-iface.h" +#include "app-match.h" +#include "libsearch_global.h" +namespace Zeeker { +class LIBSEARCH_EXPORT AppSearchPlugin : public QObject, public SearchPluginIface +{ + friend class AppSearch; + Q_OBJECT +public: + AppSearchPlugin(QObject *parent = nullptr); + PluginType pluginType() {return PluginType::SearchPlugin;} + const QString name(); + const QString description(); + const QIcon icon() {return QIcon::fromTheme("appsearch");} + void setEnable(bool enable) {m_enable = enable;} + bool isEnable() {return m_enable;} + QString getPluginName(); + + void KeywordSearch(QString keyword,DataQueue *searchResult); + QList getActioninfo(int type); + void openAction(int actionkey, QString key, int type); +private: + bool launch(const QString &path); + bool addPanelShortcut(const QString &path); + bool addDesktopShortcut(const QString &path); + bool installAppAction(const QString &name); + bool m_enable = true; + QList m_actionInfo_installed; + QList m_actionInfo_not_installed; + QThreadPool m_pool; + static size_t uniqueSymbol; + static QMutex m_mutex; +}; + +class AppSearch : public QObject, public QRunnable { + Q_OBJECT +public: + AppSearch(DataQueue *searchResult, const QString& keyword, size_t uniqueSymbol); + ~AppSearch(); +protected: + void run() override; +private: + DataQueue *m_search_result = nullptr; + size_t m_uniqueSymbol; + QString m_keyword; + QMap m_installed_apps; + QMap m_not_installed_apps; +}; +} + +#endif // APPSEARCHPLUGIN_H diff --git a/libsearch/appsearch/appsearch.pri b/libsearch/appsearch/appsearch.pri index 4a3d55d..c222506 100644 --- a/libsearch/appsearch/appsearch.pri +++ b/libsearch/appsearch/appsearch.pri @@ -2,6 +2,8 @@ INCLUDEPATH += $$PWD HEADERS += \ $$PWD/app-match.h \ + $$PWD/app-search-plugin.h SOURCES += \ $$PWD/app-match.cpp \ + $$PWD/app-search-plugin.cpp diff --git a/libsearch/index/file-search-plugin.cpp b/libsearch/index/file-search-plugin.cpp index 67d9647..d8aecd4 100644 --- a/libsearch/index/file-search-plugin.cpp +++ b/libsearch/index/file-search-plugin.cpp @@ -49,7 +49,7 @@ QList FileSearchPlugin::getActioninfo(int type) return m_actionInfo; } -void FileSearchPlugin::openAction(int actionkey, QString key) +void FileSearchPlugin::openAction(int actionkey, QString key, int type) { //TODO add some return message here. switch (actionkey) { @@ -112,7 +112,7 @@ QList DirSearchPlugin::getActioninfo(int type) return m_actionInfo; } -void DirSearchPlugin::openAction(int actionkey, QString key) +void DirSearchPlugin::openAction(int actionkey, QString key, int type) { //TODO add some return message here. switch (actionkey) { @@ -173,7 +173,7 @@ QList FileContengSearchPlugin::getActioninfo(int return m_actionInfo; } -void FileContengSearchPlugin::openAction(int actionkey, QString key) +void FileContengSearchPlugin::openAction(int actionkey, QString key, int type) { //TODO add some return message here. switch (actionkey) { diff --git a/libsearch/index/file-search-plugin.h b/libsearch/index/file-search-plugin.h index 0c2fb28..ab33db3 100644 --- a/libsearch/index/file-search-plugin.h +++ b/libsearch/index/file-search-plugin.h @@ -24,7 +24,7 @@ public: void KeywordSearch(QString keyword,DataQueue *searchResult); QList getActioninfo(int type); - void openAction(int actionkey, QString key); + void openAction(int actionkey, QString key, int type = 0); private: bool m_enable = true; @@ -47,7 +47,7 @@ public: void KeywordSearch(QString keyword,DataQueue *searchResult); QList getActioninfo(int type); - void openAction(int actionkey, QString key); + void openAction(int actionkey, QString key, int type = 0); private: bool m_enable = true; @@ -70,7 +70,7 @@ public: void KeywordSearch(QString keyword,DataQueue *searchResult); QList getActioninfo(int type); - void openAction(int actionkey, QString key); + void openAction(int actionkey, QString key, int type = 0); private: bool m_enable = true; diff --git a/libsearch/plugininterface/search-plugin-iface.h b/libsearch/plugininterface/search-plugin-iface.h index f8c7c80..47d9e77 100644 --- a/libsearch/plugininterface/search-plugin-iface.h +++ b/libsearch/plugininterface/search-plugin-iface.h @@ -40,7 +40,7 @@ public: virtual QString getPluginName() = 0; virtual void KeywordSearch(QString keyword,DataQueue *searchResult) = 0; virtual QList getActioninfo(int type) = 0; - virtual void openAction(int actionkey, QString key) = 0; + virtual void openAction(int actionkey, QString key, int type) = 0; }; } diff --git a/libsearch/pluginmanage/search-plugin-manager.cpp b/libsearch/pluginmanage/search-plugin-manager.cpp index f9d2ee2..54a943b 100644 --- a/libsearch/pluginmanage/search-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-plugin-manager.cpp @@ -1,6 +1,7 @@ #include #include "search-plugin-manager.h" #include "file-search-plugin.h" +#include "app-search-plugin.h"- using namespace Zeeker; @@ -10,6 +11,7 @@ SearchPluginManager::SearchPluginManager(QObject *parent) registerPlugin(new FileSearchPlugin(this)); registerPlugin(new DirSearchPlugin(this)); registerPlugin(new FileContengSearchPlugin(this)); + registerPlugin(new AppSearchPlugin(this)); } bool SearchPluginManager::registerPlugin(Zeeker::SearchPluginIface *plugin) diff --git a/translations/libukui-search/libukui-search_zh_CN.ts b/translations/libukui-search/libukui-search_zh_CN.ts index 16cebf3..f2175a2 100644 --- a/translations/libukui-search/libukui-search_zh_CN.ts +++ b/translations/libukui-search/libukui-search_zh_CN.ts @@ -1,6 +1,48 @@ + + Zeeker::AppSearch + + + Application Description: + 应用描述: + + + + Zeeker::AppSearchPlugin + + + Open + 打开 + + + + Add Shortcut to Desktop + 添加到桌面快捷方式 + + + + Add Shortcut to Panel + 添加到任务栏快捷方式 + + + + Install + 安装 + + + + + + Applications Search + 应用搜索 + + + Application Description: + 应用描述: + + Zeeker::DirSearchPlugin