From 3efb8f66a604baca4833a92627363f294a0b83d6 Mon Sep 17 00:00:00 2001 From: zhangzihao Date: Thu, 26 Aug 2021 08:20:38 +0800 Subject: [PATCH] Add note search plugin. --- libsearch/libsearch.h | 1 - libsearch/libsearch.pro | 5 +- libsearch/notesearch/note-search-plugin.cpp | 200 ++++++++++++++++++ libsearch/notesearch/note-search-plugin.h | 87 ++++++++ libsearch/notesearch/notesearch.pri | 7 + .../pluginmanage/search-plugin-manager.cpp | 4 +- libsearch/settingsearch/setting-match.cpp | 156 -------------- libsearch/settingsearch/setting-match.h | 54 ----- libsearch/settingsearch/settingsearch.pri | 2 - 9 files changed, 299 insertions(+), 217 deletions(-) create mode 100644 libsearch/notesearch/note-search-plugin.cpp create mode 100644 libsearch/notesearch/note-search-plugin.h create mode 100644 libsearch/notesearch/notesearch.pri delete mode 100644 libsearch/settingsearch/setting-match.cpp delete mode 100644 libsearch/settingsearch/setting-match.h diff --git a/libsearch/libsearch.h b/libsearch/libsearch.h index 5c0bfa7..7ef4074 100644 --- a/libsearch/libsearch.h +++ b/libsearch/libsearch.h @@ -22,7 +22,6 @@ #include "libsearch_global.h" #include "appsearch/app-match.h" -#include "settingsearch/setting-match.h" #include "file-utils.h" #include "global-settings.h" diff --git a/libsearch/libsearch.pro b/libsearch/libsearch.pro index d8b8ac9..58618fd 100644 --- a/libsearch/libsearch.pro +++ b/libsearch/libsearch.pro @@ -27,12 +27,11 @@ DEFINES += PLUGIN_INSTALL_DIRS='\\"$${PLUGIN_INSTALL_DIRS}\\"' include(pluginmanage/plugin-manager.pri) include(plugininterface/plugin-interface.pri) include(index/index.pri) -include(parser/parser.pri)) +include(parser/parser.pri) include(appsearch/appsearch.pri) +include(notesearch/notesearch.pri) include(settingsearch/settingsearch.pri)) - - LIBS += -L$$OUT_PWD/../libchinese-segmentation/ -lchinese-segmentation LIBS += -lxapian -lquazip5 -luchardet #-L/usr/local/lib/libjemalloc -ljemalloc diff --git a/libsearch/notesearch/note-search-plugin.cpp b/libsearch/notesearch/note-search-plugin.cpp new file mode 100644 index 0000000..4bbc87a --- /dev/null +++ b/libsearch/notesearch/note-search-plugin.cpp @@ -0,0 +1,200 @@ +#include "note-search-plugin.h" +#include +#include +#include "file-utils.h" +#include "chinese-segmentation.h" +using namespace Zeeker; + +NoteSearchPlugin::NoteSearchPlugin(QObject *parent) +{ + g_uniqueSymbol = 0; + SearchPluginIface::Actioninfo open { 0, tr("Open")}; + m_actionInfo << open; + m_pool.setMaxThreadCount(1); + m_pool.setExpiryTimeout(1000); + initDetailPage(); +} + +const QString NoteSearchPlugin::name() +{ + return tr("Note Search"); +} + +const QString NoteSearchPlugin::description() +{ + return tr("Note Search."); +} + +QString NoteSearchPlugin::getPluginName() +{ + return tr("Note Search"); +} + +void NoteSearchPlugin::KeywordSearch(QString keyword, DataQueue *searchResult) +{ + g_mutex.lock(); + ++g_uniqueSymbol; + g_mutex.unlock(); + NoteSearch *ns = new NoteSearch(searchResult, keyword, g_uniqueSymbol); + m_pool.start(ns); +} + +QList NoteSearchPlugin::getActioninfo(int type) +{ + return m_actionInfo; +} + +void NoteSearchPlugin::openAction(int actionkey, QString key, int type) +{ + QProcess process; + switch (actionkey) { + case 0: + process.startDetached(QString("ukui-notebook --show %1").arg(key.toInt())); + break; + default: + break; + } +} + +QWidget *NoteSearchPlugin::detailPage(const SearchPluginIface::ResultInfo &ri) +{ + m_currentActionKey = ri.actionKey; + m_iconLabel->setPixmap(ri.icon.pixmap(120, 120)); + QFontMetrics fontMetrics = m_nameLabel->fontMetrics(); + QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号 + m_nameLabel->setText(QString("

