1.插件接口新增数据更新模式选项,2.增加应用搜索插件

This commit is contained in:
hewenfei 2023-02-27 09:36:25 +08:00
parent c0b2e23229
commit 8766051c28
8 changed files with 330 additions and 9 deletions

View File

@ -90,14 +90,15 @@ set(SOURCE_FILES
src/appdata/app-icon-provider.cpp src/appdata/app-icon-provider.h src/appdata/app-icon-provider.cpp src/appdata/app-icon-provider.h
src/appdata/data-provider-manager.cpp src/appdata/data-provider-manager.h src/appdata/data-provider-manager.cpp src/appdata/data-provider-manager.h
src/appdata/plugin/all-app-data-provider.cpp src/appdata/plugin/all-app-data-provider.h src/appdata/plugin/all-app-data-provider.cpp src/appdata/plugin/all-app-data-provider.h
src/appdata/plugin/app-search-plugin.cpp src/appdata/plugin/app-search-plugin.h
src/extension/menu-extension-iface.h src/extension/menu-extension-iface.h
src/extension/menu-extension.cpp src/extension/menu-extension.h src/extension/menu-extension.cpp src/extension/menu-extension.h
src/extension/extensions/folder-extension.cpp src/extension/extensions/folder-extension.h src/extension/extensions/folder-extension.cpp src/extension/extensions/folder-extension.h
src/extension/extensions/recent-file-extension.cpp src/extension/extensions/recent-file-extension.h src/extension/extensions/recent-file-extension.cpp src/extension/extensions/recent-file-extension.h
src/extension/extensions/favorite-extension.cpp src/extension/extensions/favorite-extension.h
src/utils/app-page-header-utils.cpp src/utils/app-page-header-utils.h src/utils/app-page-header-utils.cpp src/utils/app-page-header-utils.h
src/utils/power-button.cpp src/utils/power-button.h src/utils/power-button.cpp src/utils/power-button.h
src/utils/app-manager.cpp src/utils/app-manager.h src/utils/app-manager.cpp src/utils/app-manager.h
src/extension/extensions/favorite-extension.cpp src/extension/extensions/favorite-extension.h
) )
# qrc # qrc

View File

@ -18,6 +18,7 @@
#include "data-provider-manager.h" #include "data-provider-manager.h"
#include "plugin/all-app-data-provider.h" #include "plugin/all-app-data-provider.h"
#include "plugin/app-search-plugin.h"
namespace UkuiMenu { namespace UkuiMenu {
@ -33,6 +34,7 @@ DataProviderManager *DataProviderManager::instance()
DataProviderManager::DataProviderManager() DataProviderManager::DataProviderManager()
{ {
qRegisterMetaType<DataUpdateMode::Mode>("DataUpdateMode::Mode");
m_worker.start(); m_worker.start();
initProviders(); initProviders();
} }
@ -42,8 +44,12 @@ void DataProviderManager::initProviders()
auto *allProvider = new AllAppDataProvider; auto *allProvider = new AllAppDataProvider;
registerProvider(allProvider); registerProvider(allProvider);
auto *search = new AppSearchPlugin;
registerProvider(search);
activateProvider(allProvider->id()); activateProvider(allProvider->id());
allProvider->moveToThread(&m_worker); allProvider->moveToThread(&m_worker);
search->moveToThread(&m_worker);
} }
void DataProviderManager::registerProvider(DataProviderPluginIFace *provider) void DataProviderManager::registerProvider(DataProviderPluginIFace *provider)
@ -58,13 +64,14 @@ void DataProviderManager::registerProvider(DataProviderPluginIFace *provider)
} }
m_providers.insert(provider->id(), provider); m_providers.insert(provider->id(), provider);
connect(provider, &AllAppDataProvider::dataChanged, this, [this, provider](const QVector<DataEntity> &data) { connect(provider, &AllAppDataProvider::dataChanged, this,
[this, provider](const QVector<DataEntity> &data, DataUpdateMode::Mode mode, quint32 index) {
//qDebug() << "==DataProviderManager dataChanged:" << provider->name() << QThread::currentThreadId(); //qDebug() << "==DataProviderManager dataChanged:" << provider->name() << QThread::currentThreadId();
if (m_activatedPlugin != provider->id()) { if (m_activatedPlugin != provider->id()) {
return; return;
} }
Q_EMIT dataChanged(data); Q_EMIT dataChanged(data, mode, index);
}); });
} }

View File

@ -55,7 +55,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void pluginChanged(const QString &id, PluginGroup::Group group); void pluginChanged(const QString &id, PluginGroup::Group group);
void dataChanged(QVector<DataEntity> data); void dataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
private: private:
DataProviderManager(); DataProviderManager();

