From 6099efc8f1b894522e2a8df13ffd7aae54687048 Mon Sep 17 00:00:00 2001 From: zhangjiaping Date: Sat, 6 Mar 2021 10:05:42 +0800 Subject: [PATCH] feat(frontend): Sort installed applications. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: 已安装应用搜索结果排序 Log: 已安装应用搜索结果排序 --- libsearch/appsearch/app-match.cpp | 172 +++++++---------------------- libsearch/appsearch/app-match.h | 53 +++++---- src/control/search-detail-view.cpp | 11 +- src/model/search-item.cpp | 4 +- src/search-app-thread.cpp | 45 +++++--- src/search-app-thread.h | 3 +- 6 files changed, 106 insertions(+), 182 deletions(-) diff --git a/libsearch/appsearch/app-match.cpp b/libsearch/appsearch/app-match.cpp index 1af112e..577ae6b 100644 --- a/libsearch/appsearch/app-match.cpp +++ b/libsearch/appsearch/app-match.cpp @@ -35,12 +35,6 @@ AppMatch::AppMatch(QObject *parent) : QThread(parent) { m_watchAppDir=new QFileSystemWatcher(this); 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>(); qDBusRegisterMetaType>>(); m_interFace=new QDBusInterface ("com.kylin.softwarecenter.getsearchresults", "/com/kylin/softwarecenter/getsearchresults", @@ -64,7 +58,7 @@ AppMatch::~AppMatch(){ m_watchAppDir=NULL; } -void AppMatch::startMatchApp(QString input,QMap &installed,QMap &softwarereturn){ +void AppMatch::startMatchApp(QString input,QMap &installed,QMap &softwarereturn){ input.replace(" ",""); m_sourceText=input; getAppName(installed); @@ -72,29 +66,6 @@ void AppMatch::startMatchApp(QString input,QMap &installed, qDebug()<<"match app is successful!"; } -/** - * @brief AppMatch::startMatchApp 查询应用,含所有已安装与未安装 - * @param input 关键词 - * @param i - * @return QMap> QMap<应用名,{.desktop(未安装为空),图标(安装的是名字,未安装是路径)}> - */ -QMap> 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文件 * @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); icon=g_key_file_get_locale_string(keyfile,"Desktop Entry","Icon", nullptr, nullptr); if(!m_filePathList.contains(filePathStr)){ - m_installAppMap.insert(QString::fromLocal8Bit(name),applist< &installed) { - QMap>::const_iterator i; + QMap::const_iterator i; for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){ - appNameMatch(i.key()); - } -} - -void AppMatch::getAppName(QMap &installed) -{ - QMap>::const_iterator i; - for(i=m_installAppMap.constBegin();i!=m_installAppMap.constEnd();++i){ - appNameMatch(i.key(),installed); + appNameMatch(i.key().app_name,installed); } qDebug()<<"installed app match is successful!"; } @@ -289,59 +250,40 @@ void AppMatch::getAppName(QMap &installed) * 进行匹配 * @param appname * 应用名字 - * @param desktoppath - * desktop路径 */ -void AppMatch::appNameMatch(QString appname){ +void AppMatch::appNameMatch(QString appname,QMap &installed){ + NameString name{appname}; + QStringList list; + QMapIterator 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)){ - m_matchInstallAppMap.insert(appname,m_installAppMap.value(appname)); +// installed.insert(name,m_installAppMap.value(name)); + installed.insert(name,list); return; } QString shouzimu=FileUtils::findMultiToneWords(appname).at(1);// 中文转首字母 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; } if(m_sourceText.size()<2) return; QString pinyin=FileUtils::findMultiToneWords(appname).at(0);// 中文转拼音 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 &installed){ - 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 :"<timeout(); - slotDBusCallFinished(); -} - -void AppMatch::softWareCenterSearch(QMap &softwarereturn){ +void AppMatch::softWareCenterSearch(QMap &softwarereturn){ if(m_interFace->timeout()!=-1){ qWarning()<<"softWareCente Dbus is timeout !"; return; @@ -350,21 +292,7 @@ void AppMatch::softWareCenterSearch(QMap &softwarereturn){ qDebug()<<"softWareCenter match app is successful!"; } -void AppMatch::slotDBusCallFinished() -{ - QDBusReply>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。 -// QDBusPendingReply>> reply = *call; - if (reply.isValid()) - { - parseSoftWareCenterReturn(reply.value()); - } - else - { - qWarning() << "value method called failed!"; - } -// call->deleteLater(); -} -void AppMatch::slotDBusCallFinished(QMap &softwarereturn){ +void AppMatch::slotDBusCallFinished(QMap &softwarereturn){ QDBusReply>> reply = m_interFace->call("get_search_result",m_sourceText); //阻塞,直到远程方法调用完成。 // QDBusPendingReply>> reply = *call; if (reply.isValid()) @@ -378,47 +306,28 @@ void AppMatch::slotDBusCallFinished(QMap &softwarereturn){ // call->deleteLater(); } -void AppMatch::parseSoftWareCenterReturn(QList> list,QMap &softwarereturn){ +void AppMatch::parseSoftWareCenterReturn(QList> list,QMap &softwarereturn){ // qWarning()<> list){ -// qWarning()<close(); } -void AppMatch::returnAppMap(){ - QMap>::const_iterator i; - for(i=m_matchInstallAppMap.constBegin();i!=m_matchInstallAppMap.constEnd();++i){ - m_midResult.insert(i.key(),i.value()); - } - QMap>::const_iterator j; - for(j=m_softWareCenterMap.constBegin();j!=m_softWareCenterMap.constEnd();++j){ - m_midResult.insert(j.key(),j.value()); - } -} - void AppMatch::run(){ qDebug()<<"AppMatch is run"; this->getDesktopFilePath(); this->getAllDesktopFilePath("/usr/share/applications/"); + connect(m_watchAppDir,&QFileSystemWatcher::directoryChanged,[this](){ + this->getDesktopFilePath(); + this->getAllDesktopFilePath("/usr/share/applications/"); + }); } diff --git a/libsearch/appsearch/app-match.h b/libsearch/appsearch/app-match.h index 686f2a1..a2aa801 100644 --- a/libsearch/appsearch/app-match.h +++ b/libsearch/appsearch/app-match.h @@ -30,51 +30,60 @@ #include #include +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 { Q_OBJECT public: static AppMatch *getAppMatch(); - explicit AppMatch(QObject *parent = nullptr); - ~AppMatch(); - void startMatchApp(QString input,QMap &installed,QMap &softwarereturn); - QMap> startMatchApp(QString input); + void startMatchApp(QString input,QMap &installed,QMap &softwarereturn); private: + explicit AppMatch(QObject *parent = nullptr); + ~AppMatch(); void getAllDesktopFilePath(QString path); void getDesktopFilePath(); - void getAppName(); - void getAppName(QMap &installed); + void getAppName(QMap &installed); // void appNameMatch(QString appname,QString desktoppath,QString appicon); - void appNameMatch(QString appname); - void appNameMatch(QString appname,QMap &installed); + void appNameMatch(QString appname,QMap &installed); - void softWareCenterSearch(); - void softWareCenterSearch(QMap &softwarereturn); + void softWareCenterSearch(QMap &softwarereturn); - void parseSoftWareCenterReturn(QList> list); - void parseSoftWareCenterReturn(QList> list,QMap &softwarereturn); + void parseSoftWareCenterReturn(QList> list,QMap &softwarereturn); void getInstalledAppsVersion(QString appname); - void returnAppMap(); private: QString m_sourceText; QStringList m_filePathList; - QStringList m_returnResult; QDBusInterface *m_interFace=nullptr; QFileSystemWatcher *m_watchAppDir=nullptr; - QMap> m_softWareCenterMap; - QMap> m_installAppMap; - QMap> m_matchInstallAppMap; - QMap> m_returnResult1; - QMap> m_midResult; -// QProcess *m_versionCommand; + QMap m_installAppMap; private Q_SLOTS: - void slotDBusCallFinished(); - void slotDBusCallFinished(QMap &softwarereturn); + void slotDBusCallFinished(QMap &softwarereturn); //Q_SIGNALS: diff --git a/src/control/search-detail-view.cpp b/src/control/search-detail-view.cpp index 3738506..30c8eb9 100644 --- a/src/control/search-detail-view.cpp +++ b/src/control/search-detail-view.cpp @@ -177,7 +177,7 @@ void SearchDetailView::setAppWidget(const QString &appname, const QString &path, { m_type = SearchListView::ResType::App; m_path = path; - m_name = appname; + m_name = appname.contains("/") ? appname.left(appname.indexOf("/")) : appname; m_isEmpty = false; clearLayout(); 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)))); 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); - if (QString::compare(showname, appname)) { - m_nameLabel->setToolTip(appname); + if (QString::compare(showname, m_name)) { + m_nameLabel->setToolTip(m_name); } m_typeLabel->setText(tr("Application")); } @@ -586,7 +586,8 @@ bool SearchDetailView::installAppAction(const QString & name) { //打开软件商店下载此软件 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; } diff --git a/src/model/search-item.cpp b/src/model/search-item.cpp index dedafe5..30064c3 100644 --- a/src/model/search-item.cpp +++ b/src/model/search-item.cpp @@ -83,7 +83,9 @@ QString SearchItem::getName(int index) { case Files : //文件,返回文件名 return FileUtils::getFileName(m_pathlist.at(index)); 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 : //最佳匹配,含全部类型,需要自己判断,返回不同类型的名称 return getBestName(index); diff --git a/src/search-app-thread.cpp b/src/search-app-thread.cpp index bdd4399..36b0c54 100644 --- a/src/search-app-thread.cpp +++ b/src/search-app-thread.cpp @@ -2,15 +2,10 @@ SearchAppThread::SearchAppThread(QObject * parent) : QThread(parent) { - m_appMatch = new AppMatch(this); } SearchAppThread::~SearchAppThread() { - if (m_appMatch) { - delete m_appMatch; - m_appMatch = NULL; - } } /** @@ -29,26 +24,40 @@ void SearchAppThread::stop() m_stop = true; this->quit(); this->wait(); + m_installed_apps.clear(); + m_uninstalled_apps.clear(); } void SearchAppThread::run() { //nameList:应用名,pathList:已安装的是.desktop路径,未安装为空,iconList:已安装的是图标名,未安装的是图标路径 QStringList nameList, pathList, iconList; - QVector applist; - QMap> appList; - appList = m_appMatch->startMatchApp(m_keyword); - QMapIterator> iter(appList); - while(iter.hasNext()) + QVector appVector; + AppMatch::getAppMatch()->startMatchApp(m_keyword, m_installed_apps, m_uninstalled_apps); + QMapIterator installed_iter(m_installed_apps); + while(installed_iter.hasNext()) { - iter.next(); - nameList << iter.key(); - pathList << iter.value().at(0); - iconList << iter.value().at(1); + installed_iter.next(); + nameList << installed_iter.key().app_name; + pathList << installed_iter.value().at(0); + iconList << installed_iter.value().at(1); } - applist.append(nameList); - applist.append(pathList); - applist.append(iconList); + QMapIterator uninstalled_iter(m_uninstalled_apps); + while(uninstalled_iter.hasNext()) + { + 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) - Q_EMIT this->searchResultApp(applist); + Q_EMIT this->searchResultApp(appVector); } diff --git a/src/search-app-thread.h b/src/search-app-thread.h index 4ef40de..5bfc182 100644 --- a/src/search-app-thread.h +++ b/src/search-app-thread.h @@ -15,9 +15,10 @@ public: protected: void run() override; private: - AppMatch * m_appMatch = nullptr; QString m_keyword; bool m_stop = false; + QMap m_installed_apps; + QMap m_uninstalled_apps; Q_SIGNALS: void searchResultApp(const QVector&); };