feat(frontend): Sort installed applications.

Description: 已安装应用搜索结果排序

Log: 已安装应用搜索结果排序
This commit is contained in:
zhangjiaping 2021-03-06 10:05:42 +08:00
parent c089012854
commit 6099efc8f1
6 changed files with 106 additions and 182 deletions

View File

@ -35,12 +35,6 @@ AppMatch::AppMatch(QObject *parent) : QThread(parent)
{ {
m_watchAppDir=new QFileSystemWatcher(this); m_watchAppDir=new QFileSystemWatcher(this);
m_watchAppDir->addPath("/usr/share/applications/"); m_watchAppDir->addPath("/usr/share/applications/");
//This part is not right!!!!!!!!!----iaom
connect(m_watchAppDir,&QFileSystemWatcher::directoryChanged,[this](){
this->getDesktopFilePath();
this->getAllDesktopFilePath("/usr/share/applications/");
});
qDBusRegisterMetaType<QMap<QString,QString>>(); qDBusRegisterMetaType<QMap<QString,QString>>();
qDBusRegisterMetaType<QList<QMap<QString,QString>>>(); qDBusRegisterMetaType<QList<QMap<QString,QString>>>();
m_interFace=new QDBusInterface ("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults", m_interFace=new QDBusInterface ("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults",
@ -64,7 +58,7 @@ AppMatch::~AppMatch(){
m_watchAppDir=NULL; m_watchAppDir=NULL;
} }
void AppMatch::startMatchApp(QString input,QMap<QString,QStringList> &installed,QMap<QString,QStringList> &softwarereturn){ void AppMatch::startMatchApp(QString input,QMap<NameString,QStringList> &installed,QMap<NameString,QStringList> &softwarereturn){
input.replace(" ",""); input.replace(" ","");
m_sourceText=input; m_sourceText=input;
getAppName(installed); getAppName(installed);
@ -72,29 +66,6 @@ void AppMatch::startMatchApp(QString input,QMap<QString,QStringList> &installed,
qDebug()<<"match app is successful!"; qDebug()<<"match app is successful!";
} }
/**
* @brief AppMatch::startMatchApp
* @param input
* @param i
* @return QMap<QString,QList<QString>> QMap<{.desktop(),()}>
*/
QMap<QString,QList<QString>> AppMatch::startMatchApp(QString input){
input.replace(" ","");
m_sourceText=input;
m_softWareCenterMap.clear();
m_matchInstallAppMap.clear();
m_returnResult1.clear();
if(input.isEmpty()){
return m_returnResult1;
}
softWareCenterSearch();
getAppName();
returnAppMap();
m_returnResult1=m_midResult;
m_midResult.clear();
return m_returnResult1;
}
/** /**
* @brief AppMatch::getAllDesktopFilePath desktop文件 * @brief AppMatch::getAllDesktopFilePath desktop文件
* @param path desktop文件夹 * @param path desktop文件夹
@ -190,7 +161,9 @@ void AppMatch::getAllDesktopFilePath(QString path){
name=g_key_file_get_locale_string(keyfile,"Desktop Entry","Name", nullptr, nullptr); name=g_key_file_get_locale_string(keyfile,"Desktop Entry","Name", nullptr, nullptr);
icon=g_key_file_get_locale_string(keyfile,"Desktop Entry","Icon", nullptr, nullptr); icon=g_key_file_get_locale_string(keyfile,"Desktop Entry","Icon", nullptr, nullptr);
if(!m_filePathList.contains(filePathStr)){ if(!m_filePathList.contains(filePathStr)){
m_installAppMap.insert(QString::fromLocal8Bit(name),applist<<filePathStr<<QString::fromLocal8Bit(icon)<<""); NameString appname;
appname.app_name = QString::fromLocal8Bit(name);
m_installAppMap.insert(appname,applist<<filePathStr<<QString::fromLocal8Bit(icon)<<"");
applist.clear(); applist.clear();
} }
// m_filePathList.append(filePathStr); // m_filePathList.append(filePathStr);
@ -263,23 +236,11 @@ void AppMatch::getDesktopFilePath()
// } // }
} }
/** void AppMatch::getAppName(QMap<NameString,QStringList> &installed)
* @brief AppMatch::getAppName
*
*/
void AppMatch::getAppName()
{ {
QMap<QString, QList<QString>>::const_iterator i; QMap<NameString, QStringList>::const_iterator i;
for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){ for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){
appNameMatch(i.key()); appNameMatch(i.key().app_name,installed);
}
}
void AppMatch::getAppName(QMap<QString,QStringList> &installed)
{
QMap<QString, QList<QString>>::const_iterator i;
for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){
appNameMatch(i.key(),installed);
} }
qDebug()<<"installed app match is successful!"; qDebug()<<"installed app match is successful!";
} }
@ -289,59 +250,40 @@ void AppMatch::getAppName(QMap<QString,QStringList> &installed)
* *
* @param appname * @param appname
* *
* @param desktoppath
* desktop路径
*/ */
void AppMatch::appNameMatch(QString appname){ void AppMatch::appNameMatch(QString appname,QMap<NameString,QStringList> &installed){
NameString name{appname};
QStringList list;
QMapIterator<NameString,QStringList> iter(m_installAppMap);
while(iter.hasNext())
{
iter.next();
if (iter.key().app_name == appname) {
list = iter.value();
break;
}
}
if(appname.contains(m_sourceText,Qt::CaseInsensitive)){ if(appname.contains(m_sourceText,Qt::CaseInsensitive)){
m_matchInstallAppMap.insert(appname,m_installAppMap.value(appname)); // installed.insert(name,m_installAppMap.value(name));
installed.insert(name,list);
return; return;
} }
QString shouzimu=FileUtils::findMultiToneWords(appname).at(1);// 中文转首字母 QString shouzimu=FileUtils::findMultiToneWords(appname).at(1);// 中文转首字母
if(shouzimu.contains(m_sourceText,Qt::CaseInsensitive)){ if(shouzimu.contains(m_sourceText,Qt::CaseInsensitive)){
m_matchInstallAppMap.insert(appname,m_installAppMap.value(appname)); // installed.insert(name,m_installAppMap.value(name));
installed.insert(name,list);
return; return;
} }
if(m_sourceText.size()<2) if(m_sourceText.size()<2)
return; return;
QString pinyin=FileUtils::findMultiToneWords(appname).at(0);// 中文转拼音 QString pinyin=FileUtils::findMultiToneWords(appname).at(0);// 中文转拼音
if(pinyin.contains(m_sourceText,Qt::CaseInsensitive)){ if(pinyin.contains(m_sourceText,Qt::CaseInsensitive)){
m_matchInstallAppMap.insert(appname,m_installAppMap.value(appname)); // installed.insert(name,m_installAppMap.value(name));
installed.insert(name,list);
} }
} }
void AppMatch::appNameMatch(QString appname,QMap<QString,QStringList> &installed){ void AppMatch::softWareCenterSearch(QMap<NameString,QStringList> &softwarereturn){
if(appname.contains(m_sourceText,Qt::CaseInsensitive)){
installed.insert(appname,m_installAppMap.value(appname));
return;
}
QString shouzimu=FileUtils::findMultiToneWords(appname).at(1);// 中文转首字母
if(shouzimu.contains(m_sourceText,Qt::CaseInsensitive)){
installed.insert(appname,m_installAppMap.value(appname));
return;
}
if(m_sourceText.size()<2)
return;
QString pinyin=FileUtils::findMultiToneWords(appname).at(0);// 中文转拼音
if(pinyin.contains(m_sourceText,Qt::CaseInsensitive)){
installed.insert(appname,m_installAppMap.value(appname));
}
}
void AppMatch::softWareCenterSearch(){
// 调用D-Bus接口的方法
// QDBusPendingCall pcall = m_interFace->asyncCall("get_search_result", m_sourceText);
// 设置等待异步消息的信号槽
// QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(pcall, nullptr);
// QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, &AppMatch::slotDBusCallFinished);
if(m_interFace->timeout()!=-1)
return;
// qWarning()<<"this :"<<m_interFace->timeout();
slotDBusCallFinished();
}
void AppMatch::softWareCenterSearch(QMap<QString,QStringList> &softwarereturn){
if(m_interFace->timeout()!=-1){ if(m_interFace->timeout()!=-1){
qWarning()<<"softWareCente Dbus is timeout !"; qWarning()<<"softWareCente Dbus is timeout !";
return; return;
@ -350,21 +292,7 @@ void AppMatch::softWareCenterSearch(QMap<QString,QStringList> &softwarereturn){
qDebug()<<"softWareCenter match app is successful!"; qDebug()<<"softWareCenter match app is successful!";
} }
void AppMatch::slotDBusCallFinished() void AppMatch::slotDBusCallFinished(QMap<NameString,QStringList> &softwarereturn){
{
QDBusReply<QList<QMap<QString,QString>>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。
// QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call;
if (reply.isValid())
{
parseSoftWareCenterReturn(reply.value());
}
else
{
qWarning() << "value method called failed!";
}
// call->deleteLater();
}
void AppMatch::slotDBusCallFinished(QMap<QString,QStringList> &softwarereturn){
QDBusReply<QList<QMap<QString,QString>>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。 QDBusReply<QList<QMap<QString,QString>>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。
// QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call; // QDBusPendingReply<QList<QMap<QString,QString>>> reply = *call;
if (reply.isValid()) if (reply.isValid())
@ -378,47 +306,28 @@ void AppMatch::slotDBusCallFinished(QMap<QString,QStringList> &softwarereturn){
// call->deleteLater(); // call->deleteLater();
} }
void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<QString,QStringList> &softwarereturn){ void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<NameString,QStringList> &softwarereturn){
// qWarning()<<list; // qWarning()<<list;
QString appname; QString appname;
NameString name;
QString appicon; QString appicon;
QString appdiscription; QString appdiscription;
QStringList applist; QStringList applist;
QLocale locale; QLocale locale;
QString pkgname;
for(int i=0;i<list.size();i++){ for(int i=0;i<list.size();i++){
// qWarning()<<list.at(i).keys(); // qWarning()<<list.at(i).keys();
if(locale.language()==QLocale::Chinese){ if(locale.language()==QLocale::Chinese){
appname=list.at(i).value("displayname_cn"); appname=list.at(i).value("displayname_cn");
pkgname = list.at(i).value("appname");
} }
if(locale.language()==QLocale::English){ if(locale.language()==QLocale::English){
appname=list.at(i).value("appname"); appname=list.at(i).value("appname");
} }
appdiscription=list.at(i).value("discription"); appdiscription=list.at(i).value("discription");
appicon=list.at(i).value("icon"); appicon=list.at(i).value("icon");
softwarereturn.insert(appname,applist<<""<<appicon<<appdiscription); name.app_name = appname;
applist.clear(); pkgname.isEmpty() ? softwarereturn.insert(name,applist<<""<<appicon<<appdiscription) : softwarereturn.insert(name,applist<<""<<appicon<<pkgname);
}
}
void AppMatch::parseSoftWareCenterReturn(QList<QMap<QString,QString>> list){
// qWarning()<<list;
QString appname;
QString appicon;
QString appdiscription;
QStringList applist;
QLocale locale;
for(int i=0;i<list.size();i++){
// qWarning()<<list.at(i).keys();
if(locale.language()==QLocale::Chinese){
appname=list.at(i).value("displayname_cn");
}
if(locale.language()==QLocale::English){
appname=list.at(i).value("appname");
}
appdiscription=list.at(i).value("discription");
// qWarning()<<"discription"<<appdiscription;
appicon=list.at(i).value("icon");
m_softWareCenterMap.insert(appname,applist<<""<<appicon<<appdiscription);
applist.clear(); applist.clear();
} }
} }
@ -443,19 +352,12 @@ void AppMatch::getInstalledAppsVersion(QString appname){
// m_versionCommand->close(); // m_versionCommand->close();
} }
void AppMatch::returnAppMap(){
QMap<QString, QList<QString>>::const_iterator i;
for(i=m_matchInstallAppMap.constBegin();i!=m_matchInstallAppMap.constEnd();++i){
m_midResult.insert(i.key(),i.value());
}
QMap<QString, QList<QString>>::const_iterator j;
for(j=m_softWareCenterMap.constBegin();j!=m_softWareCenterMap.constEnd();++j){
m_midResult.insert(j.key(),j.value());
}
}
void AppMatch::run(){ void AppMatch::run(){
qDebug()<<"AppMatch is run"; qDebug()<<"AppMatch is run";
this->getDesktopFilePath(); this->getDesktopFilePath();
this->getAllDesktopFilePath("/usr/share/applications/"); this->getAllDesktopFilePath("/usr/share/applications/");
connect(m_watchAppDir,&QFileSystemWatcher::directoryChanged,[this](){
this->getDesktopFilePath();
this->getAllDesktopFilePath("/usr/share/applications/");
});
} }

View File

@ -30,51 +30,60 @@
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QThread> #include <QThread>
class NameString
{
public:
explicit NameString(const QString &str_) : app_name(str_) {}
NameString() = default;
QString app_name;
bool operator<(const NameString& name) const {
return this->app_name.length() <= name.app_name.length();
}
};
//struct NameString
//{
// QString app_name;
// //重载操作符
// inline bool operator < (const NameString& name) const
// {
//// return name.app_name.length() >= app_name.length();
// return true;
// }
//};
class AppMatch : public QThread class AppMatch : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
static AppMatch *getAppMatch(); static AppMatch *getAppMatch();
explicit AppMatch(QObject *parent = nullptr); void startMatchApp(QString input,QMap<NameString,QStringList> &installed,QMap<NameString,QStringList> &softwarereturn);
~AppMatch();
void startMatchApp(QString input,QMap<QString,QStringList> &installed,QMap<QString,QStringList> &softwarereturn);
QMap<QString,QList<QString>> startMatchApp(QString input);
private: private:
explicit AppMatch(QObject *parent = nullptr);
~AppMatch();
void getAllDesktopFilePath(QString path); void getAllDesktopFilePath(QString path);
void getDesktopFilePath(); void getDesktopFilePath();
void getAppName(); void getAppName(QMap<NameString,QStringList> &installed);
void getAppName(QMap<QString,QStringList> &installed);
// void appNameMatch(QString appname,QString desktoppath,QString appicon); // void appNameMatch(QString appname,QString desktoppath,QString appicon);
void appNameMatch(QString appname); void appNameMatch(QString appname,QMap<NameString,QStringList> &installed);
void appNameMatch(QString appname,QMap<QString,QStringList> &installed);
void softWareCenterSearch(); void softWareCenterSearch(QMap<NameString,QStringList> &softwarereturn);
void softWareCenterSearch(QMap<QString,QStringList> &softwarereturn);
void parseSoftWareCenterReturn(QList<QMap<QString,QString>> list); void parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<NameString,QStringList> &softwarereturn);
void parseSoftWareCenterReturn(QList<QMap<QString,QString>> list,QMap<QString,QStringList> &softwarereturn);
void getInstalledAppsVersion(QString appname); void getInstalledAppsVersion(QString appname);
void returnAppMap();
private: private:
QString m_sourceText; QString m_sourceText;
QStringList m_filePathList; QStringList m_filePathList;
QStringList m_returnResult;
QDBusInterface *m_interFace=nullptr; QDBusInterface *m_interFace=nullptr;
QFileSystemWatcher *m_watchAppDir=nullptr; QFileSystemWatcher *m_watchAppDir=nullptr;
QMap<QString,QList<QString>> m_softWareCenterMap; QMap<NameString,QStringList> m_installAppMap;
QMap<QString,QList<QString>> m_installAppMap;
QMap<QString,QList<QString>> m_matchInstallAppMap;
QMap<QString,QList<QString>> m_returnResult1;
QMap<QString,QList<QString>> m_midResult;
// QProcess *m_versionCommand;
private Q_SLOTS: private Q_SLOTS:
void slotDBusCallFinished(); void slotDBusCallFinished(QMap<NameString,QStringList> &softwarereturn);
void slotDBusCallFinished(QMap<QString,QStringList> &softwarereturn);
//Q_SIGNALS: //Q_SIGNALS:

View File

@ -177,7 +177,7 @@ void SearchDetailView::setAppWidget(const QString &appname, const QString &path,
{ {
m_type = SearchListView::ResType::App; m_type = SearchListView::ResType::App;
m_path = path; m_path = path;
m_name = appname; m_name = appname.contains("/") ? appname.left(appname.indexOf("/")) : appname;
m_isEmpty = false; m_isEmpty = false;
clearLayout(); clearLayout();
m_iconLabel->show(); m_iconLabel->show();
@ -202,10 +202,10 @@ void SearchDetailView::setAppWidget(const QString &appname, const QString &path,
m_iconLabel->setPixmap(icon.pixmap(icon.actualSize(QSize(96, 96)))); m_iconLabel->setPixmap(icon.pixmap(icon.actualSize(QSize(96, 96))));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics(); QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(appname, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号 QString showname = fontMetrics.elidedText(m_name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(showname); m_nameLabel->setText(showname);
if (QString::compare(showname, appname)) { if (QString::compare(showname, m_name)) {
m_nameLabel->setToolTip(appname); m_nameLabel->setToolTip(m_name);
} }
m_typeLabel->setText(tr("Application")); m_typeLabel->setText(tr("Application"));
} }
@ -586,7 +586,8 @@ bool SearchDetailView::installAppAction(const QString & name)
{ {
//打开软件商店下载此软件 //打开软件商店下载此软件
QProcess process; QProcess process;
bool res = process.startDetached(QString("kylin-software-center -find %1").arg(name)); QString app_name = name.contains("/") ? name.mid(name.indexOf("/") + 1) : name;
bool res = process.startDetached(QString("kylin-software-center -find %1").arg(app_name));
return res; return res;
} }

View File

@ -83,7 +83,9 @@ QString SearchItem::getName(int index) {
case Files : //文件,返回文件名 case Files : //文件,返回文件名
return FileUtils::getFileName(m_pathlist.at(index)); return FileUtils::getFileName(m_pathlist.at(index));
case Apps : {//应用,返回应用名 case Apps : {//应用,返回应用名
return m_pathlist.at(index); QString whole_name = m_pathlist.at(index);
QString app_name = whole_name.contains("/") ? whole_name.left(whole_name.indexOf("/")) : whole_name;
return app_name;
} }
case Best : //最佳匹配,含全部类型,需要自己判断,返回不同类型的名称 case Best : //最佳匹配,含全部类型,需要自己判断,返回不同类型的名称
return getBestName(index); return getBestName(index);

View File

@ -2,15 +2,10 @@
SearchAppThread::SearchAppThread(QObject * parent) : QThread(parent) SearchAppThread::SearchAppThread(QObject * parent) : QThread(parent)
{ {
m_appMatch = new AppMatch(this);
} }
SearchAppThread::~SearchAppThread() SearchAppThread::~SearchAppThread()
{ {
if (m_appMatch) {
delete m_appMatch;
m_appMatch = NULL;
}
} }
/** /**
@ -29,26 +24,40 @@ void SearchAppThread::stop()
m_stop = true; m_stop = true;
this->quit(); this->quit();
this->wait(); this->wait();
m_installed_apps.clear();
m_uninstalled_apps.clear();
} }
void SearchAppThread::run() void SearchAppThread::run()
{ {
//nameList:应用名pathList:已安装的是.desktop路径未安装为空iconList:已安装的是图标名,未安装的是图标路径 //nameList:应用名pathList:已安装的是.desktop路径未安装为空iconList:已安装的是图标名,未安装的是图标路径
QStringList nameList, pathList, iconList; QStringList nameList, pathList, iconList;
QVector<QStringList> applist; QVector<QStringList> appVector;
QMap<QString, QList<QString>> appList; AppMatch::getAppMatch()->startMatchApp(m_keyword, m_installed_apps, m_uninstalled_apps);
appList = m_appMatch->startMatchApp(m_keyword); QMapIterator<NameString,QStringList> installed_iter(m_installed_apps);
QMapIterator<QString,QList<QString>> iter(appList); while(installed_iter.hasNext())
while(iter.hasNext())
{ {
iter.next(); installed_iter.next();
nameList << iter.key(); nameList << installed_iter.key().app_name;
pathList << iter.value().at(0); pathList << installed_iter.value().at(0);
iconList << iter.value().at(1); iconList << installed_iter.value().at(1);
} }
applist.append(nameList); QMapIterator<NameString,QStringList> uninstalled_iter(m_uninstalled_apps);
applist.append(pathList); while(uninstalled_iter.hasNext())
applist.append(iconList); {
uninstalled_iter.next();
QString name;
//当返回列表的value中含包名时将名称按“应用名/包名”的格式存储
if (uninstalled_iter.value().length() > 2) {
name = uninstalled_iter.key().app_name + "/" + uninstalled_iter.value().at(2);
} else name = uninstalled_iter.key().app_name;
nameList << name;
pathList << uninstalled_iter.value().at(0);
iconList << uninstalled_iter.value().at(1);
}
appVector.append(nameList);
appVector.append(pathList);
appVector.append(iconList);
if (!m_stop) if (!m_stop)
Q_EMIT this->searchResultApp(applist); Q_EMIT this->searchResultApp(appVector);
} }

View File

@ -15,9 +15,10 @@ public:
protected: protected:
void run() override; void run() override;
private: private:
AppMatch * m_appMatch = nullptr;
QString m_keyword; QString m_keyword;
bool m_stop = false; bool m_stop = false;
QMap<NameString,QStringList> m_installed_apps;
QMap<NameString,QStringList> m_uninstalled_apps;
Q_SIGNALS: Q_SIGNALS:
void searchResultApp(const QVector<QStringList>&); void searchResultApp(const QVector<QStringList>&);
}; };