通过ukui-search接口实现获取应用数据功能

This commit is contained in:
hewenfei 2023-01-09 17:27:04 +08:00
parent 4832564558
commit 5098dce1cc
5 changed files with 486 additions and 24 deletions

View File

@ -27,7 +27,7 @@ find_package(PkgConfig REQUIRED)
set(UKUI_MENU_EXTERNAL_LIBS "") set(UKUI_MENU_EXTERNAL_LIBS "")
# glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper # glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper
set(UKUI_MENU_PC_PKGS glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper) set(UKUI_MENU_PC_PKGS glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper ukui-search)
foreach(external_lib IN ITEMS ${UKUI_MENU_PC_PKGS}) foreach(external_lib IN ITEMS ${UKUI_MENU_PC_PKGS})
pkg_check_modules(${external_lib} REQUIRED ${external_lib}) pkg_check_modules(${external_lib} REQUIRED ${external_lib})
@ -87,6 +87,7 @@ set(SOURCE_FILES
src/extension/menu-extension.cpp src/extension/menu-extension.h src/extension/menu-extension.cpp src/extension/menu-extension.h
src/extension/menu-extension-iface.h src/extension/menu-extension-iface.h
src/appdata/data-provider-plugin-iface.h src/appdata/data-provider-plugin-iface.h
src/appdata/app-data-manager.cpp src/appdata/app-data-manager.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
) )

View File