%1

").arg(FileUtils::escapeHtml(showname))); + if(QString::compare(showname, ri.name)) { + m_nameLabel->setToolTip(ri.name); + } + m_pluginLabel->setText(tr("Application")); + QString showDesc = fontMetrics.elidedText(ri.description.at(0).key + " " + ri.description.at(0).value, Qt::ElideRight, 3114); //当字体长度超过215时显示为省略号 + m_descLabel->setText(FileUtils::escapeHtml(showDesc)); + m_descFrame->show(); + m_line_2->show(); + return m_detailPage; +} + +void NoteSearchPlugin::initDetailPage() +{ + m_detailPage = new QWidget(); + m_detailPage->setFixedWidth(360); + m_detailPage->setAttribute(Qt::WA_TranslucentBackground); + m_detailLyt = new QVBoxLayout(m_detailPage); + m_detailLyt->setContentsMargins(8, 0, 16, 0); + m_iconLabel = new QLabel(m_detailPage); + m_iconLabel->setAlignment(Qt::AlignCenter); + m_iconLabel->setFixedHeight(128); + + m_nameFrame = new QFrame(m_detailPage); + m_nameFrameLyt = new QHBoxLayout(m_nameFrame); + m_nameFrame->setLayout(m_nameFrameLyt); + m_nameFrameLyt->setContentsMargins(8, 0, 0, 0); + m_nameLabel = new QLabel(m_nameFrame); + m_nameLabel->setMaximumWidth(280); + m_pluginLabel = new QLabel(m_nameFrame); + m_pluginLabel->setText(tr("Note Search")); + m_pluginLabel->setEnabled(false); + m_nameFrameLyt->addWidget(m_nameLabel); + m_nameFrameLyt->addStretch(); + m_nameFrameLyt->addWidget(m_pluginLabel); + + m_line_1 = new QFrame(m_detailPage); + m_line_1->setLineWidth(0); + m_line_1->setFixedHeight(1); + m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}"); + m_descFrame = new QFrame(m_detailPage); + m_descFrameLyt = new QVBoxLayout(m_descFrame); + m_descLabel = new QLabel(m_descFrame); + m_descLabel->setTextFormat(Qt::PlainText); + m_descLabel->setWordWrap(true); + m_descFrameLyt->addWidget(m_descLabel); + m_descFrame->setLayout(m_descFrameLyt); + m_descFrameLyt->setContentsMargins(8, 0, 0, 0); + m_line_2 = new QFrame(m_detailPage); + m_line_2->setLineWidth(0); + m_line_2->setFixedHeight(1); + m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}"); + + m_line_1 = new QFrame(m_detailPage); + m_line_1->setLineWidth(0); + m_line_1->setFixedHeight(1); + m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}"); + + m_actionFrame = new QFrame(m_detailPage); + m_actionFrameLyt = new QVBoxLayout(m_actionFrame); + m_actionFrameLyt->setContentsMargins(8, 0, 0, 0); + m_actionLabel1 = new ActionLabel(tr("Open"), m_currentActionKey, m_actionFrame); + + m_actionFrameLyt->addWidget(m_actionLabel1);; + m_actionFrame->setLayout(m_actionFrameLyt); + + m_detailLyt->addSpacing(50); + m_detailLyt->addWidget(m_iconLabel); + m_detailLyt->addWidget(m_nameFrame); + m_detailLyt->addWidget(m_line_1); + m_detailLyt->addWidget(m_descFrame); + m_detailLyt->addWidget(m_line_2); + m_detailLyt->addWidget(m_actionFrame); + m_detailPage->setLayout(m_detailLyt); + m_detailLyt->addStretch(); + + connect(m_actionLabel1, &ActionLabel::actionTriggered, [ & ](){ + openAction(0, m_currentActionKey, 0); + }); +} + + +NoteSearch::NoteSearch(DataQueue *searchResult, const QString &keyword, size_t uniqueSymbol) { + this->setAutoDelete(true); + this->m_searchResult = searchResult; + this->m_keyword = keyword; + this->m_uniqueSymbol = uniqueSymbol; +} + +void NoteSearch::run() { + QVector sKeyWordVec = ChineseSegmentation::getInstance()->callSegement(m_keyword.toStdString()); + QStringList keywordList; + for (SKeyWord sKeyWord : sKeyWordVec) { + keywordList.append(QString::fromStdString(sKeyWord.word)); + } + QDBusInterface qi("org.ukui.note", "/org/ukui/note", "org.ukui.note.interface", QDBusConnection::sessionBus()); + QDBusReply reply = qi.call("keywordMatch", keywordList); + + if(reply.isValid()) { + if (m_uniqueSymbol ^ g_uniqueSymbol) { + qDebug() << m_uniqueSymbol << g_uniqueSymbol; + return; + } else { + qDebug() << m_uniqueSymbol << g_uniqueSymbol; + + for (std::pair it : reply.value().toStdMap()) { + qDebug() << it.first; + qDebug() << it.second; + qDebug() << it.second.value().currentType(); + QDBusArgument dbusArgs = it.second.value(); + QStringList str; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + QVariant tmp; + dbusArgs >> tmp; + str.append(tmp.toString()); + } + dbusArgs.endArray(); + qDebug() << str; + SearchPluginIface::ResultInfo ri = { + icon : QIcon::fromTheme("kylin-notebook"), + name : str.at(1), + description : QVector() << SearchPluginIface::DescriptionInfo { + key : QString(tr("Note Description:")), + value : str.at(0) + }, + actionKey : it.first + }; + m_searchResult->enqueue(ri); + } + } + } else { + qWarning() << "Note dbus called failed!" << qi.lastError(); + } +} + diff --git a/libsearch/notesearch/note-search-plugin.h b/libsearch/notesearch/note-search-plugin.h new file mode 100644 index 0000000..2080bac --- /dev/null +++ b/libsearch/notesearch/note-search-plugin.h @@ -0,0 +1,87 @@ +#ifndef NOTESEARCHPLUGIN_H +#define NOTESEARCHPLUGIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "search-plugin-iface.h" +#include "action-label.h" +#include "libsearch_global.h" +namespace Zeeker { + +static size_t g_uniqueSymbol; +static QMutex g_mutex; + +class NoteSearch; + +class LIBSEARCH_EXPORT NoteSearchPlugin : public QObject, public SearchPluginIface +{ + Q_OBJECT + friend class NoteSearch; +public: + NoteSearchPlugin(QObject *parent = nullptr); + PluginType pluginType() {return PluginType::SearchPlugin;} + const QString name(); + const QString description(); + const QIcon icon() {return QIcon::fromTheme("folder");} + 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); +// bool isPreviewEnable(QString key, int type); +// QWidget *previewPage(QString key, int type, QWidget *parent); + QWidget *detailPage(const ResultInfo &ri); + +private: + QDBusInterface *m_interFace = nullptr; + void initDetailPage(); + QString m_currentActionKey; + QWidget *m_detailPage = nullptr; + QVBoxLayout *m_detailLyt = nullptr; + QLabel *m_iconLabel = nullptr; + QFrame *m_nameFrame = nullptr; + QHBoxLayout *m_nameFrameLyt = nullptr; + QLabel *m_nameLabel = nullptr; + QLabel *m_pluginLabel = nullptr; + QFrame *m_line_1 = nullptr; + QFrame *m_descFrame = nullptr; + QLabel *m_descLabel = nullptr; + QVBoxLayout *m_descFrameLyt = nullptr; + QFrame *m_line_2 = nullptr; + QFrame *m_actionFrame = nullptr; + QVBoxLayout *m_actionFrameLyt = nullptr; + ActionLabel *m_actionLabel1 = nullptr; + QVBoxLayout * m_actionLyt = nullptr; + + bool m_enable = true; + QList m_actionInfo; + QThreadPool m_pool; +}; + +class NoteSearch : public QObject, public QRunnable { + Q_OBJECT +public: + NoteSearch(DataQueue *searchResult, const QString& keyword, size_t uniqueSymbol); + ~NoteSearch() = default; +protected: + void run() override; +private: + DataQueue *m_searchResult = nullptr; + size_t m_uniqueSymbol; + QString m_keyword; +}; +} + +#endif // NOTESEARCHPLUGIN_H diff --git a/libsearch/notesearch/notesearch.pri b/libsearch/notesearch/notesearch.pri new file mode 100644 index 0000000..62dc971 --- /dev/null +++ b/libsearch/notesearch/notesearch.pri @@ -0,0 +1,7 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/note-search-plugin.h + +SOURCES += \ + $$PWD/note-search-plugin.cpp diff --git a/libsearch/pluginmanage/search-plugin-manager.cpp b/libsearch/pluginmanage/search-plugin-manager.cpp index 6251530..0d10bef 100644 --- a/libsearch/pluginmanage/search-plugin-manager.cpp +++ b/libsearch/pluginmanage/search-plugin-manager.cpp @@ -1,8 +1,9 @@ #include #include "search-plugin-manager.h" #include "file-search-plugin.h" -#include "app-search-plugin.h"- +#include "app-search-plugin.h" #include "settings-search-plugin.h" +#include "note-search-plugin.h" using namespace Zeeker; @@ -10,6 +11,7 @@ static SearchPluginManager *global_instance = nullptr; SearchPluginManager::SearchPluginManager(QObject *parent) { registerPlugin(new AppSearchPlugin(this)); + registerPlugin(new NoteSearchPlugin(this)); registerPlugin(new SettingsSearchPlugin(this)); registerPlugin(new DirSearchPlugin(this)); registerPlugin(new FileSearchPlugin(this)); diff --git a/libsearch/settingsearch/setting-match.cpp b/libsearch/settingsearch/setting-match.cpp deleted file mode 100644 index 69b86fd..0000000 --- a/libsearch/settingsearch/setting-match.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 . - * - * Authors: sunfengsheng - * - */ -#include "setting-match.h" -#include "file-utils.h" -#include -using namespace Zeeker; -SettingsMatch::SettingsMatch(QObject *parent) : QObject(parent) { - xmlElement(); -} - -/** - * @brief SettingsMatch::startMatchApp - * 返回给页面 - * @param source - * 获取的字符串 - * @return - */ -QStringList SettingsMatch::startMatchApp(const QString &source) { - m_sourceText = source; - QStringList settingList = matching(); - return settingList; -} - -/** - * @brief SettingsMatch::xmlElement - * 将xml文件内容读到内存 - */ -void SettingsMatch::xmlElement() { - QString ChineseIndex; - QString EnglishIndex; - QString path = 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(); - - while(!node.isNull()) { - QDomElement element = node.toElement(); - QString key = element.attribute("name"); - m_chine_searchResult = m_chine_searchList.value(key); - m_English_searchResult = m_English_searchList.value(key); - QDomNodeList list = element.childNodes(); - 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"&&path=="wayland")||(version=="hw990"&&path=="x11")){ - break; - } - } - if(n.nodeName() == QString::fromLocal8Bit("ChinesePlugin")) { - ChineseIndex = n.toElement().text(); - } - if(n.nodeName() == QString::fromLocal8Bit("ChineseFunc")) { - ChineseIndex += QString::fromLocal8Bit("/") + n.toElement().text(); - m_chine_searchResult.append(ChineseIndex); - } - if(n.nodeName() == QString::fromLocal8Bit("EnglishFunc")) { - EnglishIndex = QString::fromLocal8Bit("/") + n.toElement().text(); - m_English_searchResult.append(EnglishIndex); - } - } - m_chine_searchList.insert(key, m_chine_searchResult); - m_English_searchList.insert(key, m_English_searchResult); - node = node.nextSibling(); - } - file.close(); -} - -/** - * @brief SettingsMatch::matching - * 进行关键字匹配 - * @return - */ -QStringList SettingsMatch::matching() { - QStringList returnresult; - QStringList regmatch; - QString key; - QStringList pinyinlist; - QMap::const_iterator i; - QLocale ql; - if(ql.language() == QLocale::Chinese) { - for(i = m_chine_searchList.constBegin(); i != m_chine_searchList.constEnd(); ++i) { - regmatch = *i; - key = i.key(); - for(int t = 0; t < regmatch.size(); t++) { - if(m_sourceText == "/") - continue; - QString str = regmatch.at(t); - pinyinlist = FileUtils::findMultiToneWords(str); - if(str.contains(m_sourceText)) { - str = key + "/" + str; - returnresult.append(str);//中文名 - continue; - } - for(int i = 0; i < pinyinlist.size() / 2; i++) { - str = regmatch.at(t); - QString shouzimu = pinyinlist.at(2 * i + 1); // 中文转首字母 - if(shouzimu.contains(m_sourceText, Qt::CaseInsensitive)) { - str = key + "/" + str; - returnresult.append(str); - break; - } - if(m_sourceText.size() < 2) - break; - QString pinyin = pinyinlist.at(2 * i); // 中文转拼音 - if(pinyin.contains(m_sourceText, Qt::CaseInsensitive)) { - str = key + "/" + str; - returnresult.append(str); - break; - } - } - - } - } - } - if(ql.language() == QLocale::English) { - for(i = m_English_searchList.constBegin(); i != m_English_searchList.constEnd(); ++i) { - regmatch = *i; - key = i.key(); - for(int t = 0; t < regmatch.size(); t++) { - if(m_sourceText == "/") - continue; - QString str = regmatch.at(t); - if(str.contains(m_sourceText, Qt::CaseInsensitive)) { - str = key + "/" + str; - returnresult.append(str); - } - } - } - } - return returnresult; -} diff --git a/libsearch/settingsearch/setting-match.h b/libsearch/settingsearch/setting-match.h deleted file mode 100644 index 5cbe62f..0000000 --- a/libsearch/settingsearch/setting-match.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 . - * - * Authors: sunfengsheng - * - */ -#ifndef SETTINGSEARCH_H -#define SETTINGSEARCH_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace Zeeker { -class SettingsMatch : public QObject { - Q_OBJECT -public: - explicit SettingsMatch(QObject *parent = nullptr); - QStringList startMatchApp(const QString &source); - -private: - void xmlElement(); - QStringList matching(); - -private: - QMap m_chine_searchList; - QMap m_English_searchList; - QStringList m_chine_searchResult; - QStringList m_English_searchResult; - QString m_sourceText; - -}; -} - -#endif // SETTINGSEARCH_H diff --git a/libsearch/settingsearch/settingsearch.pri b/libsearch/settingsearch/settingsearch.pri index 2ca2624..fd5ff3b 100644 --- a/libsearch/settingsearch/settingsearch.pri +++ b/libsearch/settingsearch/settingsearch.pri @@ -1,9 +1,7 @@ INCLUDEPATH += $$PWD HEADERS += \ - $$PWD/setting-match.h \ $$PWD/settings-search-plugin.h SOURCES += \ - $$PWD/setting-match.cpp \ $$PWD/settings-search-plugin.cpp