feat: 修改后端使用model实现
This commit is contained in:
parent
d201ead078
commit
2d08482c4c
|
@ -129,6 +129,8 @@ set(SOURCE_FILES
|
||||||
src/extension/favorite/favorite-extension-plugin.cpp src/extension/favorite/favorite-extension-plugin.h
|
src/extension/favorite/favorite-extension-plugin.cpp src/extension/favorite/favorite-extension-plugin.h
|
||||||
src/extension/favorite/favorite-context-menu.cpp src/extension/favorite/favorite-context-menu.h
|
src/extension/favorite/favorite-context-menu.cpp src/extension/favorite/favorite-context-menu.h
|
||||||
src/extension/favorite/favorite-widget.cpp src/extension/favorite/favorite-widget.h
|
src/extension/favorite/favorite-widget.cpp src/extension/favorite/favorite-widget.h
|
||||||
|
src/libappdata/basic-app-model.cpp src/libappdata/basic-app-model.h
|
||||||
|
src/libappdata/app-database-interface.cpp src/libappdata/app-database-interface.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,334 @@
|
||||||
|
//
|
||||||
|
// Created by hxf on 23-12-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "app-database-interface.h"
|
||||||
|
#include "user-config.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
#include <application-info.h>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#define APP_ICON_PREFIX "image://appicon/"
|
||||||
|
|
||||||
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
class AppDatabaseWorkerPrivate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
friend class AppDatabaseInterface;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AppDatabaseWorkerPrivate(AppDatabaseInterface *parent = nullptr);
|
||||||
|
DataEntityVector getAllApps();
|
||||||
|
|
||||||
|
// 数据库操作函数
|
||||||
|
void setAppProperty(const QString &appid, const UkuiSearch::ApplicationPropertyMap &propertyMap);
|
||||||
|
void setAppProperty(const QString &appid, const UkuiSearch::ApplicationProperty::Property &property, const QVariant &value);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
/**
|
||||||
|
* 应用数据库的添加信号处理函数
|
||||||
|
* @param infos 新增应用的id列表
|
||||||
|
*/
|
||||||
|
void onAppDatabaseAdded(const QStringList &infos);
|
||||||
|
void onAppDatabaseUpdate(const UkuiSearch::ApplicationInfoMap &infoMap);
|
||||||
|
void onAppDatabaseUpdateAll(const QStringList &infos);
|
||||||
|
void onAppDatabaseDeleted(const QStringList &infos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void addInfoToApp(const QMap<UkuiSearch::ApplicationProperty::Property, QVariant> &info, DataEntity &app);
|
||||||
|
bool isFiltered(const UkuiSearch::ApplicationPropertyMap &appInfo) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppDatabaseInterface *q {nullptr};
|
||||||
|
|
||||||
|
UkuiSearch::ApplicationInfo *appDatabase {nullptr};
|
||||||
|
UkuiSearch::ApplicationProperties properties;
|
||||||
|
UkuiSearch::ApplicationPropertyMap filter;
|
||||||
|
};
|
||||||
|
|
||||||
|
AppDatabaseWorkerPrivate::AppDatabaseWorkerPrivate(AppDatabaseInterface *parent) : QObject(parent), q(parent)
|
||||||
|
{
|
||||||
|
// 注册需要在信号和槽函数中使用的数据结构
|
||||||
|
qRegisterMetaType<UkuiMenu::DataEntityVector>("DataEntityVector");
|
||||||
|
|
||||||
|
// 初始化应用数据库链接
|
||||||
|
appDatabase = new UkuiSearch::ApplicationInfo(this);
|
||||||
|
|
||||||
|
// 首次启动时,为某些应用设置标志位
|
||||||
|
if (UserConfig::instance()->isFirstStartUp()) {
|
||||||
|
// 默认收藏应用
|
||||||
|
for (const auto &appid : GlobalSetting::instance()->defaultFavoriteApps()) {
|
||||||
|
appDatabase->setAppToFavorites(appid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置从数据库查询哪些属性
|
||||||
|
properties << UkuiSearch::ApplicationProperty::Property::Top
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::Lock
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::Favorites
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::LaunchTimes
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::DesktopFilePath
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::Icon
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::LocalName
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::Category
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::FirstLetterAll
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::DontDisplay
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::AutoStart
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::InsertTime
|
||||||
|
<< UkuiSearch::ApplicationProperty::Property::Launched;
|
||||||
|
|
||||||
|
// 需要从数据库过滤的属性
|
||||||
|
filter.insert(UkuiSearch::ApplicationProperty::Property::DontDisplay, 0);
|
||||||
|
filter.insert(UkuiSearch::ApplicationProperty::Property::AutoStart, 0);
|
||||||
|
|
||||||
|
// 链接数据库信号
|
||||||
|
connect(appDatabase, &UkuiSearch::ApplicationInfo::appDBItems2BAdd, this, &AppDatabaseWorkerPrivate::onAppDatabaseAdded);
|
||||||
|
connect(appDatabase, &UkuiSearch::ApplicationInfo::appDBItems2BUpdate, this, &AppDatabaseWorkerPrivate::onAppDatabaseUpdate);
|
||||||
|
connect(appDatabase, &UkuiSearch::ApplicationInfo::appDBItems2BUpdateAll, this, &AppDatabaseWorkerPrivate::onAppDatabaseUpdateAll);
|
||||||
|
connect(appDatabase, &UkuiSearch::ApplicationInfo::appDBItems2BDelete, this, &AppDatabaseWorkerPrivate::onAppDatabaseDeleted);
|
||||||
|
connect(appDatabase, &UkuiSearch::ApplicationInfo::DBOpenFailed, q, &AppDatabaseInterface::appDatabaseOpenFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::addInfoToApp(const UkuiSearch::ApplicationPropertyMap &info, DataEntity &app)
|
||||||
|
{
|
||||||
|
app.setTop(info.value(UkuiSearch::ApplicationProperty::Property::Top).toInt());
|
||||||
|
app.setLock(info.value(UkuiSearch::ApplicationProperty::Property::Lock).toInt() == 1);
|
||||||
|
app.setFavorite(info.value(UkuiSearch::ApplicationProperty::Property::Favorites).toInt());
|
||||||
|
app.setLaunchTimes(info.value(UkuiSearch::ApplicationProperty::Property::LaunchTimes).toInt());
|
||||||
|
app.setId(info.value(UkuiSearch::ApplicationProperty::Property::DesktopFilePath).toString());
|
||||||
|
app.setIcon(APP_ICON_PREFIX + info.value(UkuiSearch::ApplicationProperty::Property::Icon).toString());
|
||||||
|
app.setName(info.value(UkuiSearch::ApplicationProperty::Property::LocalName).toString());
|
||||||
|
app.setCategory(info.value(UkuiSearch::ApplicationProperty::Property::Category).toString());
|
||||||
|
app.setFirstLetter(info.value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString());
|
||||||
|
app.setInsertTime(info.value(UkuiSearch::ApplicationProperty::Property::InsertTime).toString());
|
||||||
|
app.setLaunched(info.value(UkuiSearch::ApplicationProperty::Property::Launched).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppDatabaseWorkerPrivate::isFiltered(const UkuiSearch::ApplicationPropertyMap &appInfo) const
|
||||||
|
{
|
||||||
|
QMapIterator<UkuiSearch::ApplicationProperty::Property, QVariant> iterator(filter);
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next();
|
||||||
|
if (appInfo.value(iterator.key()) == iterator.value()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntityVector AppDatabaseWorkerPrivate::getAllApps()
|
||||||
|
{
|
||||||
|
UkuiSearch::ApplicationInfoMap appInfos = appDatabase->getInfo(properties, filter);
|
||||||
|
if (appInfos.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntityVector apps;
|
||||||
|
for (const auto &info : appInfos) {
|
||||||
|
DataEntity app;
|
||||||
|
AppDatabaseWorkerPrivate::addInfoToApp(info, app);
|
||||||
|
apps.append(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
return apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::onAppDatabaseAdded(const QStringList &infos)
|
||||||
|
{
|
||||||
|
if (infos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntityVector apps;
|
||||||
|
for (const QString &appid : infos) {
|
||||||
|
const UkuiSearch::ApplicationPropertyMap appInfo = appDatabase->getInfo(appid, properties);
|
||||||
|
if (isFiltered(appInfo)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntity app;
|
||||||
|
addInfoToApp(appInfo, app);
|
||||||
|
apps.append(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apps.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT q->appAdded(apps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::onAppDatabaseUpdate(const UkuiSearch::ApplicationInfoMap &infoMap)
|
||||||
|
{
|
||||||
|
if (infoMap.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPair<DataEntity, QVector<int> > > updates;
|
||||||
|
QMapIterator<QString, UkuiSearch::ApplicationPropertyMap> iterator(infoMap);
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next();
|
||||||
|
|
||||||
|
DataEntity app;
|
||||||
|
QVector<int> roles;
|
||||||
|
|
||||||
|
QMapIterator<UkuiSearch::ApplicationProperty::Property, QVariant> it(iterator.value());
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
|
||||||
|
switch (it.key()) {
|
||||||
|
case UkuiSearch::ApplicationProperty::LocalName:
|
||||||
|
app.setName(it.value().toString());
|
||||||
|
roles.append(DataEntity::Name);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::FirstLetterAll:
|
||||||
|
app.setFirstLetter(it.value().toString());
|
||||||
|
roles.append(DataEntity::FirstLetter);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Icon:
|
||||||
|
app.setIcon(it.value().toString());
|
||||||
|
roles.append(DataEntity::Icon);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::InsertTime:
|
||||||
|
app.setInsertTime(it.value().toString());
|
||||||
|
roles.append(DataEntity::Icon);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Category:
|
||||||
|
app.setCategory(it.value().toString());
|
||||||
|
roles.append(DataEntity::Category);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::LaunchTimes:
|
||||||
|
app.setLaunchTimes(it.value().toInt());
|
||||||
|
roles.append(DataEntity::LaunchTimes);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Favorites:
|
||||||
|
app.setFavorite(it.value().toInt());
|
||||||
|
roles.append(DataEntity::Favorite);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Launched:
|
||||||
|
app.setLaunched(it.value().toInt());
|
||||||
|
roles.append(DataEntity::IsLaunched);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Top:
|
||||||
|
app.setTop(it.value().toInt());
|
||||||
|
roles.append(DataEntity::Top);
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Lock:
|
||||||
|
app.setLock(it.value().toBool());
|
||||||
|
roles.append(DataEntity::IsLocked);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这个函数中,没有更新列不会发送信号
|
||||||
|
if (roles.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.setId(iterator.key());
|
||||||
|
updates.append({app, roles});
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT q->appUpdated(updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::onAppDatabaseDeleted(const QStringList &infos)
|
||||||
|
{
|
||||||
|
if (infos.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT q->appDeleted(infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::onAppDatabaseUpdateAll(const QStringList &infos)
|
||||||
|
{
|
||||||
|
if (infos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPair<DataEntity, QVector<int> > > updates;
|
||||||
|
DataEntityVector apps;
|
||||||
|
|
||||||
|
for (const auto &appid : infos) {
|
||||||
|
const UkuiSearch::ApplicationPropertyMap appInfo = appDatabase->getInfo(appid, properties);
|
||||||
|
DataEntity app;
|
||||||
|
addInfoToApp(appInfo, app);
|
||||||
|
apps.append(app);
|
||||||
|
|
||||||
|
updates.append({app, {}});
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT q->appUpdated(updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::setAppProperty(const QString &appid, const UkuiSearch::ApplicationPropertyMap &propertyMap)
|
||||||
|
{
|
||||||
|
QMapIterator<UkuiSearch::ApplicationProperty::Property, QVariant> iterator(propertyMap);
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
iterator.next();
|
||||||
|
setAppProperty(appid, iterator.key(), iterator.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseWorkerPrivate::setAppProperty(const QString &appid, const UkuiSearch::ApplicationProperty::Property &property,
|
||||||
|
const QVariant &value)
|
||||||
|
{
|
||||||
|
switch (property) {
|
||||||
|
case UkuiSearch::ApplicationProperty::Favorites:
|
||||||
|
appDatabase->setFavoritesOfApp(appid, value.toInt());
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Launched:
|
||||||
|
appDatabase->setAppLaunchedState(appid, value.toBool());
|
||||||
|
break;
|
||||||
|
case UkuiSearch::ApplicationProperty::Top:
|
||||||
|
appDatabase->setTopOfApp(appid, value.toInt());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== AppDatabaseInterface ====== //
|
||||||
|
AppDatabaseInterface::AppDatabaseInterface(QObject *parent) : QObject(parent), d(new AppDatabaseWorkerPrivate(this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntityVector AppDatabaseInterface::apps() const
|
||||||
|
{
|
||||||
|
return d->getAllApps();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseInterface::fixAppToTop(const QString &appid, int index)
|
||||||
|
{
|
||||||
|
if (index < 0) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Top, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseInterface::fixAppToFavorite(const QString &appid, int index)
|
||||||
|
{
|
||||||
|
if (index < 0) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Favorites, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppDatabaseInterface::updateApLaunchedState(const QString &appid, bool state)
|
||||||
|
{
|
||||||
|
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Launched, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // UkuiMenu
|
||||||
|
|
||||||
|
#include "app-database-interface.moc"
|
|
@ -0,0 +1,85 @@
|
||||||
|
//
|
||||||
|
// Created by hxf on 23-12-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UKUI_MENU_APP_DATABASE_INTERFACE_H
|
||||||
|
#define UKUI_MENU_APP_DATABASE_INTERFACE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPair>
|
||||||
|
#include "data-entity.h"
|
||||||
|
|
||||||
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
typedef QVector<DataEntity> DataEntityVector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封装与应用数据库的链接
|
||||||
|
*/
|
||||||
|
class AppDatabaseWorkerPrivate;
|
||||||
|
|
||||||
|
class AppDatabaseInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AppDatabaseInterface(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据库获取全部应用
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
DataEntityVector apps() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 置顶应用
|
||||||
|
* @param appid 应用id
|
||||||
|
* @param index 置顶后的位置,小于或等于0将会取消置顶
|
||||||
|
*/
|
||||||
|
void fixAppToTop(const QString &appid, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收藏应用
|
||||||
|
* @param appid 应用id
|
||||||
|
* @param index 收藏后的位置,小于或等于0将会取消收藏
|
||||||
|
*/
|
||||||
|
void fixAppToFavorite(const QString &appid, int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置应用是否已经被启动过
|
||||||
|
* @param state 状态值,true已被启动,false未被启动
|
||||||
|
*/
|
||||||
|
void updateApLaunchedState(const QString &appid, bool state = true);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
/**
|
||||||
|
* 新增应用信号
|
||||||
|
* @param apps 新增加的应用
|
||||||
|
*/
|
||||||
|
void appAdded(const UkuiMenu::DataEntityVector &apps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新的应用及其属性列表
|
||||||
|
* @param updates
|
||||||
|
*/
|
||||||
|
void appUpdated(const QVector<QPair<UkuiMenu::DataEntity, QVector<int> > > &updates);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用被删除的信号
|
||||||
|
* @param apps 返回被删除应用的id列表
|
||||||
|
*/
|
||||||
|
void appDeleted(const QStringList &apps);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用数据库打开失败信号
|
||||||
|
*/
|
||||||
|
void appDatabaseOpenFailed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AppDatabaseWorkerPrivate *d {nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // UkuiMenu
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(UkuiMenu::DataEntityVector)
|
||||||
|
|
||||||
|
#endif //UKUI_MENU_APP_DATABASE_INTERFACE_H
|
|
@ -0,0 +1,164 @@
|
||||||
|
//
|
||||||
|
// Created by hxf on 23-12-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "basic-app-model.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
BasicAppModel::BasicAppModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
, m_databaseInterface(new AppDatabaseInterface(this))
|
||||||
|
{
|
||||||
|
connect(m_databaseInterface, &AppDatabaseInterface::appDatabaseOpenFailed, this, [this] {
|
||||||
|
qWarning() << "BasicAppModel: app database open failed.";
|
||||||
|
m_apps.clear();
|
||||||
|
// TODO: 显示错误信息到界面
|
||||||
|
});
|
||||||
|
|
||||||
|
m_apps = m_databaseInterface->apps();
|
||||||
|
|
||||||
|
connect(m_databaseInterface, &AppDatabaseInterface::appAdded, this, &BasicAppModel::onAppAdded);
|
||||||
|
connect(m_databaseInterface, &AppDatabaseInterface::appUpdated, this, &BasicAppModel::onAppUpdated);
|
||||||
|
connect(m_databaseInterface, &AppDatabaseInterface::appDeleted, this, &BasicAppModel::onAppDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasicAppModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return m_apps.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasicAppModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant BasicAppModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const DataEntity &app = m_apps[index.row()];
|
||||||
|
return app.getValue(static_cast<DataEntity::PropertyName>(role));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BasicAppModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (!checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntity &app = m_apps[index.row()];
|
||||||
|
DataEntity::PropertyName propertyName;
|
||||||
|
switch (propertyName) {
|
||||||
|
case DataEntity::Group:
|
||||||
|
app.setGroup(value.toString());
|
||||||
|
return true;
|
||||||
|
case DataEntity::IsLaunched: {
|
||||||
|
if (value.toBool() == app.launched()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_databaseInterface->updateApLaunchedState(app.id(), value.toBool());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case DataEntity::Favorite:
|
||||||
|
if (value.toInt() == app.favorite()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_databaseInterface->fixAppToFavorite(app.id(), value.toInt());
|
||||||
|
return true;
|
||||||
|
case DataEntity::Top:
|
||||||
|
if (value.toInt() == app.top()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_databaseInterface->fixAppToTop(app.id(), value.toInt());
|
||||||
|
return true;
|
||||||
|
case DataEntity::RecentInstall:
|
||||||
|
app.setRecentInstall(value.toBool());
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QAbstractItemModel::setData(index, value, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> BasicAppModel::roleNames() const
|
||||||
|
{
|
||||||
|
return DataEntity::AppRoleNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDatabaseInterface *BasicAppModel::databaseInterface() const
|
||||||
|
{
|
||||||
|
return m_databaseInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicAppModel::onAppAdded(const DataEntityVector &apps)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size() + apps.size() - 1);
|
||||||
|
m_apps.append(apps);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicAppModel::onAppUpdated(const QVector<QPair<DataEntity, QVector<int> > > &updates)
|
||||||
|
{
|
||||||
|
for (const auto &pair : updates) {
|
||||||
|
int index = indexOfApp(pair.first.id());
|
||||||
|
if (index < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntity &app = m_apps[index];
|
||||||
|
QVector<int> roles = pair.second;
|
||||||
|
if (!roles.isEmpty()) {
|
||||||
|
for (const auto &role : roles) {
|
||||||
|
app.setValue(static_cast<DataEntity::PropertyName>(role), static_cast<DataEntity::PropertyName>(role));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
app = pair.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataChanged(QAbstractListModel::index(index), QAbstractListModel::index(index), roles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicAppModel::onAppDeleted(const QStringList &apps)
|
||||||
|
{
|
||||||
|
for (const auto &appid : apps) {
|
||||||
|
int index = indexOfApp(appid);
|
||||||
|
if (index < 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
m_apps.takeAt(index);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int BasicAppModel::indexOfApp(const QString &appid) const
|
||||||
|
{
|
||||||
|
auto it = std::find_if(m_apps.constBegin(), m_apps.constEnd(), [&appid] (const DataEntity &app) {
|
||||||
|
return app.id() == appid;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it == m_apps.constEnd()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::distance(m_apps.constBegin(), it);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntity BasicAppModel::appOfIndex(int row) const
|
||||||
|
{
|
||||||
|
QModelIndex idx = QAbstractListModel::index(row);
|
||||||
|
if (!checkIndex(idx, QAbstractItemModel::CheckIndexOption::IndexIsValid)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_apps.at(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // UkuiMenu
|
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// Created by hxf on 23-12-11.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UKUI_MENU_BASIC_APP_MODEL_H
|
||||||
|
#define UKUI_MENU_BASIC_APP_MODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "data-entity.h"
|
||||||
|
#include "app-database-interface.h"
|
||||||
|
|
||||||
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
class BasicAppModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit BasicAppModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库访问接口
|
||||||
|
* @return @AppDatabaseInterface *
|
||||||
|
*/
|
||||||
|
AppDatabaseInterface *databaseInterface() const;
|
||||||
|
DataEntity appOfIndex(int row) const;
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
int columnCount(const QModelIndex &parent) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onAppAdded(const UkuiMenu::DataEntityVector &apps);
|
||||||
|
void onAppUpdated(const QVector<QPair<UkuiMenu::DataEntity, QVector<int> > > &updates);
|
||||||
|
void onAppDeleted(const QStringList &apps);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int indexOfApp(const QString &appid) const;
|
||||||
|
AppDatabaseInterface *m_databaseInterface {nullptr};
|
||||||
|
|
||||||
|
QVector<DataEntity> m_apps;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // UkuiMenu
|
||||||
|
|
||||||
|
#endif //UKUI_MENU_BASIC_APP_MODEL_H
|
Loading…
Reference in New Issue