Refactoring the code of the setting search plugin.

This commit is contained in:
baijunjie 2021-11-30 17:21:06 +08:00 committed by iaom
parent 2a326372e8
commit 9692ba6ca6
4 changed files with 221 additions and 317 deletions

View File

@ -131,6 +131,10 @@ QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
}
}
QIcon FileUtils::getSettingIcon() {
return QIcon::fromTheme("ukui-control-center"); //返回控制面板应用图标
}
/**
* @brief FileUtils::getFileName
* @param uri "file:///home/xxx/xxx/xxxx.txt"

View File

@ -68,6 +68,7 @@ public:
static QIcon getFileIcon(const QString &, bool checkValid = true);
static QIcon getAppIcon(const QString &);
static QIcon getSettingIcon(const QString &, const bool&);
static QIcon getSettingIcon();
static QString getFileName(const QString &);
static QString getAppName(const QString &);

View File

@ -4,13 +4,19 @@
#include <QWidget>
#include "settings-search-plugin.h"
#include "file-utils.h"
using namespace Zeeker;
static SettingsMatch * settingMatchClass = nullptr;
size_t SettingsSearchPlugin::m_uniqueSymbolForSettings = 0;
QMutex SettingsSearchPlugin::m_mutex;
SettingsSearchPlugin::SettingsSearchPlugin(QObject *parent) : QObject(parent)
{
SearchPluginIface::Actioninfo open { 0, tr("Open")};
m_actionInfo << open;
xmlElement();
SettingsMatch::getInstance()->start();
m_pool.setMaxThreadCount(1);
m_pool.setExpiryTimeout(1000);
initDetailPage();
}
@ -31,234 +37,11 @@ QString SettingsSearchPlugin::getPluginName()
void Zeeker::SettingsSearchPlugin::KeywordSearch(QString keyword, DataQueue<ResultInfo> *searchResult)
{
if (keyword == "/")
return;
QStringList pinyinlist;
QStringList resultName;
ResultInfo resultInfo;
resultInfo.type = 0;
QLocale ql;
/*
if (ql.language() == QLocale::Chinese) {
for (auto i = m_chineseSearchList.constBegin(); i != m_chineseSearchList.constEnd(); ++i) {
QStringList regmatch = *i;
QString key = i.key();
for (int t = 0; t < regmatch.size(); t++) {
if (keyword == "/")
continue;
QString str = regmatch.at(t);
if (str.contains(keyword)) {
resultInfo.name = str;//中文名
str = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(str, true);
resultInfo.actionKey = str;
searchResult->enqueue(resultInfo);
continue;
}
pinyinlist = FileUtils::findMultiToneWords(str);
for (int i = 0; i < pinyinlist.size() / 2; i++) {
str = regmatch.at(t);
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
if (shouzimu.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = str;
str = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(str, true);
resultInfo.actionKey = str;
searchResult->enqueue(resultInfo);
break;
}
if (keyword.size() < 2)
break;
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
if (pinyin.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = str;
str = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(str, true);
resultInfo.actionKey = str;
searchResult->enqueue(resultInfo);
break;
}
}
}
}
}
if (ql.language() == QLocale::English) {
for (auto i = m_englishSearchList.constBegin(); i != m_englishSearchList.constEnd(); ++i) {
QStringList regmatch = *i;
QString key = i.key();
for (int t = 0; t < regmatch.size(); t++) {
if (keyword == "/")
continue;
QString str = regmatch.at(t);
if (str.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = str;
str = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(str, true);
resultInfo.actionKey = str;
searchResult->enqueue(resultInfo);
}
}
}
}
*/
//匹配中英混合列表(一级菜单)
for (auto i = m_mixSearchList.constBegin(); i != m_mixSearchList.constEnd(); ++i) {
QMap<QString, QString> regmatch = *i;
QString key = i.key();
for (auto t = regmatch.begin(); t != regmatch.end(); ++t) {
QString englishStr = t.value();
QString chineseStr = t.key();
QString englishPath = "";
QString chinesePath = "";
//转拼音(支持模糊)
QStringList pinyinlist = FileUtils::findMultiToneWords(chineseStr);
for (int i = 0; i < pinyinlist.size() / 2; i++) {
//首字母
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
if (shouzimu.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? chineseStr : englishStr;
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
if(ql.language() == QLocale::English) {
englishPath = key + "/" + englishStr;
resultInfo.icon = FileUtils::getSettingIcon(englishPath, true);
resultInfo.actionKey = englishPath;
} else if (ql.language() == QLocale::Chinese) {
chinesePath = key + "/" + chineseStr;
resultInfo.icon = FileUtils::getSettingIcon(chinesePath, true);
resultInfo.actionKey = chinesePath;
}
searchResult->enqueue(resultInfo);
break;
}
if (keyword.size() < 2)
break;
//拼音
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
if (pinyin.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? chineseStr : englishStr;
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
if(ql.language() == QLocale::English) {
englishPath = key + "/" + englishStr;
resultInfo.icon = FileUtils::getSettingIcon(englishPath, true);
resultInfo.actionKey = englishPath;
} else if (ql.language() == QLocale::Chinese) {
chinesePath = key + "/" + chineseStr;
resultInfo.icon = FileUtils::getSettingIcon(chinesePath, true);
resultInfo.actionKey = chinesePath;
}
searchResult->enqueue(resultInfo);
break;
}
}
//中文名
if (chineseStr.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? chineseStr : englishStr;
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
chinesePath = key + "/" + chineseStr;
resultInfo.icon = FileUtils::getSettingIcon(chinesePath, true);
resultInfo.actionKey = chinesePath;
searchResult->enqueue(resultInfo);
}
//英文名
if (englishStr.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? chineseStr : englishStr;
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
englishPath = key + "/" + englishStr;
resultInfo.icon = FileUtils::getSettingIcon(englishPath, true);
resultInfo.actionKey = englishPath;
searchResult->enqueue(resultInfo);
}
}
}
//匹配中文列表(二级菜单)
for (auto i = m_chineseSearchList.constBegin(); i != m_chineseSearchList.constEnd(); ++i) {
QStringList regmatch = *i;
QString key = i.key();
for (int t = 0; t < regmatch.size(); t++) {
QString str = regmatch.at(t);
QString path = "";
//直接匹配
if (str.contains(keyword)) {
resultInfo.name = ql.language() == QLocale::Chinese ? str : m_englishSearchList[key].at(t);
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
path = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(path, true);
resultInfo.actionKey = path;
searchResult->enqueue(resultInfo);
continue;
}
//转拼音(支持模糊)
pinyinlist = FileUtils::findMultiToneWords(str);
for (int i = 0; i < pinyinlist.size() / 2; i++) {
//首字母匹配
QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母
if (shouzimu.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? str : m_englishSearchList[key].at(t);
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
path = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(path, true);
resultInfo.actionKey = path;
searchResult->enqueue(resultInfo);
break;
}
if (keyword.size() < 2)
break;
//拼音匹配
QString pinyin = pinyinlist.at(2 * i); // 中文转拼音
if (pinyin.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? str : m_englishSearchList[key].at(t);
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
path = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(path, true);
resultInfo.actionKey = path;
searchResult->enqueue(resultInfo);
break;
}
}
}
}
//匹配英文列表(二级菜单)
for (auto i = m_englishSearchList.constBegin(); i != m_englishSearchList.constEnd(); ++i) {
QStringList regmatch = *i;
QString key = i.key();
QString path = "";
for (int t = 0; t < regmatch.size(); t++) {
QString str = regmatch.at(t);
if (str.contains(keyword, Qt::CaseInsensitive)) {
resultInfo.name = ql.language() == QLocale::Chinese ? m_chineseSearchList[key].at(t) : str;
if (resultName.contains(resultInfo.name)) {
continue;
}
resultName.append(resultInfo.name);
path = key + "/" + str;
resultInfo.icon = FileUtils::getSettingIcon(path, true);
resultInfo.actionKey = path;
searchResult->enqueue(resultInfo);
}
}
}
m_mutex.lock();
++m_uniqueSymbolForSettings;
m_mutex.unlock();
SettingsSearch *settingSearch = new SettingsSearch(searchResult, keyword, m_uniqueSymbolForSettings);
m_pool.start(settingSearch);
}
QList<SearchPluginIface::Actioninfo> SettingsSearchPlugin::getActioninfo(int type)
@ -273,7 +56,7 @@ void SettingsSearchPlugin::openAction(int actionkey, QString key, int type)
switch (actionkey) {
case 0:
//打开控制面板对应页面
process.startDetached(QString("ukui-control-center -m %1").arg(key.left(key.indexOf("/")).toLower()));
process.startDetached(QString("ukui-control-center -m %1").arg(key.toLower()));
break;
default:
@ -304,85 +87,6 @@ QWidget *SettingsSearchPlugin::detailPage(const ResultInfo &ri)
// return nullptr;
//}
/**
* @brief SettingsSearchPlugin::xmlElement
* xml文件内容读到内存
*/
void SettingsSearchPlugin::xmlElement() {
QString environment = QProcessEnvironment::systemEnvironment().value("XDG_SESSION_TYPE");
QString version;
QFile file(QString::fromLocal8Bit("/usr/share/ukui-control-center/shell/res/search.xml"));
if(!file.open(QIODevice::ReadOnly)) {
return;
}
QDomDocument doc;
doc.setContent(&file);
QDomElement root = doc.documentElement();
QDomNode node = root.previousSibling();
node = root.firstChild();
QString chineseIndex;
QString englishIndex;
QStringList chineseSearchResult;
QStringList englishSearchResult;
while (!node.isNull()) {
QDomElement element = node.toElement();
QDomNodeList list = element.childNodes();
//通过xml文件的子节点判断父节点是否有问题
if (list.count() >= 8 && (list.at(6).nodeName() == QString::fromLocal8Bit("EnglishFunc1"))) {
//直接获取二级菜单英文名
QString key = list.at(6).toElement().text();
chineseSearchResult = m_chineseSearchList.value(key);
englishSearchResult = m_englishSearchList.value(key);
for (int i = 0; i < list.count(); ++i) {
QDomNode n = list.at(i);
if (n.nodeName() == QString::fromLocal8Bit("Environment")) {
version=n.toElement().text();
if ((version == "v101" && environment == "wayland")
|| (version == "hw990" && environment == "x11")) {
break;
}
continue;
}
if (n.nodeName() == QString::fromLocal8Bit("ChineseFunc1")) {
chineseIndex = n.toElement().text();
if (chineseIndex.isEmpty()) {
continue;
}
if (0 == m_mixSearchList[key].count(chineseIndex)) {
m_mixSearchList[key].insert(chineseIndex, key);
}
}
if (n.nodeName() == QString::fromLocal8Bit("ChineseFunc2")) {
chineseIndex = n.toElement().text();
if (chineseIndex.isEmpty()) {
continue;
}
chineseSearchResult.append(chineseIndex);
}
if (n.nodeName() == QString::fromLocal8Bit("EnglishFunc2")) {
englishIndex = /*QString::fromLocal8Bit("/") + */n.toElement().text();
if (englishIndex.isEmpty()) {
continue;
}
englishSearchResult.append(englishIndex);
}
}
m_chineseSearchList.insert(key, chineseSearchResult);
m_englishSearchList.insert(key, englishSearchResult);
node = node.nextSibling();
} else {
qWarning() << "There's something wrong with the xml file's item:" << element.attribute("name");
node = node.nextSibling();
}
}
file.close();
}
void SettingsSearchPlugin::initDetailPage()
{
m_detailPage = new QWidget();
@ -432,3 +136,168 @@ void SettingsSearchPlugin::initDetailPage()
openAction(0, m_currentActionKey, 0);
});
}
SettingsSearch::SettingsSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, const QString &keyword, size_t uniqueSymbol)
{
this->setAutoDelete(true);
this->m_searchResult = searchResult;
this->m_keyword = keyword;
this->m_uniqueSymbol = uniqueSymbol;
}
void SettingsSearch::run()
{
SettingsMatch::getInstance()->startSearch(m_keyword, m_uniqueSymbol, m_searchResult);
}
SettingsMatch *SettingsMatch::getInstance()
{
if (!settingMatchClass) {
settingMatchClass = new SettingsMatch;
}
return settingMatchClass;
}
void SettingsMatch::run()
{
this->initDataOfXml();
}
/**
* @brief SettingsMatch::initDataOfXml
* xml文件内容读到内存
*/
void SettingsMatch::initDataOfXml(){
QFile file(QString::fromLocal8Bit("/usr/share/ukui-control-center/shell/res/search.xml"));//xml文件所在路径
if(!file.open(QIODevice::ReadOnly)) {
return;
}
QDomDocument doc;
doc.setContent(&file);
file.close();
QDomElement root = doc.documentElement();
QDomNode node = root.previousSibling();
node = root.firstChild();
matchNodes(node);
}
bool SettingsMatch::matchCommonEnvironment(QDomNode childNode)
{
if (childNode.nodeName() == QString::fromLocal8Bit("Environment")) {
QString environment = QProcessEnvironment::systemEnvironment().value("XDG_SESSION_TYPE");
QString version = childNode.toElement().text();
if ((version == "v101" && environment == "wayland")
|| (version == "hw990" && environment == "x11")) {
return false;
}
}
return true;
}
void SettingsMatch::matchNodes(QDomNode node){
QString chineseIndex;
QString englishIndex;
QStringList englishSearchResult;
while (!node.isNull()) {
QDomElement element = node.toElement();
QDomNodeList list = element.childNodes();
QString enNameOfModule = element.attribute("name");
QString enNameOfPlugin = list.at(0).nextSiblingElement("EnglishFunc1").toElement().text();
QString enNameOfFunc = list.at(0).nextSiblingElement("EnglishFunc2").toElement().text();
englishSearchResult = m_searchMap[enNameOfModule].value(enNameOfPlugin);
for (int i = 0; i < list.count(); ++i) {
QDomNode childNode = list.at(i);
QStringList aItemInfo;
chineseIndex = childNode.toElement().text();
if (!matchCommonEnvironment(childNode)) {
break;
}
//TODO: Refactoring this part of code.
if (childNode.nodeName() == QString::fromLocal8Bit("ChinesePlugin")) {
englishIndex = enNameOfModule;
aItemInfo << englishIndex << chineseIndex << FileUtils::findMultiToneWords(chineseIndex);
m_dataMap.insert(enNameOfModule, aItemInfo);
}
if (childNode.nodeName() == QString::fromLocal8Bit("ChineseFunc1")) {
englishIndex = enNameOfPlugin;
aItemInfo << englishIndex << chineseIndex << FileUtils::findMultiToneWords(chineseIndex);
m_dataMap.insert(enNameOfModule + "/" + enNameOfPlugin, aItemInfo);
}
if (childNode.nodeName() == QString::fromLocal8Bit("ChineseFunc2")) {
englishIndex = enNameOfFunc;
englishSearchResult.append(englishIndex);
aItemInfo << englishIndex << chineseIndex << FileUtils::findMultiToneWords(chineseIndex);
m_dataMap.insert(enNameOfModule + "/" + enNameOfPlugin+ "/" + englishIndex, aItemInfo);
}
}
m_searchMap[enNameOfModule].insert(enNameOfPlugin, englishSearchResult);
node = node.nextSibling();
}
}
void SettingsMatch::startSearch(QString &keyword, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult)
{
if (keyword == "/") {
return;
}
//根据searchMap的对应关系匹配dataMap中的数据信息
for (auto i = m_searchMap.constBegin(); i != m_searchMap.constEnd(); ++i) {
QMap<QString, QStringList> regMatch = *i;
QString moduleName = i.key();
for (auto t = regMatch.begin(); t != regMatch.end(); ++t) {
//匹配二级菜单信息
QString pluginName = t.key();
QString keyOfSecondLv =QString("%1/%2").arg(moduleName, pluginName);
matchDataMap(keyOfSecondLv, keyword, uniqueSymbol, searchResult);
//匹配对应三级菜单信息
for (QString funcName: t.value()) {
QString keyOfThirdLv = keyOfSecondLv + QString("/%1").arg(funcName);
matchDataMap(keyOfThirdLv, keyword, uniqueSymbol, searchResult);
}
}
}
}
void SettingsMatch::matchDataMap(QString &key, QString &keyword, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult)
{
SearchPluginIface::ResultInfo resultInfo;
resultInfo.type = 0;
for (int counter = 0; counter < m_dataMap.value(key).size(); ++counter) {
QString data = m_dataMap.value(key).at(counter);
//关键字为单字不搜拼音
if (keyword.size() < 2 and counter > 1 and counter % 2 == 0) {
continue;
}
if (data.contains(keyword, Qt::CaseInsensitive)) {
createResultInfo(resultInfo, m_dataMap.value(key), key);
//判断是否为同一次搜索
if (uniqueSymbol == SettingsSearchPlugin::m_uniqueSymbolForSettings) {
searchResult->enqueue(resultInfo);
SettingsSearchPlugin::m_mutex.unlock();
break;
} else {
SettingsSearchPlugin::m_mutex.unlock();
return;
}
}
}
}
void SettingsMatch::createResultInfo(SearchPluginIface::ResultInfo &resultInfo, const QStringList &itemInfo, const QString &path)
{
QLocale ql;
resultInfo.name = ql.language() == QLocale::English ? itemInfo.at(0) : itemInfo.at(1);
resultInfo.icon = FileUtils::getSettingIcon();
resultInfo.actionKey = path.section("/", 1, 1);
}

