forked from openkylin/ukui-menu
通过ukui-search接口实现获取应用数据功能
This commit is contained in:
parent
4832564558
commit
5098dce1cc
|
@ -27,7 +27,7 @@ find_package(PkgConfig REQUIRED)
|
|||
|
||||
set(UKUI_MENU_EXTERNAL_LIBS "")
|
||||
# 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})
|
||||
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-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/recent-file-extension.cpp src/extension/extensions/recent-file-extension.h
|
||||
)
|
||||
|
|
|
@ -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"
|
|
@ -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
|
129
src/commons.cpp
129
src/commons.cpp
|
@ -20,17 +20,128 @@
|
|||
|
||||
#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)
|
||||
: 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;
|
||||
}
|
||||
|
|
|
@ -68,30 +68,57 @@ public:
|
|||
ExtraData
|
||||
};
|
||||
DataEntity() = default;
|
||||
DataEntity(const DataEntity& obj);
|
||||
DataEntity(DataType::Type type, QString name, QString icon, QString comment, QString extraData);
|
||||
|
||||
void setType(DataType::Type type) {m_type = type;}
|
||||
DataType::Type type() {return m_type;}
|
||||
int top() const;
|
||||
void setTop(int top);
|
||||
|
||||
void setIcon(const QString& icon) {m_icon = icon;}
|
||||
QString icon() {return m_icon;}
|
||||
bool isLock() const;
|
||||
void setLock(bool lock);
|
||||
|
||||
void setName(const QString& name) {m_name = name;}
|
||||
QString name() {return m_name;}
|
||||
int favorite() const;
|
||||
void setFavorite(int favorite);
|
||||
|
||||
void setComment(const QString& comment) {m_comment = comment;}
|
||||
QString comment() {return m_comment;}
|
||||
int launchTimes() const;
|
||||
void setLaunchTimes(int launchTimes);
|
||||
|
||||
void setExtraData(const QString& extraData) {m_extraData = extraData;}
|
||||
QString extraData() {return m_extraData;}
|
||||
QString id() const;
|
||||
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:
|
||||
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_name;
|
||||
QString m_comment; // 应用描述
|
||||
QString m_extraData; // 额外的数据
|
||||
DataType::Type m_type {DataType::Normal};
|
||||
QString m_category;
|
||||
QString m_firstLetter;
|
||||
QString m_comment; // 应用描述
|
||||
QString m_extraData; // 额外的数据
|
||||
};
|
||||
|
||||
class CommonsModule
|
||||
|
|
Loading…
Reference in New Issue