@ -0,0 +1,258 @@
/*
* 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-data-manager.h"
#include <UkuiSearchAppInfoTable>
#define APP_ICON_PREFIX "image://appicon/"
namespace UkuiMenu {
class AppDataWorker : public QObject
{
Q_OBJECT
public:
explicit AppDataWorker(AppDataManager *appManager = nullptr);
Q_SIGNALS:
void appDataChanged();
void favoriteAppChanged();
void appDataBaseOpenFailed();
private Q_SLOTS:
void initAppData();
void onAppAdded(const QVector<UkuiSearch::AppInfoResult> &infos);
void onAppUpdated(QVector<UkuiSearch::AppInfoResult> infos);
void onAppDeleted(QStringList infos);
private:
void updateFavoriteApps();
private:
AppDataManager *m_appManager{nullptr};
UkuiSearch::AppInfoTable *m_appInfoTable = nullptr;
};
AppDataWorker::AppDataWorker(AppDataManager *appManager) : QObject(nullptr), m_appManager(appManager)
{
m_appInfoTable = new UkuiSearch::AppInfoTable(this);
if (!m_appInfoTable || !m_appManager) {
return;
}
initAppData();
connect(m_appInfoTable, &UkuiSearch::AppInfoTable::appDBItems2BAdd, this, &AppDataWorker::onAppAdded);
connect(m_appInfoTable, &UkuiSearch::AppInfoTable::appDBItems2BUpdate, this, &AppDataWorker::onAppUpdated);
connect(m_appInfoTable, &UkuiSearch::AppInfoTable::appDBItems2BDelete, this, &AppDataWorker::onAppDeleted);
connect(m_appInfoTable, &UkuiSearch::AppInfoTable::DBOpenFailed, this, &AppDataWorker::appDataBaseOpenFailed);
}
void AppDataWorker::initAppData()
{
QVector<UkuiSearch::AppInfoResult> appInfos;
if (!m_appInfoTable->getAppInfoResults(appInfos)) {
return;
}
if (appInfos.isEmpty()) {
return;
}
// parse app-info
QVector<DataEntity> normalApps;
for (const auto &info : appInfos) {
DataEntity app;
app.setTop(info.top);
app.setLock(info.lock == 1);
app.setFavorite(info.favorite);
app.setLaunchTimes(info.launchTimes);
app.setId(info.desktopPath);
app.setIcon(APP_ICON_PREFIX + info.iconName);
app.setName(info.appLocalName);
app.setCategory(info.category);
app.setFirstLetter(info.firstLetter);
normalApps.append(app);
}
{
QMutexLocker locker(&m_appManager->m_mutex);
m_appManager->m_normalApps.swap(normalApps);
}
updateFavoriteApps();
}
void AppDataWorker::updateFavoriteApps()
{
QVector<DataEntity> favoriteApps;
for (const auto &app : m_appManager->m_normalApps) {
if (app.favorite() > 0) {
favoriteApps.append(app);
}
}
if (favoriteApps.isEmpty()) {
return;
}
// 排序搜藏夹数据
std::sort(favoriteApps.begin(), favoriteApps.end(), [](const DataEntity& a, const DataEntity &b) {
return a.favorite() < b.favorite();
});
{
QMutexLocker locker(&m_appManager->m_mutex);
m_appManager->m_favoriteApps.swap(favoriteApps);
}
Q_EMIT favoriteAppChanged();
}
void AppDataWorker::onAppAdded(const QVector<UkuiSearch::AppInfoResult> &infos)
{
if (infos.isEmpty()) {
return;
}
{
QMutexLocker locker(&m_appManager->m_mutex);
for (const auto &info: infos) {
DataEntity app;
app.setTop(info.top);
app.setLock(info.lock == 1);
app.setFavorite(info.favorite);
app.setLaunchTimes(info.launchTimes);
app.setId(info.desktopPath);
app.setIcon(APP_ICON_PREFIX + info.iconName);
app.setName(info.appLocalName);
app.setCategory(info.category);
app.setFirstLetter(info.firstLetter);
m_appManager->m_normalApps.append(app);
}
}
Q_EMIT appDataChanged();
}
void AppDataWorker::onAppUpdated(QVector<UkuiSearch::AppInfoResult> infos)
{
if (infos.isEmpty()) {
return;
}
for (auto &app : m_appManager->m_normalApps) {
if (infos.isEmpty()) {
break;
}
for (int i = 0; i < infos.size(); ++i) {
const UkuiSearch::AppInfoResult &info = infos.at(i);
if (info.desktopPath == app.id()) {
QMutexLocker locker(&m_appManager->m_mutex);
app.setTop(info.top);
app.setLock(info.lock == 1);
app.setFavorite(info.favorite);
app.setLaunchTimes(info.launchTimes);
app.setIcon(APP_ICON_PREFIX + info.iconName);
app.setName(info.appLocalName);
app.setCategory(info.category);
app.setFirstLetter(info.firstLetter);
infos.remove(i);
break;
}
}
}
Q_EMIT appDataChanged();
updateFavoriteApps();
}
void AppDataWorker::onAppDeleted(QStringList infos)
{
if (infos.isEmpty()) {
return;
}
QVector<DataEntity>::iterator appIterator = m_appManager->m_normalApps.begin();
for (; appIterator != m_appManager->m_normalApps.end(); ++appIterator) {
if (infos.isEmpty()) {
break;
}
QStringList::iterator infoIterator = infos.begin();
for (; infoIterator != infos.end(); ++infoIterator) {
if ((*appIterator).id() == *infoIterator) {
QMutexLocker locker(&m_appManager->m_mutex);
m_appManager->m_normalApps.erase(appIterator);
infos.erase(infoIterator);
break;
}
}
}
Q_EMIT appDataChanged();
updateFavoriteApps();
}
// ===== AppDataManager ===== //
AppDataManager *AppDataManager::instance()
{
static AppDataManager appDataManager;
return &appDataManager;
}
AppDataManager::AppDataManager()
{
AppDataWorker *appDataWorker = new AppDataWorker(this);
appDataWorker->moveToThread(&m_workerThread);
connect(&m_workerThread, &QThread::finished, appDataWorker, &QObject::deleteLater);
connect(appDataWorker, &AppDataWorker::appDataChanged, this, &AppDataManager::appDataChanged);
connect(appDataWorker, &AppDataWorker::favoriteAppChanged, this, &AppDataManager::favoriteAppChanged);
m_workerThread.start();
}
AppDataManager::~AppDataManager()
{
m_workerThread.quit();
m_workerThread.wait();
}
QVector<DataEntity> AppDataManager::normalApps()
{
QMutexLocker locker(&m_mutex);
return m_normalApps;
}
QVector<DataEntity> AppDataManager::favoriteApps()
{
QMutexLocker locker(&m_mutex);
return m_favoriteApps;
}
} // UkuiMenu
#include "app-data-manager.moc"

View File

@ -0,0 +1,65 @@
/*
* 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_DATA_MANAGER_H
#define UKUI_MENU_APP_DATA_MANAGER_H
#include <QObject>
#include <QVector>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include "commons.h"
namespace UkuiMenu {
class AppDataManager : public QObject
{
friend class AppDataWorker;
Q_OBJECT
public:
static AppDataManager *instance();
~AppDataManager() override;
AppDataManager(const AppDataManager& obj) = delete;
AppDataManager &operator=(const AppDataManager& obj) = delete;
AppDataManager(AppDataManager&& obj) = delete;
AppDataManager &operator=(AppDataManager&& obj) = delete;
QVector<DataEntity> normalApps();
QVector<DataEntity> favoriteApps();
Q_SIGNALS:
void appDataChanged();
void favoriteAppChanged();
private:
AppDataManager();
private:
QMutex m_mutex;
QThread m_workerThread;
QVector<DataEntity> m_normalApps;
QVector<DataEntity> m_favoriteApps;
};
} // UkuiMenu
#endif //UKUI_MENU_APP_DATA_MANAGER_H

View File

@ -20,17 +20,128 @@
#include <utility> #include <utility>
UkuiMenu::DataEntity::DataEntity(const UkuiMenu::DataEntity &obj)
{
m_type = obj.m_type;
m_name = obj.m_name;
m_icon = obj.m_icon;
m_comment = obj.m_comment;
m_extraData = obj.m_extraData;
}
UkuiMenu::DataEntity::DataEntity(UkuiMenu::DataType::Type type, QString name, QString icon, QString comment, QString extraData) UkuiMenu::DataEntity::DataEntity(UkuiMenu::DataType::Type type, QString name, QString icon, QString comment, QString extraData)
: m_type(type), m_name(std::move(name)), m_icon(std::move(icon)), m_comment(std::move(comment)), m_extraData(std::move(extraData)) : m_type(type), m_name(std::move(name)), m_icon(std::move(icon)), m_comment(std::move(comment)), m_extraData(std::move(extraData))
{ {
} }
int UkuiMenu::DataEntity::top() const
{
return m_top;
}
void UkuiMenu::DataEntity::setTop(int top)
{
m_top = top;
}
bool UkuiMenu::DataEntity::isLock() const
{
return m_lock;
}
void UkuiMenu::DataEntity::setLock(bool lock)
{
m_lock = lock;
}
int UkuiMenu::DataEntity::favorite() const
{
return m_favorite;
}
void UkuiMenu::DataEntity::setFavorite(int favorite)
{
m_favorite = favorite;
}
int UkuiMenu::DataEntity::launchTimes() const
{
return m_launchTimes;
}
void UkuiMenu::DataEntity::setLaunchTimes(int launchTimes)
{
m_launchTimes = launchTimes;
}
QString UkuiMenu::DataEntity::id() const
{
return m_id;
}
void UkuiMenu::DataEntity::setId(const QString &id)
{
m_id = id;
}
void UkuiMenu::DataEntity::setCategory(const QString &category)
{
m_category = category;
}
QString UkuiMenu::DataEntity::category() const
{
return m_category;
}
void UkuiMenu::DataEntity::setFirstLetter(const QString &firstLetter)
{
m_firstLetter = firstLetter;
}
QString UkuiMenu::DataEntity::firstLetter() const
{
return m_firstLetter;
}
void UkuiMenu::DataEntity::setType(UkuiMenu::DataType::Type type)
{
m_type = type;
}
UkuiMenu::DataType::Type UkuiMenu::DataEntity::type() const
{
return m_type;
}
void UkuiMenu::DataEntity::setIcon(const QString &icon)
{
m_icon = icon;
}
QString UkuiMenu::DataEntity::icon() const
{
return m_icon;
}
void UkuiMenu::DataEntity::setName(const QString &name)
{
m_name = name;
}
QString UkuiMenu::DataEntity::name() const
{
return m_name;
}
void UkuiMenu::DataEntity::setComment(const QString &comment)
{
m_comment = comment;
}
QString UkuiMenu::DataEntity::comment() const
{
return m_comment;
}
void UkuiMenu::DataEntity::setExtraData(const QString &extraData)
{
m_extraData = extraData;
}
QString UkuiMenu::DataEntity::extraData() const
{
return m_extraData;
}

View File

@ -68,30 +68,57 @@ public:
ExtraData ExtraData
}; };
DataEntity() = default; DataEntity() = default;
DataEntity(const DataEntity& obj);
DataEntity(DataType::Type type, QString name, QString icon, QString comment, QString extraData); DataEntity(DataType::Type type, QString name, QString icon, QString comment, QString extraData);
void setType(DataType::Type type) {m_type = type;} int top() const;
DataType::Type type() {return m_type;} void setTop(int top);
void setIcon(const QString& icon) {m_icon = icon;} bool isLock() const;
QString icon() {return m_icon;} void setLock(bool lock);
void setName(const QString& name) {m_name = name;} int favorite() const;
QString name() {return m_name;} void setFavorite(int favorite);
void setComment(const QString& comment) {m_comment = comment;} int launchTimes() const;
QString comment() {return m_comment;} void setLaunchTimes(int launchTimes);
void setExtraData(const QString& extraData) {m_extraData = extraData;} QString id() const;
QString extraData() {return m_extraData;} void setId(const QString& id);
void setCategory(const QString& category);
QString category() const;
void setFirstLetter(const QString& firstLetter);
QString firstLetter() const;
void setType(DataType::Type type);
DataType::Type type() const;
void setIcon(const QString& icon);
QString icon() const;
void setName(const QString& name);
QString name() const;
void setComment(const QString& comment);
QString comment() const;
void setExtraData(const QString& extraData);
QString extraData() const;
private: private:
bool m_lock{false}; // 应用锁定
int m_top{0}; // 置顶状态及序号
int m_favorite{0}; // 收藏状态及序号
int m_launchTimes{0}; // 启动次数
DataType::Type m_type {DataType::Normal};
QString m_id; // 应用可执行文件路径
QString m_icon; QString m_icon;
QString m_name; QString m_name;
QString m_comment; // 应用描述 QString m_category;
QString m_extraData; // 额外的数据 QString m_firstLetter;
DataType::Type m_type {DataType::Normal}; QString m_comment; // 应用描述
QString m_extraData; // 额外的数据
}; };
class CommonsModule class CommonsModule