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-context-menu.cpp src/extension/favorite/favorite-context-menu.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