Add plugin re-register and un-register function.

Modify the destructor function of Applications search plugin.

Enable plugins to adjust their order.
This commit is contained in:
baijunjie 2022-11-22 10:17:36 +08:00 committed by JunjieBai
parent 2ba15cf6c0
commit 192b2e9ed5
16 changed files with 690 additions and 30 deletions

View File

@ -59,6 +59,52 @@ void ResultArea::appendWidet(ResultWidget *widget)
m_widget->setFixedHeight(m_widget->height() + widget->height() + spacing_height);
}
void ResultArea::insertWidget(ResultWidget *widget, int index)
{
m_mainLyt->insertWidget(index, widget);
setupConnectionsForWidget(widget);
widget->clearResult();
m_widget_list.insert(index, widget);
qDebug() << "========insert widget:" << widget->pluginId() << index;
int spacing_height = m_widget_list.length() > 1 ? m_mainLyt->spacing() : 0;
m_widget->setFixedHeight(m_widget->height() + widget->height() + spacing_height);
}
bool ResultArea::removeWidget(const QString &pluginName)
{
int height = 0;
bool res(false);
for (ResultWidget *myWidget : m_widget_list) {
if (myWidget->pluginId() == pluginName) {
height = myWidget->height();
myWidget->disconnect();
myWidget->clearResult();
m_mainLyt->removeWidget(myWidget);
m_widget_list.removeAll(myWidget);
res = true;
break;
}
}
if (res) {
int spacing_height = m_widget_list.length() > 0 ? m_mainLyt->spacing() : 0;
m_widget->setFixedHeight(m_widget->height() - (height + spacing_height));
qDebug() << "Remove Widget " << pluginName;
}
return res;
}
bool ResultArea::moveWidget(const QString& pluginName, int index)
{
for (ResultWidget *myWidget : m_widget_list) {
if (myWidget->pluginId() == pluginName) {
m_mainLyt->removeWidget(myWidget);
m_mainLyt->insertWidget(index, myWidget);//第一个插件固定为bestlist
return true;
}
}
return false;
}
/**
* @brief ResultArea::setVisibleList
* @param list
@ -517,6 +563,8 @@ void ResultArea::setupConnectionsForWidget(ResultWidget *widget)
}
});
connect(widget, &ResultWidget::sendBestListData, m_bestListWidget, &BestListWidget::sendBestListData);
connect(SearchPluginManager::getInstance(), &SearchPluginManager::unregistered, this, &ResultArea::removeWidget);
}
DetailArea::DetailArea(QWidget *parent) : QScrollArea(parent)

View File

@ -37,6 +37,9 @@ public:
ResultArea(QWidget *parent = nullptr);
~ResultArea() = default;
void appendWidet(ResultWidget *);
void insertWidget(ResultWidget *widget, int index);
bool removeWidget(const QString& pluginName);
bool moveWidget(const QString& pluginName, int index);
void setVisibleList(const QStringList &);
void pressEnter();
void pressDown();

View File

@ -42,20 +42,57 @@ void SearchResultPage::setSize(const int&width, const int&height)
void SearchResultPage::setInternalPlugins()
{
Q_FOREACH (QString plugin_id, SearchPluginManager::getInstance()->getPluginIds()) {
ResultWidget * widget = new ResultWidget(plugin_id, m_resultArea);
QList<PluginInfo> infoList = SearchPluginManager::getInstance()->getPluginIds();
QVector<QString> pluginOrders(infoList.size());
for (const PluginInfo& info : infoList) {
if (info.isEnable() and info.order() > 0) {
if (info.order() > pluginOrders.size()) {
QVector<QString> tmpVct(info.order() - pluginOrders.size());
pluginOrders.append(tmpVct);
}
pluginOrders[info.order() - 1] = info.name();
}
}
pluginOrders.removeAll("");
for (const QString& pluginId : pluginOrders) {
ResultWidget * widget = new ResultWidget(pluginId, m_resultArea);
m_resultArea->appendWidet(widget);
setupConnectionsForWidget(widget);
}
}
void SearchResultPage::appendPlugin(const QString &plugin_id)
{
ResultWidget * widget = new ResultWidget(plugin_id, m_resultArea);
m_resultArea->appendWidet(widget);
QList<PluginInfo> infoList = SearchPluginManager::getInstance()->getPluginIds();
QVector<QString> pluginOrders(infoList.size());
for (const PluginInfo& info : infoList) {
if (info.isEnable() and info.order() > 0) {
if (info.order() > pluginOrders.size()) {
QVector<QString> tmpVct(info.order() - pluginOrders.size());
pluginOrders.append(tmpVct);
}
pluginOrders[info.order() - 1] = info.name();
}
}
pluginOrders.removeAll("");
if (pluginOrders.contains(plugin_id)) {
m_resultArea->insertWidget(widget, pluginOrders.indexOf(plugin_id) + 1);
} else {
m_resultArea->insertWidget(widget, pluginOrders.size());
}
setupConnectionsForWidget(widget);
}
void SearchResultPage::movePlugin(const QString &plugin_id, int index)
{
m_resultArea->moveWidget(plugin_id, index);
}
void SearchResultPage::pressEnter()
{
this->m_resultArea->pressEnter();
@ -177,6 +214,9 @@ void SearchResultPage::initConnections()
connect(qApp, &QApplication::paletteChanged, this, [=]() {
update();
});
connect(SearchPluginManager::getInstance(), &SearchPluginManager::reRegistered, this, &SearchResultPage::appendPlugin);
connect(SearchPluginManager::getInstance(), &SearchPluginManager::changePos, this, &SearchResultPage::movePlugin);
}
void SearchResultPage::setupConnectionsForWidget(ResultWidget *widget)

View File

@ -34,6 +34,7 @@ public:
void setSize(const int&, const int&);
void setInternalPlugins();
void appendPlugin(const QString &plugin_id);
void movePlugin(const QString &plugin_id, int index);
void pressEnter();
void pressUp();
void pressDown();

View File

@ -313,7 +313,7 @@ void MainWindow::searchKeywordSlot(const QString &keyword)
// m_stackedWidget->setPage(int(StackedPage::HomePage));
QTimer::singleShot(10, this, [ = ]() {
m_askTimer->stop();
// Q_EMIT m_searchResultPage->stopSearch();
Q_EMIT m_searchResultPage->stopSearch();
m_searchResultPage->hide();
this->resizeHeight(68);
});

View File

@ -130,8 +130,22 @@ void BestListModel::appendInfo(const QString &pluginId, const SearchPluginIface:
m_item->m_result_info_list.append(info);
QVector<SearchPluginIface::ResultInfo> result_info_list_tmp;
QVector<QString> plugin_id_list_tmp;
QStringList plugin_order = SearchPluginManager::getInstance()->getPluginIds();
Q_FOREACH (QString plugin, plugin_order) {
QList<PluginInfo> infoList = SearchPluginManager::getInstance()->getPluginIds();
QVector<QString> orders(infoList.length());
for (const PluginInfo& info : infoList) {
if (info.isEnable() and info.order() > 0) {
if (info.order() > orders.size()) {
QVector<QString> tmpVct(info.order() - orders.size());
orders.append(tmpVct);
}
orders[info.order() - 1] = info.name();
}
}
orders.removeAll("");
Q_FOREACH (const QString& plugin, orders) {
if (m_plugin_id_list.contains(plugin)) {
result_info_list_tmp.append(m_item->m_result_info_list.at(m_plugin_id_list.lastIndexOf(plugin)));
plugin_id_list_tmp.append(plugin);
@ -146,6 +160,44 @@ void BestListModel::appendInfo(const QString &pluginId, const SearchPluginIface:
}
void BestListModel::removeInfo(const QString &pluginId)
{
this->beginResetModel();
int index = m_plugin_id_list.lastIndexOf(pluginId);
if (index == -1) {
return;
}
m_item->m_result_info_list.removeAt(index);
m_plugin_id_list.removeAll(pluginId);
this->endResetModel();
Q_EMIT this->itemListChanged(m_item->m_result_info_list.length());
}
void BestListModel::moveInfo(const QString &pluginName, const int pos)
{
this->beginResetModel();
int index = m_plugin_id_list.lastIndexOf(pluginName);
if (index == -1) {
return;
}
m_plugin_id_list.removeAll(pluginName);
if (pos > m_plugin_id_list.size()) {
m_plugin_id_list.append(pluginName);
} else {
m_plugin_id_list.insert(pos - 1, pluginName);
}
SearchPluginIface::ResultInfo info = m_item->m_result_info_list.at(index);
m_item->m_result_info_list.removeAt(index);
if (pos > m_item->m_result_info_list.size()) {
m_item->m_result_info_list.append(info);
} else {
m_item->m_result_info_list.insert(pos - 1, info);
}
this->endResetModel();
}
void BestListModel::startSearch(const QString &keyword)
{
if (!m_item->m_result_info_list.isEmpty()) {

View File

@ -33,6 +33,8 @@ public:
public Q_SLOTS:
void appendInfo(const QString &, const SearchPluginIface::ResultInfo &);
void removeInfo(const QString &);
void moveInfo(const QString &pluginName, const int pos);
void startSearch(const QString &);
Q_SIGNALS:

View File

@ -85,12 +85,24 @@ void UkuiSearchGui::parseCmd(QString msg, bool isPrimary)
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption quitOption(QStringList()<<"q"<<"quit", tr("Quit ukui-search application"));
QCommandLineOption quitOption(QStringList{"q","quit"}, tr("Quit ukui-search application"));
parser.addOption(quitOption);
QCommandLineOption showOption(QStringList()<<"s"<<"show", tr("Show main window"));
QCommandLineOption showOption(QStringList{"s","show"}, tr("Show main window"));
parser.addOption(showOption);
QCommandLineOption unregisterOption("unregister", tr("unregister a plugin with <pluginName>"), "pluginName");
parser.addOption(unregisterOption);
QCommandLineOption registerOption("register", tr("register a plugin with <pluginName>"), "pluginName");
parser.addOption(registerOption);
QCommandLineOption moveOption(QStringList{"m", "move"}, tr("move <pluginName> to the target pos"), "pluginName");
parser.addOption(moveOption);
QCommandLineOption indexOption(QStringList{"i", "index"}, tr("move plugin to <index>"), "index");
parser.addOption(indexOption);
if (isPrimary) {
const QStringList args = QString(msg).split(' ');
parser.process(args);
@ -100,6 +112,21 @@ void UkuiSearchGui::parseCmd(QString msg, bool isPrimary)
if (parser.isSet(quitOption)) {
this->quit();
}
if (parser.isSet(unregisterOption)) {
QString pluginName = parser.value(unregisterOption);
qDebug() << "unregister plugin:" << pluginName << SearchPluginManager::getInstance()->unregisterPlugin(pluginName);
}
if (parser.isSet(registerOption)) {
qDebug() << parser.values("register");
QString pluginName = parser.value(registerOption);
qDebug() << "register plugin:" << pluginName << SearchPluginManager::getInstance()->reRegisterPlugin(pluginName);
}
if (parser.isSet(moveOption) and parser.isSet(indexOption)) {
QString pluginName = parser.value(moveOption);
int pos = parser.value(indexOption).toInt();
qDebug() << QString("move plugin:%1 to %2").arg(pluginName).arg(pos) << SearchPluginManager::getInstance()->changePluginPos(pluginName, pos);
}
}
else {
if (arguments().count() < 2) {

View File

@ -209,6 +209,16 @@ void BestListView::initConnections()
this->setCurrentIndex(index);
}
});
connect(SearchPluginManager::getInstance(), &SearchPluginManager::unregistered, this, [=] (const QString &plugin) {
QModelIndex index = this->currentIndex();
this->m_model->removeInfo(plugin);
if (index.isValid()) {
this->setCurrentIndex(index);
}
});
connect(SearchPluginManager::getInstance(), &SearchPluginManager::changePos, this, [ = ] (const QString &pluginName, const int index){
this->m_model->moveInfo(pluginName, index);
});
}
BestListWidget::BestListWidget(QWidget *parent) : QWidget(parent)

View File

@ -18,10 +18,10 @@ AppSearchPlugin::AppSearchPlugin(QObject *parent) : QThread(parent), m_appSearch
// m_pool.setExpiryTimeout(1000);
initDetailPage();
m_timer = new QTimer(this);
m_timer = new QTimer;
m_timer->setInterval(3000);
m_timer->moveToThread(this);
connect(this, SIGNAL(startTimer), m_timer, SLOT(start()));
connect(this, SIGNAL(startTimer()), m_timer, SLOT(start()));
connect(this, &AppSearchPlugin::stopTimer, m_timer, &QTimer::stop);
connect(m_timer, &QTimer::timeout, this, [ & ]{
qWarning() << "The app-search thread stopped because of timeout.";
@ -63,6 +63,16 @@ AppSearchPlugin::AppSearchPlugin(QObject *parent) : QThread(parent), m_appSearch
});
}
AppSearchPlugin::~AppSearchPlugin()
{
this->quit();
this->wait();
if (m_timer) {
delete m_timer;
m_timer = nullptr;
}
}
const QString AppSearchPlugin::name()
{
return "Applications Search";

View File

@ -24,6 +24,7 @@ class LIBSEARCH_EXPORT AppSearchPlugin : public QThread, public SearchPluginIfac
Q_OBJECT
public:
AppSearchPlugin(QObject *parent = nullptr);
~AppSearchPlugin();
PluginType pluginType() {return PluginType::SearchPlugin;}
const QString name();
const QString description();

View File

@ -0,0 +1,37 @@
#ifndef PLUGININFO_H
#define PLUGININFO_H
#include <QString>
namespace UkuiSearch {
class PluginInfo
{
public:
explicit PluginInfo(QString name, bool enable, int order, bool isFixed, bool isExternal, QString path = QString())
: m_name(name),
m_enable(enable),
m_order(order),
m_isFixed(isFixed),
m_isExternal(isExternal),
m_path(path) {}
QString name() const {return m_name;}
int order() const {return m_order;}
bool isEnable() const {return m_enable;}
bool isFixed() const {return m_isFixed;}
bool isExternal() const {return m_isExternal;}
QString path() const {return m_path;}
private:
QString m_name;
QString m_path;
int m_order;
bool m_enable;
bool m_isExternal;
bool m_isFixed;
};
}
#endif // PLUGININFO_H

View File

@ -58,7 +58,9 @@ PluginManager::PluginManager(QObject *parent) : QObject(parent)
switch (piface->pluginType()) {
case PluginInterface::PluginType::SearchPlugin: {
auto p = dynamic_cast<SearchPluginIface *>(plugin);
SearchPluginManager::getInstance()->registerPlugin(p);
if (!SearchPluginManager::getInstance()->registerExternalPlugin(p, pluginsDir.absoluteFilePath(fileName))) {
m_hash.erase(m_hash.find(piface->name()));
}
break;
}
case PluginInterface::PluginType::SearchTaskPlugin: {

View File

@ -1,6 +1,7 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/plugin-info.h \
$$PWD/search-plugin-manager.h \
$$PWD/plugin-manager.h \
$$PWD/search-task-plugin-manager.h

View File

@ -7,30 +7,383 @@
#include "web-search-plugin.h"
#include "mail-search-plugin.h"
#define PLUGIN_ORDER_SETTINGS QDir::homePath() + "/.config/org.ukui/ukui-search/ukui-search-plugin-order.conf"
#define PLUGINS_INFO_GROUP "PluginsInfo"
#define EXTERNAL_PLUGINS_GROUP "ExternalPlugins"
#define PLUGIN_NAME_VALUE "PluginName"
#define PLUGIN_ORDER_VALUE "Order"
#define PLUGIN_ENABLE_VALUE "Enable"
#define PLUGIN_EXTERNAL_VALUE "External"
#define PLUGIN_PATH_VALUE "Path"
#define PLUGIN_FIX_VALUE "FixPos"
using namespace UkuiSearch;
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));
registerPlugin(new FileContengSearchPlugin(this));
initOrderSettings();
registerPlugin(new AppSearchPlugin);
registerPlugin(new NoteSearchPlugin);
registerPlugin(new SettingsSearchPlugin);
registerPlugin(new DirSearchPlugin);
registerPlugin(new FileSearchPlugin);
registerPlugin(new FileContengSearchPlugin);
// registerPlugin(new MailSearchPlugin(this));
registerPlugin(new WebSearchPlugin(this));
registerPlugin(new WebSearchPlugin);
}
bool SearchPluginManager::registerPlugin(UkuiSearch::SearchPluginIface *plugin)
{
if (m_map.end() != m_map.find(plugin->name())){
return false;
bool res(false);
if (m_map.end() != m_map.find(plugin->name())) {
qWarning() << "the plugin:" << plugin->name() << "has been registered.";
return res;
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
QStringList plugins = m_orderSettings->childGroups();
if (plugins.contains(plugin->name())) {
m_orderSettings->beginGroup(plugin->name());
if (!m_orderSettings->value(PLUGIN_ENABLE_VALUE).toBool()) {
qWarning() << "plugin: " << plugin->name() << "is not available now.";
} else {
m_map[plugin->name()] = plugin;
qDebug() << "register search plugin: " << plugin->name();
res = true;
}
m_orderSettings->endGroup();
} else {
qWarning() << "Fail to register, can not find plugin:" << plugin->name() << "in config file";
}
m_orderSettings->endGroup();
if (!res) {
qWarning() << "Can not register plugin:" << plugin->name();
if (plugin) {
delete plugin;
plugin = nullptr;
}
}
return res;
}
bool SearchPluginManager::registerExternalPlugin(SearchPluginIface *plugin, const QString &path)
{
//TODO: external plugin need a life cycle management!
bool res(false);
if (m_map.end() != m_map.find(plugin->name())) {
qWarning() << "the plugin:" << plugin->name() << "has been registered.";
return res;
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
QStringList plugins = m_orderSettings->childGroups();
if (!plugins.contains(plugin->name())) {
int pluginOrder = plugins.length() + 1;
//网页搜索为最后一项
if (plugins.contains("Web Page")) {
m_orderSettings->beginGroup("Web Page");
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, pluginOrder);
m_orderSettings->endGroup();
pluginOrder--;
}
//更新配置文件
m_orderSettings->beginGroup(plugin->name());
m_orderSettings->setValue(PLUGIN_PATH_VALUE, path);
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, pluginOrder);
m_orderSettings->setValue(PLUGIN_ENABLE_VALUE, true);
m_orderSettings->setValue(PLUGIN_EXTERNAL_VALUE, true);
m_orderSettings->setValue(PLUGIN_FIX_VALUE, false);
m_orderSettings->endGroup();
}
if (m_orderSettings->value(plugin->name() + QString("/") + PLUGIN_ENABLE_VALUE).toBool()) {
m_map[plugin->name()] = plugin;
qDebug() << "register search plugin: " << path;
res = true;
} else {
qWarning() << "Plugin is not available.Fail to register: " << plugin->name();
}
m_orderSettings->endGroup();
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
m_orderSettings->setValue(path, plugin->name());
m_orderSettings->endGroup();
return res;
}
bool SearchPluginManager::reRegisterPlugin(const QString &pluginName)
{
QString name;
if (pluginName == "Web") {
name = pluginName + " Page";
} else if (pluginName == "Content") {
name = "File " + name + " Search";
} else if (pluginName.contains(".so")) {
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
name = m_orderSettings->value(pluginName).toString();
m_orderSettings->endGroup();
} else {
name = pluginName + " Search";
}
bool res(false);
if (m_map.end() == m_map.find(name)) {
bool isExternal(false);
QVariant value = m_orderSettings->value(PLUGINS_INFO_GROUP + QString("/") + name);
if (value.isNull()) {
isExternal = true;
} else {
isExternal = value.toBool();
}
if (pluginName == "Applications") {
reRegisterPlugin(new AppSearchPlugin, isExternal);
res = true;
} else if (pluginName == "Note") {
reRegisterPlugin(new NoteSearchPlugin, isExternal);
res = true;
} else if (pluginName == "Settings") {
reRegisterPlugin(new SettingsSearchPlugin, isExternal);
res = true;
} else if (pluginName == "Dir") {
reRegisterPlugin(new DirSearchPlugin, isExternal);
res = true;
} else if (pluginName == "File") {
reRegisterPlugin(new FileSearchPlugin, isExternal);
res = true;
} else if (pluginName == "Content") {
reRegisterPlugin(new FileContengSearchPlugin, isExternal);
res = true;
} else if (pluginName == "Web") {
reRegisterPlugin(new WebSearchPlugin, isExternal);
res = true;
} else if (pluginName.contains(".so")) {
//外部插件pluginName为so文件全路径
QPluginLoader loader(pluginName);
// version check
QString type = loader.metaData().value("MetaData").toObject().value("type").toString();
QString version = loader.metaData().value("MetaData").toObject().value("version").toString();
if(type == "SEARCH_PLUGIN" and version == SEARCH_PLUGIN_IFACE_VERSION) {
QObject *plugin = loader.instance();
if (plugin) {
auto externalPlugin = dynamic_cast<SearchPluginIface *>(plugin);
reRegisterPlugin(externalPlugin, isExternal, pluginName);
res = true;
}
}
} else {
return res;
}
}
return res;
}
bool SearchPluginManager::reRegisterPlugin(SearchPluginIface *plugin, bool isExternal, const QString &externalPluginPath)
{
bool res(false);
if (m_map.end() != m_map.find(plugin->name())) {
qWarning() << "plugin " << plugin->name() << "has been registered.";
if (plugin) {
delete plugin;
plugin = nullptr;
}
return res;
}
m_map[plugin->name()] = plugin;
qDebug() << "register search plugin: " << plugin->name();
m_plugin_order[m_plugin_order.size()] = plugin->name();//按注册顺序绑定优先级
if (isExternal) {
if (!externalPluginPath.isEmpty()) {
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
m_orderSettings->setValue(externalPluginPath, plugin->name());
m_orderSettings->endGroup();
} else {
qWarning() << QString("Can not identify external plugin %1 through a empty path!").arg(plugin->name());
}
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
QStringList plugins = m_orderSettings->childGroups();
if (plugins.contains(plugin->name())) {
m_orderSettings->beginGroup(plugin->name());
m_orderSettings->setValue(PLUGIN_ENABLE_VALUE, true);
m_orderSettings->endGroup();
res = true;
} else {
qWarning() << "Fail to re-register plugin" << plugin->name() << " Conf file error!";
}
m_orderSettings->endGroup();
if (!res) {
if (plugin) {
delete plugin;
plugin = nullptr;
}
} else {
Q_EMIT this->reRegistered(plugin->name());
}
return res;
}
bool SearchPluginManager::unregisterPlugin(const QString &pluginName)
{
//用来测试命令行的字符串拼接
QString name = pluginName + " Search";
if (pluginName == "Web") {
name = pluginName + " Page";
} else if (pluginName == "Content") {
name = "File " + name + " Search";
}
//外部插件pluginName是so文件全路径
QString externalPluginPath;
if (pluginName.contains(".so")) {
externalPluginPath = pluginName;
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
name = m_orderSettings->value(externalPluginPath).toString();
m_orderSettings->endGroup();
}
if (m_map.end() == m_map.find(name)) {
qWarning() << "plugin:" << name << "has not been registered.";
return false;
}
Q_EMIT this->unregistered(name);
if (m_map[name]) {
m_map[name]->stopSearch();
delete m_map[name];
m_map[name] = nullptr;
}
m_map.erase(m_map.find(name));
if (!externalPluginPath.isEmpty()) {
m_orderSettings->remove(EXTERNAL_PLUGINS_GROUP + QString("/") + externalPluginPath);
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP + QString("/") + name);
m_orderSettings->setValue(PLUGIN_ENABLE_VALUE, false);
m_orderSettings->endGroup();
return true;
/*
// m_plugin_order.clear();
// int i = 0;
// for (auto iter = m_map.cbegin(); iter != m_map.cend(); iter++) {
// m_plugin_order[i] = iter->first;
// i++;
// }
// std::map<int, QString>::iterator iter;
// bool removed(false);
// for (iter = m_plugin_order.begin(); iter != m_plugin_order.end();) {
// if (iter->second == name) {
// iter = m_plugin_order.erase(iter);
// removed = true;
// } else if (removed) {
// m_plugin_order[iter->first - 1] = iter->second;
// iter = m_plugin_order.erase(iter);
// } else {
// iter++;
// }
// }
// return true;
*/
}
bool SearchPluginManager::changePluginPos(const QString &pluginName, int pos)
{
bool res(false);
if (pos < 1) {
qWarning() << "Invalid destination position!";
return res;
}
//用来测试命令行的字符串拼接
QString name = pluginName + " Search";
if (pluginName == "Web") {
name = pluginName + " Page";
} else if (pluginName == "Content") {
name = "File " + name + " Search";
} else if (pluginName.contains(".so")) {
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
name = m_orderSettings->value(pluginName).toString();
m_orderSettings->endGroup();
}
if (m_map.find(name) == m_map.end()) {
qWarning() << "Fail to change pos, plugin" << name << "has not been registered.";
return res;
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
QStringList plugins = m_orderSettings->childGroups();
int oldOrder = m_orderSettings->value(name + QString("/") + PLUGIN_ORDER_VALUE).toInt();
if (oldOrder < 1) {
qWarning() << "Invalid order value of " << name;
m_orderSettings->endGroup();
return res;
}
if (oldOrder == pos) {
qWarning() << "Plugin's position has not been changed";
m_orderSettings->endGroup();
return res;
}
for (const QString& orderName : plugins) {
m_orderSettings->beginGroup(orderName);
if (orderName == name) {
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, pos);
} else {
int orderValue = m_orderSettings->value(PLUGIN_ORDER_VALUE).toInt();
if (oldOrder > pos and orderValue >= pos and orderValue < oldOrder) {
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, orderValue + 1);
} else if (oldOrder < pos and orderValue > oldOrder and orderValue <= pos) {
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, orderValue - 1);
}
}
m_orderSettings->endGroup();
}
m_orderSettings->endGroup();
Q_EMIT this->changePos(name, pos);
return res;
}
bool SearchPluginManager::unregisterPlugin(SearchPluginIface *plugin, bool isExternal, const QString &externalPluginPath)
{
bool res(false);
if (m_map.end() == m_map.find(plugin->name())) {
qWarning() << "plugin:" << plugin->name() << "has not been registered.";
return res;
}
Q_EMIT this->unregistered(plugin->name());
if (m_map[plugin->name()]) {
m_map[plugin->name()]->stopSearch();
delete m_map[plugin->name()];
m_map[plugin->name()] = nullptr;
}
m_map.erase(m_map.find(plugin->name()));
if (isExternal) {
if (!externalPluginPath.isEmpty()) {
m_orderSettings->beginGroup(EXTERNAL_PLUGINS_GROUP);
m_orderSettings->remove(externalPluginPath);
m_orderSettings->endGroup();
res = true;
} else {
qWarning() << "Fail to unregister, can not identify the plugin through a empty path.";
}
}
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP + QString("/") + plugin->name());
m_orderSettings->setValue(PLUGIN_ENABLE_VALUE, false);
m_orderSettings->endGroup();
return res;
}
SearchPluginManager *SearchPluginManager::getInstance()
@ -41,13 +394,26 @@ SearchPluginManager *SearchPluginManager::getInstance()
return global_instance;
}
const QStringList SearchPluginManager::getPluginIds()
const QList<PluginInfo> SearchPluginManager::getPluginIds()
{
QStringList list;
for (auto i = m_plugin_order.begin(); i != m_plugin_order.end(); i++) {
list.append(m_plugin_order[(*i).first]);//根据优先级返回plugin ID
QList<PluginInfo> infoList;
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
QStringList plugins = m_orderSettings->childGroups();
for (const QString& pluginName : plugins) {
if (m_map.find(pluginName) != m_map.end()) {
m_orderSettings->beginGroup(pluginName);
PluginInfo info(pluginName,
m_orderSettings->value(PLUGIN_ENABLE_VALUE).toBool(),
m_orderSettings->value(PLUGIN_ORDER_VALUE).toInt(),
m_orderSettings->value(PLUGIN_FIX_VALUE).toBool(),
m_orderSettings->value(PLUGIN_EXTERNAL_VALUE).toBool(),
m_orderSettings->value(PLUGIN_PATH_VALUE).toString());
m_orderSettings->endGroup();
infoList.append(info);
}
}
return list;
m_orderSettings->endGroup();
return infoList;
}
SearchPluginIface *SearchPluginManager::getPlugin(const QString &pluginId)
@ -62,5 +428,35 @@ void SearchPluginManager::close()
SearchPluginManager::~SearchPluginManager()
{
for (auto iter = m_map.begin(); iter != m_map.end();) {
if (iter->second) {
delete iter->second;
iter->second = nullptr;
}
}
m_map.clear();
}
void SearchPluginManager::initOrderSettings()
{
m_orderSettings = new QSettings(PLUGIN_ORDER_SETTINGS, QSettings::IniFormat, this);
m_orderSettings->beginGroup(PLUGINS_INFO_GROUP);
if (m_orderSettings->childGroups().isEmpty()) {
bool isFixed(false);
for (int i = 0; i < m_defaultPluginOrder.size(); i++) {
QString pluginName = m_defaultPluginOrder.at(i);
//默认Web Page固定位置
if (pluginName == "Web Page") {
isFixed = true;
}
m_orderSettings->beginGroup(pluginName);
m_orderSettings->setValue(PLUGIN_ORDER_VALUE, i + 1);
m_orderSettings->setValue(PLUGIN_ENABLE_VALUE, true);
m_orderSettings->setValue(PLUGIN_EXTERNAL_VALUE, false);
m_orderSettings->setValue(PLUGIN_FIX_VALUE, isFixed);
m_orderSettings->endGroup();
}
}
m_orderSettings->endGroup();
}

View File

@ -2,28 +2,58 @@
#define SEARCHPLUGINFACTORY_H
#include <QObject>
#include <QSettings>
#include "search-plugin-iface.h"
#include "plugin-info.h"
namespace UkuiSearch {
class SearchPluginManager : public QObject
{
Q_OBJECT
QStringList m_defaultPluginOrder = {
"Applications Search",
"Note Search",
"Settings Search",
"Dir Search",
"File Search",
"File Content Search",
"Web Page"
};
public:
bool registerPlugin(SearchPluginIface *plugin);
bool registerExternalPlugin(SearchPluginIface *plugin, const QString &path);
bool reRegisterPlugin(SearchPluginIface *plugin, bool isExternal, const QString &externalPluginPath = QString());
bool unregisterPlugin(SearchPluginIface *plugin, bool isExternal, const QString &externalPluginPath = QString());
//测试用接口
bool reRegisterPlugin(const QString &pluginName);
bool unregisterPlugin(const QString &pluginName);
bool changePluginPos(const QString &pluginName, int pos);
static SearchPluginManager *getInstance();
const QStringList getPluginIds();
const QList<PluginInfo> getPluginIds();
SearchPluginIface *getPlugin(const QString &pluginId);
void close();
private:
std::map<QString, SearchPluginIface*> m_map;
std::map<int, QString> m_plugin_order;//绑定plugin ID和优先级
explicit SearchPluginManager(QObject *parent = nullptr);
~SearchPluginManager();
void initOrderSettings();
std::map<QString, SearchPluginIface*> m_map;
std::map<int, QString> m_plugin_order;//绑定plugin ID和优先级
QSettings *m_orderSettings = nullptr;
QStringList m_externalPlugins;
Q_SIGNALS:
void unregistered(const QString& pluginName);
void reRegistered(const QString& pluginName);
void changePos(const QString& pluginName, int index);
};
}