View File

@ -41,6 +41,19 @@ public:
Q_ENUM(Group) Q_ENUM(Group)
}; };
class DataUpdateMode
{
Q_GADGET
public:
enum Mode {
Reset = 0,
Append,
Prepend,
Insert
};
Q_ENUM(Mode)
};
class DataProviderPluginIFace : public QObject class DataProviderPluginIFace : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -69,9 +82,11 @@ Q_SIGNALS:
/** /**
* *
*/ */
void dataChanged(QVector<DataEntity> newData); void dataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode = DataUpdateMode::Reset, quint32 index = 0);
}; };
} // UkuiMenu } // UkuiMenu
//Q_DECLARE_METATYPE(UkuiMenu::DataUpdateMode::Mode)
#endif //UKUI_MENU_DATA_PROVIDER_PLUGIN_IFACE_H #endif //UKUI_MENU_DATA_PROVIDER_PLUGIN_IFACE_H

View File

@ -0,0 +1,183 @@
/*
* Copyright (C) 2023, 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/>.
*
*/
#include "app-search-plugin.h"
#include <UkuiSearchTask>
namespace UkuiMenu {
class AppSearchPluginPrivate : public QThread
{
Q_OBJECT
public:
AppSearchPluginPrivate();
Q_SIGNALS:
void searchedOne(DataEntity app);
public Q_SLOTS:
void startSearch(QString &keyword);
void stopSearch();
protected:
void run() override;
private:
size_t m_searchId{0};
QTimer *m_timer{nullptr};
UkuiSearch::UkuiSearchTask *m_appSearchTask{nullptr};
UkuiSearch::DataQueue<UkuiSearch::ResultItem> *m_dataQueue{nullptr};
};
AppSearchPluginPrivate::AppSearchPluginPrivate() : QThread(nullptr)
{
m_appSearchTask = new UkuiSearch::UkuiSearchTask(this);
m_dataQueue = m_appSearchTask->init();
m_appSearchTask->initSearchPlugin(UkuiSearch::SearchType::Application);
m_appSearchTask->setSearchOnlineApps(false);
m_appSearchTask->setResultDataType(UkuiSearch::SearchType::Application,
UkuiSearch::ApplicationDesktopPath | UkuiSearch::ApplicationLocalName | UkuiSearch::ApplicationIconName);
m_timer = new QTimer;
m_timer->setInterval(3000);
m_timer->moveToThread(this);
}
void AppSearchPluginPrivate::startSearch(QString &keyword)
{
if (!this->isRunning()) {
this->start();
}
m_appSearchTask->clearKeyWords();
m_appSearchTask->addKeyword(keyword);
m_searchId = m_appSearchTask->startSearch(UkuiSearch::SearchType::Application);
}
void AppSearchPluginPrivate::stopSearch()
{
m_appSearchTask->stop();
this->requestInterruption();
}
void AppSearchPluginPrivate::run()
{
while (!isInterruptionRequested()) {
UkuiSearch::ResultItem result = m_dataQueue->tryDequeue();
if(result.getSearchId() == 0 && result.getItemKey().isEmpty() && result.getExtral().isEmpty()) {
if(!m_timer->isActive()) {
// 超时退出
m_timer->start();
}
msleep(100);
} else {
m_timer->stop();
if (result.getSearchId() == m_searchId) {
QVariantList list = result.getExtral();
DataEntity app;
app.setType(DataType::Normal);
app.setId(list.at(0).toString());
app.setName(list.at(1).toString());
app.setIcon("image://appicon/" + list.at(2).toString());
Q_EMIT this->searchedOne(app);
}
}
if(m_timer->isActive() && m_timer->remainingTime() < 0.01 && m_dataQueue->isEmpty()) {
this->requestInterruption();
}
}
}
// ========AppSearchPlugin======== //
AppSearchPlugin::AppSearchPlugin()
{
m_searchPluginPrivate = new AppSearchPluginPrivate;
connect(m_searchPluginPrivate, &AppSearchPluginPrivate::searchedOne, this, &AppSearchPlugin::onSearchedOne);
}
int AppSearchPlugin::index()
{
return 0;
}
QString AppSearchPlugin::id()
{
return "search";
}
QString AppSearchPlugin::name()
{
return tr("Search");
}
QString AppSearchPlugin::icon()
{
return "image://appicon/search-symbolic";
}
QString AppSearchPlugin::title()
{
return "";
}
PluginGroup::Group AppSearchPlugin::group()
{
return PluginGroup::Button;
}
QVector<DataEntity> AppSearchPlugin::data()
{
return {};
}
void AppSearchPlugin::forceUpdate()
{
}
void AppSearchPlugin::forceUpdate(QString &key)
{
// qDebug() << "==AppSearchPlugin key:" << key;
Q_EMIT dataChanged({});
if (key.isEmpty()) {
return;
}
m_searchPluginPrivate->startSearch(key);
}
void AppSearchPlugin::onSearchedOne(const DataEntity &app)
{
Q_EMIT dataChanged({1, app}, DataUpdateMode::Append);
}
AppSearchPlugin::~AppSearchPlugin()
{
m_searchPluginPrivate->stopSearch();
m_searchPluginPrivate->quit();
m_searchPluginPrivate->wait();
m_searchPluginPrivate->deleteLater();
}
} // UkuiMenu
#include "app-search-plugin.moc"

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2023, 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/>.
*
*/
#ifndef UKUI_MENU_APP_SEARCH_PLUGIN_H
#define UKUI_MENU_APP_SEARCH_PLUGIN_H
#include "data-provider-plugin-iface.h"
namespace UkuiMenu {
class AppSearchPluginPrivate;
class AppSearchPlugin : public DataProviderPluginIFace
{
Q_OBJECT
public:
AppSearchPlugin();
~AppSearchPlugin() override;
int index() override;
QString id() override;
QString name() override;
QString icon() override;
QString title() override;
PluginGroup::Group group() override;
QVector<DataEntity> data() override;
void forceUpdate() override;
void forceUpdate(QString &key) override;
private Q_SLOTS:
void onSearchedOne(const DataEntity &app);
private:
AppSearchPluginPrivate *m_searchPluginPrivate{nullptr};
};
} // UkuiMenu
#endif //UKUI_MENU_APP_SEARCH_PLUGIN_H

