ukui-search/libsearch/appsearch/app-match.cpp

299 lines
11 KiB
C++
Raw Normal View History

2021-01-29 11:43:07 +08:00
/*
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
*
* Authors: sunfengsheng <sunfengsheng@kylinos.cn>
*
*/
2020-12-30 15:31:36 +08:00
#include "app-match.h"
#include <glib.h>
2021-09-08 15:31:47 +08:00
#include <qt5xdg/XdgIcon>
#include <qt5xdg/XdgDesktopFile>
2020-12-30 21:41:00 +08:00
#include "file-utils.h"
#include "app-search-plugin.h"
2021-08-26 19:59:31 +08:00
#define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications/"
2021-12-14 14:43:35 +08:00
using namespace UkuiSearch;
2021-03-05 08:43:02 +08:00
static AppMatch *app_match_Class = nullptr;
2021-02-27 00:57:47 +08:00
2021-04-26 15:06:47 +08:00
AppMatch *AppMatch::getAppMatch() {
if(!app_match_Class) {
2021-03-05 08:43:02 +08:00
app_match_Class = new AppMatch;
}
return app_match_Class;
}
AppMatch::AppMatch(QObject *parent) : QThread(parent)
// m_versionCommand(new QProcess(this))
{
2021-04-26 15:06:47 +08:00
m_watchAppDir = new QFileSystemWatcher(this);
2021-02-27 00:57:47 +08:00
m_watchAppDir->addPath("/usr/share/applications/");
2021-08-26 19:59:31 +08:00
QDir androidPath(ANDROID_APP_DESKTOP_PATH);
if(!androidPath.exists()) {
androidPath.mkpath(ANDROID_APP_DESKTOP_PATH);
}
2021-08-26 19:59:31 +08:00
m_watchAppDir->addPath(ANDROID_APP_DESKTOP_PATH);
2021-04-26 15:06:47 +08:00
qDBusRegisterMetaType<QMap<QString, QString>>();
qDBusRegisterMetaType<QList<QMap<QString, QString>>>();
m_interFace = new QDBusInterface("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults",
"com.kylin.getsearchresults",
QDBusConnection::sessionBus());
if(!m_interFace->isValid()) {
2021-02-26 11:21:41 +08:00
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
2021-04-26 15:06:47 +08:00
}
2021-09-13 19:46:39 +08:00
m_interFace->setTimeout(1500);
qDebug() << "AppMatch init finished.";
2020-12-30 15:31:36 +08:00
}
2021-04-26 15:06:47 +08:00
AppMatch::~AppMatch() {
if(m_interFace) {
2021-02-26 11:38:22 +08:00
delete m_interFace;
}
2021-04-26 15:06:47 +08:00
m_interFace = NULL;
if(m_watchAppDir) {
2021-02-27 00:57:47 +08:00
delete m_watchAppDir;
}
2021-04-26 15:06:47 +08:00
m_watchAppDir = NULL;
2021-02-26 11:38:22 +08:00
}
void AppMatch::startMatchApp(QString input, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult) {
appNameMatch(input, uniqueSymbol, searchResult);
slotDBusCallFinished(input, uniqueSymbol, searchResult);
qDebug() << "App match finished!";
2021-03-05 08:43:02 +08:00
}
2020-12-30 15:31:36 +08:00
2020-12-30 21:41:00 +08:00
/**
* @brief AppMatch::getAllDesktopFilePath desktop文件
* @param path desktop文件夹
*/
2021-04-26 15:06:47 +08:00
void AppMatch::getAllDesktopFilePath(QString path) {
2020-12-30 15:31:36 +08:00
QDir dir(path);
2021-04-26 15:06:47 +08:00
if(!dir.exists()) {
2020-12-30 15:31:36 +08:00
return;
}
2021-04-26 15:06:47 +08:00
dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
2020-12-30 15:31:36 +08:00
dir.setSorting(QDir::DirsFirst);
QFileInfoList list = dir.entryInfoList();
list.removeAll(QFileInfo("/usr/share/applications/screensavers"));
2021-04-26 15:06:47 +08:00
if(list.size() < 1) {
2020-12-30 15:31:36 +08:00
return;
}
XdgDesktopFile desktopfile;
2021-04-26 15:06:47 +08:00
int i = 0;
while(i < list.size()) {
2020-12-30 15:31:36 +08:00
QFileInfo fileInfo = list.at(i);
//如果是文件夹,递归
bool isDir = fileInfo.isDir();
if(isDir) {
getAllDesktopFilePath(fileInfo.filePath());
qDebug() << fileInfo.filePath();
++i;
2021-04-26 15:06:47 +08:00
} else {
QString filePathStr = fileInfo.filePath();
2021-09-14 10:22:18 +08:00
if(m_ExcludedDesktopfiles.contains(filePathStr)) {
++i;
continue;
}
2020-12-30 15:31:36 +08:00
//过滤后缀不是.desktop的文件
2021-04-26 15:06:47 +08:00
if(!filePathStr.endsWith(".desktop")) {
++i;
2020-12-30 15:31:36 +08:00
continue;
}
desktopfile.load(filePathStr);
if(desktopfile.value("NoDisplay").toString().contains("true") || desktopfile.value("NotShowIn").toString().contains("UKUI")) {
++i;
continue;
2020-12-30 15:31:36 +08:00
}
QString name = desktopfile.localizedValue("Name").toString();
if(name.isEmpty()) {
++i;
qDebug() << filePathStr << "name!!";
continue;
2020-12-30 15:31:36 +08:00
}
2021-08-26 19:59:31 +08:00
QString icon = desktopfile.iconName();
NameString appname;
QStringList appInfolist;
2021-08-26 19:59:31 +08:00
appname.app_name = name;
appInfolist << filePathStr << icon;
appInfolist.append(desktopfile.value("Name").toString());
appInfolist.append(desktopfile.value("Name[zh_CN]").toString());
m_installAppMap.insert(appname, appInfolist);
++i;
2020-12-30 15:31:36 +08:00
}
}
2020-12-30 15:31:36 +08:00
}
2020-12-30 21:41:00 +08:00
/**
* @brief AppMatch::appNameMatch
*
* @param appname
*
*/
void AppMatch::appNameMatch(QString keyWord, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult) {
2021-04-26 15:06:47 +08:00
QMapIterator<NameString, QStringList> iter(m_installAppMap);
while(iter.hasNext()) {
iter.next();
if(iter.key().app_name.contains(keyWord, Qt::CaseInsensitive)) {
SearchPluginIface::ResultInfo ri;
creatResultInfo(ri, iter, true);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.lock();
if (uniqueSymbol == AppSearchPlugin::uniqueSymbol) {
searchResult->enqueue(ri);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
continue;
} else {
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
return;
}
2021-06-28 19:38:27 +08:00
}
if(iter.value().at(3) == ""){
continue;
}
2021-06-28 19:38:27 +08:00
QStringList pinyinlist;
pinyinlist = FileUtils::findMultiToneWords(iter.value().at(3));
2021-06-28 19:38:27 +08:00
2021-09-08 15:31:47 +08:00
bool matched = false;
2021-06-28 19:38:27 +08:00
for(int i = 0; i < pinyinlist.size() / 2; i++) {
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
if(shouzimu.contains(keyWord, Qt::CaseInsensitive)) {
SearchPluginIface::ResultInfo ri;
creatResultInfo(ri, iter, true);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.lock();
if (uniqueSymbol == AppSearchPlugin::uniqueSymbol) {
searchResult->enqueue(ri);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
matched = true;
break;
} else {
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
return;
}
2021-06-28 19:38:27 +08:00
}
if(keyWord.size() < 2)
2021-06-30 09:03:00 +08:00
break;
2021-06-28 19:38:27 +08:00
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
if(pinyin.contains(keyWord, Qt::CaseInsensitive)) {
SearchPluginIface::ResultInfo ri;
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.lock();
creatResultInfo(ri, iter, true);
if (uniqueSymbol == AppSearchPlugin::uniqueSymbol) {
searchResult->enqueue(ri);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
matched = true;
break;
2021-09-08 15:31:47 +08:00
} else {
AppSearchPlugin::m_mutex.unlock();
return;
}
2021-06-28 19:38:27 +08:00
}
}
2021-09-08 15:31:47 +08:00
if(matched) {
continue;
}
2021-08-26 19:59:31 +08:00
QStringList tmpList;
tmpList << iter.value().at(2) << iter.value().at(3);
for(QString s : tmpList) {
if(s.contains(keyWord, Qt::CaseInsensitive)) {
SearchPluginIface::ResultInfo ri;
AppSearchPlugin::m_mutex.lock();
creatResultInfo(ri, iter, true);
if (uniqueSymbol == AppSearchPlugin::uniqueSymbol) {
searchResult->enqueue(ri);
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
break;
2021-08-26 19:59:31 +08:00
} else {
AppSearchPlugin::m_mutex.unlock();
2021-09-08 15:31:47 +08:00
return;
2021-08-26 19:59:31 +08:00
}
}
}
2021-06-28 19:38:27 +08:00
}
}
2021-02-26 11:21:41 +08:00
2021-04-26 15:06:47 +08:00
void AppMatch::softWareCenterSearch(QMap<NameString, QStringList> &softwarereturn) {
2021-05-30 11:28:04 +08:00
// if(m_interFace->timeout() != -1) {
// qWarning() << "softWareCente Dbus is timeout !";
// return;
// }
// slotDBusCallFinished(softwarereturn);
2021-04-26 15:06:47 +08:00
qDebug() << "softWareCenter match app is successful!";
2021-03-05 08:43:02 +08:00
}
void AppMatch::slotDBusCallFinished(QString keyWord, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult) {
QDBusReply<QList<QMap<QString, QString>>> reply = m_interFace->call("get_search_result", keyWord); //阻塞,直到远程方法调用完成。
2021-03-05 08:43:02 +08:00
// QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call;
2021-04-26 15:06:47 +08:00
if(reply.isValid()) {
parseSoftWareCenterReturn(reply.value(), uniqueSymbol, searchResult);
2021-04-26 15:06:47 +08:00
} else {
qWarning() << "SoftWareCenter dbus called failed!";
2021-04-26 15:06:47 +08:00
}
2021-03-05 08:43:02 +08:00
// call->deleteLater();
}
void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString, QString>> list, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult) {
qDebug() << "Begin parseSoftWareCenterReturn";
2021-03-05 08:43:02 +08:00
QLocale locale;
2021-04-26 15:06:47 +08:00
for(int i = 0; i < list.size(); i++) {
SearchPluginIface::ResultInfo ri;
2021-04-26 15:06:47 +08:00
if(locale.language() == QLocale::Chinese) {
ri.name = list.at(i).value("displayname_cn");
} else {
ri.name = list.at(i).value("appname");
2021-03-05 08:43:02 +08:00
}
ri.icon = !(QIcon(list.at(i).value("icon")).isNull()) ? QIcon(list.at(i).value("icon")) : QIcon(":/res/icons/desktop.png");
SearchPluginIface::DescriptionInfo di;
di.key = QString(tr("Application Description:"));
di.value = list.at(i).value("discription");
ri.description.append(di);
ri.actionKey = list.at(i).value("appname");
ri.type = 1; //1 means not installed apps.
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.lock();
if (uniqueSymbol == AppSearchPlugin::uniqueSymbol) {
searchResult->enqueue(ri);
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
} else {
2021-08-26 19:59:31 +08:00
AppSearchPlugin::m_mutex.unlock();
break;
2021-03-05 08:43:02 +08:00
}
2020-12-30 15:31:36 +08:00
}
}
2021-02-26 11:21:41 +08:00
void AppMatch::creatResultInfo(SearchPluginIface::ResultInfo &ri, QMapIterator<NameString, QStringList> &iter, bool isInstalled)
{
2021-09-08 15:31:47 +08:00
// ri.icon = QIcon::fromTheme(iter.value().at(1), QIcon(":/res/icons/desktop.png"));
ri.icon = XdgIcon::fromTheme(iter.value().at(1), QIcon(":/res/icons/desktop.png"));
ri.name = iter.key().app_name;
ri.actionKey = iter.value().at(0);
ri.type = 0; //0 means installed apps.
2021-02-26 11:21:41 +08:00
}
2021-04-26 15:06:47 +08:00
void AppMatch::run() {
2021-09-14 10:22:18 +08:00
qDebug() << "App map init..";
2021-03-05 08:43:02 +08:00
this->getAllDesktopFilePath("/usr/share/applications/");
2021-08-26 19:59:31 +08:00
this->getAllDesktopFilePath(ANDROID_APP_DESKTOP_PATH);
connect(m_watchAppDir, &QFileSystemWatcher::directoryChanged, this, [ = ](const QString & path) {
2021-09-14 10:22:18 +08:00
m_installAppMap.clear();
2021-04-26 15:06:47 +08:00
this->getAllDesktopFilePath("/usr/share/applications/");
2021-08-26 19:59:31 +08:00
this->getAllDesktopFilePath(ANDROID_APP_DESKTOP_PATH);
2021-09-14 10:22:18 +08:00
qDebug() << "App map update " << m_installAppMap.size();
});
2021-09-14 10:22:18 +08:00
qDebug() << "App map init finished.." << m_installAppMap.size();
2021-03-05 08:43:02 +08:00
}