Add note search plugin.

This commit is contained in:
zhangzihao 2021-08-26 08:20:38 +08:00
parent 9d34095932
commit 3efb8f66a6
9 changed files with 299 additions and 217 deletions

View File

@ -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"

View File

@ -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

View File

@ -0,0 +1,200 @@
#include "note-search-plugin.h"
#include <QWidget>
#include <QLabel>
#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<SearchPluginIface::ResultInfo> *searchResult)
{
g_mutex.lock();
++g_uniqueSymbol;
g_mutex.unlock();
NoteSearch *ns = new NoteSearch(searchResult, keyword, g_uniqueSymbol);
m_pool.start(ns);
}
QList<SearchPluginIface::Actioninfo> 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("<h3 style=\"font-weight:normal;\">%1</h3>").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<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 NoteSearch::run() {
QVector<SKeyWord> 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<QVariantMap> 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<QString, QVariant> it : reply.value().toStdMap()) {
qDebug() << it.first;
qDebug() << it.second;
qDebug() << it.second.value<QDBusArgument>().currentType();
QDBusArgument dbusArgs = it.second.value<QDBusArgument>();
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>() << 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();
}
}

View File

@ -0,0 +1,87 @@
#ifndef NOTESEARCHPLUGIN_H
#define NOTESEARCHPLUGIN_H
#include <QObject>
#include <QWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFrame>
#include <QLabel>
#include <QAction>
#include <QDBusInterface>
#include <QThreadPool>
#include <QProcess>
#include <QDBusReply>
#include <typeinfo>
#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<ResultInfo> *searchResult);
QList<SearchPluginIface::Actioninfo> 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<NoteSearchPlugin::Actioninfo> m_actionInfo;
QThreadPool m_pool;
};
class NoteSearch : public QObject, public QRunnable {
Q_OBJECT
public:
NoteSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, const QString& keyword, size_t uniqueSymbol);
~NoteSearch() = default;
protected:
void run() override;
private:
DataQueue<SearchPluginIface::ResultInfo> *m_searchResult = nullptr;
size_t m_uniqueSymbol;
QString m_keyword;
};
}
#endif // NOTESEARCHPLUGIN_H

View File

@ -0,0 +1,7 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/note-search-plugin.h
SOURCES += \
$$PWD/note-search-plugin.cpp

View File

@ -1,8 +1,9 @@
#include <QDebug>
#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));

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* Authors: sunfengsheng <sunfengsheng@kylinos.cn>
*
*/
#include "setting-match.h"
#include "file-utils.h"
#include <QProcessEnvironment>
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<QString, QStringList>::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;
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* Authors: sunfengsheng <sunfengsheng@kylinos.cn>
*
*/
#ifndef SETTINGSEARCH_H
#define SETTINGSEARCH_H
#include <QObject>
#include <QFile>
#include <QDomElement>
#include <QDomDocument>
#include <QDomNode>
#include <QDomNodeList>
#include <QMap>
#include <QStringList>
#include <QTimer>
#include <QDebug>
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<QString, QStringList> m_chine_searchList;
QMap<QString, QStringList> m_English_searchList;
QStringList m_chine_searchResult;
QStringList m_English_searchResult;
QString m_sourceText;
};
}
#endif // SETTINGSEARCH_H

View File

@ -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