View File

@ -18,7 +18,6 @@
#include "model.h" #include "model.h"
#include "app-manager.h" #include "app-manager.h"
#include "data-provider-manager.h"
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@ -101,14 +100,69 @@ void AppModel::appClicked(const int &index)
void AppModel::reloadPluginData() void AppModel::reloadPluginData()
{ {
onPluginDataChanged(DataProviderManager::instance()->data()); QVector<DataEntity> data = DataProviderManager::instance()->data();
resetModel(data);
} }
void AppModel::onPluginDataChanged(QVector<DataEntity> data) void AppModel::onPluginDataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index)
{
switch (mode) {
default:
case DataUpdateMode::Reset: {
resetModel(data);
break;
}
case DataUpdateMode::Append: {
appendData(data);
break;
}
case DataUpdateMode::Prepend: {
prependData(data);
break;
}
case DataUpdateMode::Insert: {
insertData(data, static_cast<int>(index));
break;
}
}
}
void AppModel::resetModel(QVector<DataEntity> &data)
{ {
Q_EMIT beginResetModel(); Q_EMIT beginResetModel();
m_apps.swap(data); m_apps.swap(data);
Q_EMIT endResetModel(); Q_EMIT endResetModel();
} }
void AppModel::appendData(QVector<DataEntity> &data)
{
Q_EMIT beginInsertRows(QModelIndex(), m_apps.size(), (m_apps.size() + data.size() - 1));
m_apps.append(data);
Q_EMIT endInsertRows();
}
void AppModel::prependData(QVector<DataEntity> &data)
{
Q_EMIT beginInsertRows(QModelIndex(), 0, data.size() - 1);
data.append(m_apps);
m_apps.swap(data);
Q_EMIT endInsertRows();
}
void AppModel::insertData(QVector<DataEntity> &data, int index)
{
if (index < 0 || (!m_apps.isEmpty() && index >= m_apps.size())) {
return;
}
Q_EMIT beginInsertRows(QModelIndex(), index, index + data.size() - 1);
for (const auto &item : data) {
m_apps.insert(index, item);
++index;
}
Q_EMIT endInsertRows();
}
} // UkuiMenu } // UkuiMenu

View File

@ -23,6 +23,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include "commons.h" #include "commons.h"
#include "data-provider-manager.h"
namespace UkuiMenu { namespace UkuiMenu {
@ -40,9 +41,15 @@ public:
Q_INVOKABLE void appClicked(const int &index); Q_INVOKABLE void appClicked(const int &index);
private Q_SLOTS: private Q_SLOTS:
void onPluginDataChanged(QVector<DataEntity> data); void onPluginDataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
void reloadPluginData(); void reloadPluginData();
private:
void resetModel(QVector<DataEntity> &data);
void appendData(QVector<DataEntity> &data);
void prependData(QVector<DataEntity> &data);
void insertData(QVector<DataEntity> &data, int index);
private: private:
QVector<DataEntity> m_apps; QVector<DataEntity> m_apps;
}; };