View File

@ -9,6 +9,7 @@
#include <QFrame>
#include <QLabel>
#include <QAction>
#include <QDomDocument>
#include "action-label.h"
#include "search-plugin-iface.h"
@ -16,8 +17,9 @@ namespace Zeeker {
class LIBSEARCH_EXPORT SettingsSearchPlugin : public QObject, public SearchPluginIface
{
Q_OBJECT
friend class SettingsSearch;
friend class SettingsMatch;
public:
SettingsSearchPlugin(QObject *parent = nullptr);
PluginType pluginType() {return PluginType::SearchPlugin;}
const QString name();
@ -35,8 +37,13 @@ public:
QWidget *detailPage(const ResultInfo &ri);
private:
void xmlElement();
void initDetailPage();
bool m_enable = true;
QList<SettingsSearchPlugin::Actioninfo> m_actionInfo;
QThreadPool m_pool;
static size_t m_uniqueSymbolForSettings;
static QMutex m_mutex;
QString m_currentActionKey;
QWidget *m_detailPage = nullptr;
QVBoxLayout *m_detailLyt = nullptr;
@ -49,15 +56,38 @@ private:
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;
QVBoxLayout * m_actionLyt = nullptr;
};
QMap<QString, QStringList> m_chineseSearchList;
QMap<QString, QStringList> m_englishSearchList;
QMap<QString, QMap<QString, QString>> m_mixSearchList;//map数据对应Chinese Name和English Name
class SettingsSearch :public QObject, public QRunnable {
Q_OBJECT
public:
SettingsSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, const QString& keyword, size_t uniqueSymbol);
~SettingsSearch() = default;
protected:
void run() override;
private:
QString m_keyword;
size_t m_uniqueSymbol;
DataQueue<SearchPluginIface::ResultInfo> *m_searchResult = nullptr;
};
bool m_enable = true;
QList<SettingsSearchPlugin::Actioninfo> m_actionInfo;
class SettingsMatch :public QObject , public QThread {
public:
static SettingsMatch *getInstance();
void startSearch(QString &keyword, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult);
protected:
void run() override;
private:
explicit SettingsMatch() = default;
~SettingsMatch() = default;
void initDataOfXml();
bool matchCommonEnvironment(QDomNode childNode);
void matchNodes(QDomNode node);
void matchDataMap(QString &key, QString &keyword, size_t uniqueSymbol, DataQueue<SearchPluginIface::ResultInfo> *searchResult);
void createResultInfo(SearchPluginIface::ResultInfo &resultInfo, const QStringList &itemInfo, const QString &path);
QMap<QString, QMap<QString, QStringList>> m_searchMap;
QMap<QString, QStringList> m_dataMap;
};
}
#endif // SETTINGSSEARCHPLUGIN_H