feat(extension):实现收藏区域显示应用组和右键菜单功能
This commit is contained in:
parent
1e34114387
commit
898b61d312
|
@ -129,6 +129,10 @@ 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/extension/favorite/app-favorite-model.cpp src/extension/favorite/app-favorite-model.h
|
||||
src/extension/favorite/favorites-config.cpp src/extension/favorite/favorites-config.h
|
||||
src/extension/favorite/favorites-model.cpp src/extension/favorite/favorites-model.h
|
||||
src/extension/favorite/favorite-folder-helper.cpp src/extension/favorite/favorite-folder-helper.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
|
||||
)
|
||||
|
|
|
@ -34,7 +34,8 @@ public:
|
|||
enum Type {
|
||||
Normal, // 普通Item
|
||||
Label, // 标签数据
|
||||
Folder // 文件夹
|
||||
Folder, // 应用组
|
||||
Files // 文件夹
|
||||
};
|
||||
Q_ENUM(Type);
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
Extension, /**< 扩展页 */
|
||||
FolderPage, /**< 文件夹页面 */
|
||||
FullScreen, /**< 全屏应用列表 */
|
||||
FullScreenFolder, /**< 全屏文件夹页面 */
|
||||
Folder, /**< 应用组页面 */
|
||||
};
|
||||
Q_ENUM(Location)
|
||||
};
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-27.
|
||||
//
|
||||
|
||||
#include "favorites-config.h"
|
||||
#include "app-favorite-model.h"
|
||||
#include "favorite-folder-helper.h"
|
||||
|
||||
#include <QMimeDatabase>
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
AppFavoritesModel &AppFavoritesModel::instance()
|
||||
{
|
||||
static AppFavoritesModel appFavoritesModel;
|
||||
return appFavoritesModel;
|
||||
}
|
||||
|
||||
AppFavoritesModel::AppFavoritesModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
m_sourceModel = BasicAppModel::instance();
|
||||
|
||||
updateData();
|
||||
|
||||
connect(m_sourceModel, &BasicAppModel::dataChanged, this, &AppFavoritesModel::onAppUpdated);
|
||||
connect(m_sourceModel, &BasicAppModel::rowsAboutToBeRemoved, this, &AppFavoritesModel::onAppRemoved);
|
||||
connect(FavoriteFolderHelper::instance(), &FavoriteFolderHelper::folderAdded, this,&AppFavoritesModel::onFolderAdded);
|
||||
connect(FavoriteFolderHelper::instance(), &FavoriteFolderHelper::folderToBeDeleted, this, &AppFavoritesModel::onFolderDeleted);
|
||||
connect(FavoriteFolderHelper::instance(), &FavoriteFolderHelper::folderDataChanged, this, &AppFavoritesModel::onFolderChanged);
|
||||
}
|
||||
|
||||
AppFavoritesModel::~AppFavoritesModel()
|
||||
{
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> AppFavoritesModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> names;
|
||||
names.insert(DataEntity::Id, "id");
|
||||
names.insert(DataEntity::Icon, "icon");
|
||||
names.insert(DataEntity::Name, "name");
|
||||
names.insert(DataEntity::Type, "type");
|
||||
return names;
|
||||
}
|
||||
|
||||
int AppFavoritesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_favoritesApps.count() + m_folders.count() + m_favoritesFiles.count();
|
||||
}
|
||||
|
||||
QVariant AppFavoritesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= rowCount()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (index.row() < m_favoritesApps.count()) {
|
||||
return m_favoritesApps.at(index.row()).data(role);
|
||||
|
||||
} else if (index.row() < m_favoritesApps.count() + m_folders.count() && index.row() >= m_favoritesApps.count()) {
|
||||
return folderData(index, role);
|
||||
|
||||
} else {
|
||||
return fileData(index, role);
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::getFavoritesApps()
|
||||
{
|
||||
m_favoritesApps.clear();
|
||||
for (int i = 0; i < m_sourceModel->rowCount(QModelIndex()); i++) {
|
||||
updateFavoritesApps(m_sourceModel->appOfIndex(i), m_sourceModel->index(i));
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::onAppUpdated(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
{
|
||||
for (const auto &role : roles) {
|
||||
if (role == DataEntity::Favorite) {
|
||||
updateFavoritesApps(m_sourceModel->appOfIndex(topLeft.row()), topLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::getFoldersId()
|
||||
{
|
||||
QVector<int> foldersId;
|
||||
for (const auto &folder : FavoriteFolderHelper::instance()->folderData()) {
|
||||
foldersId.append(folder.getId());
|
||||
}
|
||||
m_folders.swap(foldersId);
|
||||
}
|
||||
|
||||
void AppFavoritesModel::getFavoritesFiles()
|
||||
{
|
||||
}
|
||||
|
||||
void AppFavoritesModel::updateFavoritesApps(const DataEntity &app, const QModelIndex &sourceIndex)
|
||||
{
|
||||
if (app.id().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (app.favorite() > 0 && !FavoriteFolderHelper::instance()->containApp(app.id())) {
|
||||
QPersistentModelIndex index(sourceIndex);
|
||||
addFavoriteApp(index);
|
||||
|
||||
} else if (app.favorite() == 0) {
|
||||
QPersistentModelIndex index(sourceIndex);
|
||||
removeFavoriteApp(index);
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::updateData()
|
||||
{
|
||||
getFavoritesApps();
|
||||
getFoldersId();
|
||||
getFavoritesFiles();
|
||||
}
|
||||
|
||||
QVariant AppFavoritesModel::folderData(const QModelIndex &index, int role) const
|
||||
{
|
||||
FavoritesFolder folder;
|
||||
int folderId = m_folders.at(index.row() - m_favoritesApps.count());
|
||||
if (!FavoriteFolderHelper::instance()->getFolderFromId(folderId, folder)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case DataEntity::Id:
|
||||
return QString::number(folder.getId());
|
||||
case DataEntity::Icon:
|
||||
return FavoriteFolderHelper::folderIcon(folder).join(" ");
|
||||
case DataEntity::Name:
|
||||
return folder.getName();
|
||||
case DataEntity::Type:
|
||||
return DataType::Folder;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant AppFavoritesModel::fileData(const QModelIndex &index, int role) const
|
||||
{
|
||||
int fileIndex = index.row() - m_favoritesApps.count() - m_folders.count();
|
||||
QString url = m_favoritesFiles.at(fileIndex);
|
||||
|
||||
switch (role) {
|
||||
case DataEntity::Id:
|
||||
return url;
|
||||
case DataEntity::Icon: {
|
||||
QMimeDatabase mimeDatabase;
|
||||
return mimeDatabase.mimeTypeForFile(url).iconName();
|
||||
}
|
||||
case DataEntity::Name:
|
||||
return QUrl(url).fileName();
|
||||
case DataEntity::Type:
|
||||
return DataType::Files;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QStringList AppFavoritesModel::favoritesApps() const
|
||||
{
|
||||
QMap<int, QString> apps;
|
||||
for (auto index : m_favoritesApps) {
|
||||
QString id = m_sourceModel->data(index, DataEntity::Id).toString();
|
||||
int favorite = m_sourceModel->data(index, DataEntity::Favorite).toInt();
|
||||
apps.insert(favorite, id);
|
||||
}
|
||||
|
||||
return apps.values();
|
||||
}
|
||||
|
||||
void AppFavoritesModel::changeAppState(const QString &id, const int &index)
|
||||
{
|
||||
if (id.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_sourceModel->databaseInterface()->fixAppToFavorite(id, index);
|
||||
|
||||
// 同步配置文件,更新应用顺序
|
||||
if (index > 0) {
|
||||
FavoritesConfig::instance().insertValue(id, index);
|
||||
}
|
||||
}
|
||||
|
||||
bool AppFavoritesModel::getApp(const QString &appid, DataEntity &app)
|
||||
{
|
||||
return m_sourceModel->databaseInterface()->getApp(appid, app);
|
||||
}
|
||||
|
||||
void AppFavoritesModel::onAppRemoved(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
for(int row = first; row <= last; ++row) {
|
||||
QModelIndex sourceIndex = m_sourceModel->index(row, 0, {});
|
||||
QPersistentModelIndex index(sourceIndex);
|
||||
|
||||
if (index.data(DataEntity::Favorite).toInt() > 0) {
|
||||
QString appId = index.data(DataEntity::Id).toString();
|
||||
|
||||
if (!m_favoritesApps.contains(index) && FavoriteFolderHelper::instance()->containApp(appId)) {
|
||||
FavoriteFolderHelper::instance()->removeAppFromFolder(appId);
|
||||
}
|
||||
|
||||
removeFavoriteApp(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::addFavoriteApp(const QPersistentModelIndex &modelIndex)
|
||||
{
|
||||
if (m_favoritesApps.contains(modelIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
beginInsertRows(QModelIndex(), m_favoritesApps.count(), m_favoritesApps.count());
|
||||
m_favoritesApps.append(modelIndex);
|
||||
endInsertRows();
|
||||
|
||||
FavoritesConfig::instance().insertValue(modelIndex.data(DataEntity::Id).toString());
|
||||
}
|
||||
|
||||
void AppFavoritesModel::removeFavoriteApp(const QPersistentModelIndex &modelIndex)
|
||||
{
|
||||
if (!m_favoritesApps.contains(modelIndex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
beginRemoveRows(QModelIndex(), m_favoritesApps.indexOf(modelIndex), m_favoritesApps.indexOf(modelIndex));
|
||||
m_favoritesApps.removeOne(modelIndex);
|
||||
endRemoveRows();
|
||||
|
||||
FavoritesConfig::instance().removeValueById(modelIndex.data(DataEntity::Id).toString());
|
||||
}
|
||||
|
||||
void AppFavoritesModel::onFolderAdded(const int &folderId, const int &order)
|
||||
{
|
||||
if (!m_folders.contains(folderId)) {
|
||||
beginInsertRows(QModelIndex(), m_favoritesApps.count() + m_folders.count(), m_favoritesApps.count() + m_folders.count());
|
||||
m_folders.append(folderId);
|
||||
endInsertRows();
|
||||
|
||||
FavoritesFolder folder;
|
||||
FavoriteFolderHelper::instance()->getFolderFromId(folderId, folder);
|
||||
for (auto app : folder.getApps()) {
|
||||
removeFavoriteApp(getIndexFromAppId(app));
|
||||
}
|
||||
|
||||
FavoritesConfig::instance().insertValue(QString::number(folderId), std::max(0, order));
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::onFolderDeleted(const int &folderId, const QStringList &apps)
|
||||
{
|
||||
if (m_folders.contains(folderId)) {
|
||||
beginRemoveRows(QModelIndex(), m_favoritesApps.count() + m_folders.indexOf(folderId), m_favoritesApps.count() + m_folders.indexOf(folderId));
|
||||
m_folders.removeOne(folderId);
|
||||
endRemoveRows();
|
||||
|
||||
for (auto app : apps) {
|
||||
QPersistentModelIndex modelIndex(m_sourceModel->index(m_sourceModel->indexOfApp(app)));
|
||||
addFavoriteApp(modelIndex);
|
||||
}
|
||||
|
||||
FavoritesConfig::instance().removeValueById(QString::number(folderId));
|
||||
}
|
||||
}
|
||||
|
||||
void AppFavoritesModel::onFolderChanged(const int &folderId, const QString &appId)
|
||||
{
|
||||
QVector<int> roles;
|
||||
if (appId.isEmpty()) {
|
||||
roles.append(DataEntity::Name);
|
||||
int row = m_favoritesApps.count() + m_folders.indexOf(folderId);
|
||||
|
||||
Q_EMIT dataChanged(index(row), index(row), roles);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FavoriteFolderHelper::instance()->containApp(appId)) {
|
||||
removeFavoriteApp(getIndexFromAppId(appId));
|
||||
|
||||
} else {
|
||||
QPersistentModelIndex modelIndex(m_sourceModel->index(m_sourceModel->indexOfApp(appId)));
|
||||
addFavoriteApp(modelIndex);
|
||||
}
|
||||
|
||||
roles.append(DataEntity::Icon);
|
||||
int row = m_favoritesApps.count() + m_folders.indexOf(folderId);
|
||||
|
||||
Q_EMIT dataChanged(index(row), index(row), roles);
|
||||
}
|
||||
|
||||
QPersistentModelIndex AppFavoritesModel::getIndexFromAppId(const QString &id) const
|
||||
{
|
||||
auto modelIndex = std::find_if(m_favoritesApps.constBegin(), m_favoritesApps.constEnd(), [&id] (const QPersistentModelIndex &index) {
|
||||
return index.data(DataEntity::Id).toString() == id;
|
||||
});
|
||||
|
||||
if (modelIndex == m_favoritesApps.constEnd()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return *modelIndex;
|
||||
}
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-27.
|
||||
//
|
||||
|
||||
#ifndef UKUI_MENU_APP_FAVORITE_MODEL_H
|
||||
#define UKUI_MENU_APP_FAVORITE_MODEL_H
|
||||
|
||||
#include "data-entity.h"
|
||||
#include "libappdata/basic-app-model.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QAbstractListModel>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class AppFavoritesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static AppFavoritesModel &instance();
|
||||
~AppFavoritesModel() override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
QStringList favoritesApps() const;
|
||||
void changeAppState(const QString &id, const int &index);
|
||||
bool getApp(const QString &appid, DataEntity &app);
|
||||
|
||||
private:
|
||||
explicit AppFavoritesModel(QObject *parent = nullptr);
|
||||
|
||||
void getFavoritesApps();
|
||||
void getFoldersId();
|
||||
void getFavoritesFiles();
|
||||
void updateData();
|
||||
|
||||
void addFavoriteApp(const QPersistentModelIndex &modelIndex);
|
||||
void removeFavoriteApp(const QPersistentModelIndex &modelIndex);
|
||||
void onAppRemoved(const QModelIndex &parent, int first, int last);
|
||||
void onAppUpdated(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());
|
||||
void updateFavoritesApps(const DataEntity &app, const QModelIndex &sourceIndex);
|
||||
QPersistentModelIndex getIndexFromAppId(const QString &id) const;
|
||||
|
||||
void onFolderAdded(const int &folderId, const int &order);
|
||||
void onFolderDeleted(const int &folderId, const QStringList &apps);
|
||||
void onFolderChanged(const int &folderId, const QString &appId);
|
||||
|
||||
QVariant folderData(const QModelIndex &index, int role) const;
|
||||
QVariant fileData(const QModelIndex &index, int role) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
*不在应用组的收藏应用在baseModel的对应index
|
||||
*/
|
||||
QVector<QPersistentModelIndex> m_favoritesApps;
|
||||
/**
|
||||
*应用组的唯一Id
|
||||
*/
|
||||
QVector<int> m_folders;
|
||||
/**
|
||||
*收藏文件夹的唯一路径
|
||||
*/
|
||||
QVector<QString> m_favoritesFiles;
|
||||
BasicAppModel *m_sourceModel = nullptr;
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_APP_FAVORITE_MODEL_H
|
|
@ -17,7 +17,9 @@
|
|||
*/
|
||||
|
||||
#include "favorite-context-menu.h"
|
||||
#include "favorite-folder-helper.h"
|
||||
#include "app-data-manager.h"
|
||||
#include "favorites-model.h"
|
||||
#include "event-track.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
@ -35,33 +37,51 @@ FavoriteContextMenu::actions(const DataEntity &data, QMenu *parent, const MenuIn
|
|||
return {};
|
||||
}
|
||||
|
||||
if (data.type() != DataType::Normal) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<QAction *> list;
|
||||
|
||||
if (data.type() == DataType::Folder) {
|
||||
list << new QAction(QObject::tr("Dissolve folder"), parent);
|
||||
QObject::connect(list.last(), &QAction::triggered, parent, [data] {
|
||||
FavoriteFolderHelper::instance()->deleteFolder(data.id().toInt());
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
switch (location) {
|
||||
case MenuInfo::AppList:
|
||||
case MenuInfo::FolderPage:
|
||||
case MenuInfo::Extension: {
|
||||
case MenuInfo::FolderPage: {
|
||||
if (data.favorite() == 0) {
|
||||
list << new QAction(QObject::tr("Fix to favorite"), parent);
|
||||
QObject::connect(list.last(), &QAction::triggered, parent, [data] {
|
||||
Q_EMIT AppDataManager::instance()->fixToFavoriteSignal(data.id(), 1);
|
||||
FavoritesModel::instance().addAppToFavorites(data.id());
|
||||
EventTrack::instance()->sendDefaultEvent("fix_to_favorite", "Right-click Menu");
|
||||
});
|
||||
} else if (locationId == "favorite") {
|
||||
|
||||
} else if (data.favorite() > 0) {
|
||||
list << new QAction(QObject::tr("Remove from favorite"), parent);
|
||||
QObject::connect(list.last(), &QAction::triggered, parent, [data] {
|
||||
Q_EMIT AppDataManager::instance()->fixToFavoriteSignal(data.id(), 0);
|
||||
FavoritesModel::instance().removeAppFromFavorites(data.id());
|
||||
EventTrack::instance()->sendDefaultEvent("remove_from_favorite", "Right-click Menu");
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MenuInfo::Extension: {
|
||||
QAction *action = new QAction(QObject::tr("Remove from favorite"), parent);
|
||||
QObject::connect(action, &QAction::triggered, parent, [data] {
|
||||
FavoritesModel::instance().removeAppFromFavorites(data.id());
|
||||
EventTrack::instance()->sendDefaultEvent("remove_from_favorite", "Right-click Menu");
|
||||
});
|
||||
list << action;
|
||||
|
||||
appendActionsForAppsOutsideFolder(parent, data.id(), list);
|
||||
break;
|
||||
}
|
||||
case MenuInfo::FullScreen:
|
||||
case MenuInfo::FullScreenFolder:
|
||||
case MenuInfo::Folder: {
|
||||
appendActionsForAppsInFolder(parent, data.id(), list);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -69,4 +89,39 @@ FavoriteContextMenu::actions(const DataEntity &data, QMenu *parent, const MenuIn
|
|||
return list;
|
||||
}
|
||||
|
||||
void FavoriteContextMenu::appendActionsForAppsInFolder(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||
{
|
||||
FavoritesFolder folder;
|
||||
|
||||
list << new QAction(QObject::tr("Remove from folder"), parent);
|
||||
QObject::connect(list.last(), &QAction::triggered, parent, [appId] {
|
||||
FavoriteFolderHelper::instance()->removeAppFromFolder(appId);
|
||||
});
|
||||
}
|
||||
|
||||
void FavoriteContextMenu::appendActionsForAppsOutsideFolder(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||
{
|
||||
QAction *action = new QAction(QObject::tr("Add to folder"), parent);
|
||||
|
||||
QMenu *subMenu = new QMenu();
|
||||
QAction *subAction = new QAction(QObject::tr("Create a new folder"), parent);
|
||||
QObject::connect(subAction, &QAction::triggered, parent, [appId] {
|
||||
FavoritesModel::instance().addAppToFolder(appId, "");
|
||||
});
|
||||
subMenu->addAction(subAction);
|
||||
|
||||
for (auto folder : FavoriteFolderHelper::instance()->folderData()) {
|
||||
QString folderName = folder.getName();
|
||||
int folderId = folder.getId();
|
||||
QAction *subAction = new QAction(QObject::tr("Add to ").append(folderName), parent);
|
||||
QObject::connect(subAction, &QAction::triggered, parent, [appId, folderId] {
|
||||
FavoritesModel::instance().addAppToFolder(appId, QString::number(folderId));
|
||||
});
|
||||
subMenu->addAction(subAction);
|
||||
}
|
||||
|
||||
action->setMenu(subMenu);
|
||||
list << action;
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
||||
|
|
|
@ -30,6 +30,10 @@ public:
|
|||
QList<QAction *> actions(const DataEntity &data, QMenu *parent,
|
||||
const MenuInfo::Location &location,
|
||||
const QString &locationId) override;
|
||||
|
||||
private:
|
||||
void appendActionsForAppsInFolder(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||
void appendActionsForAppsOutsideFolder(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
|
|
@ -0,0 +1,354 @@
|
|||
/*
|
||||
* Copyright (C) 2022, 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 "favorite-folder-helper.h"
|
||||
#include "app-data-manager.h"
|
||||
#include "model-manager.h"
|
||||
#include "app-model.h"
|
||||
#include "event-track.h"
|
||||
#include "favorites-config.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QMenu>
|
||||
|
||||
#define FOLDER_FILE_PATH ".config/ukui-menu/"
|
||||
#define FOLDER_FILE_NAME "folder0.json"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
QString FavoriteFolderHelper::s_folderConfigFile = QDir::homePath() + "/" + FOLDER_FILE_PATH + FOLDER_FILE_NAME;
|
||||
|
||||
FavoriteFolderHelper *FavoriteFolderHelper::instance()
|
||||
{
|
||||
static FavoriteFolderHelper FavoriteFolderHelper;
|
||||
return &FavoriteFolderHelper;
|
||||
}
|
||||
|
||||
FavoriteFolderHelper::FavoriteFolderHelper()
|
||||
{
|
||||
qRegisterMetaType<FavoritesFolder>("FavoritesFolder");
|
||||
|
||||
if (!QFile::exists(s_folderConfigFile)) {
|
||||
QDir dir;
|
||||
QString folderConfigDir(QDir::homePath() + "/" + FOLDER_FILE_PATH);
|
||||
if (!dir.exists(folderConfigDir)) {
|
||||
if (!dir.mkdir(folderConfigDir)) {
|
||||
qWarning() << "Unable to create profile folder.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file(s_folderConfigFile);
|
||||
file.open(QFile::WriteOnly);
|
||||
file.close();
|
||||
}
|
||||
|
||||
readData();
|
||||
}
|
||||
|
||||
FavoriteFolderHelper::~FavoriteFolderHelper()
|
||||
{
|
||||
saveData();
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::insertFolder(const FavoritesFolder &folder)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_folders.insert(folder.id, folder);
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::addAppToFolder(const QString &appId, const int &folderId)
|
||||
{
|
||||
if (appId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!m_folders.contains(folderId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FavoritesFolder &folder = m_folders[folderId];
|
||||
if (folder.apps.contains(appId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
folder.apps.append(appId);
|
||||
}
|
||||
|
||||
forceSync();
|
||||
Q_EMIT folderDataChanged(folderId,appId);
|
||||
|
||||
EventTrack::instance()->sendDefaultEvent("add_app_to_folder", "AppView");
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::addAppToNewFolder(const QString &appId, const QString &folderName)
|
||||
{
|
||||
if (appId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: max越界处理
|
||||
int max = m_folders.isEmpty() ? -1 : m_folders.lastKey();
|
||||
QString name = folderName;
|
||||
if (name.isEmpty()) {
|
||||
name = tr("New Folder %1").arg(m_folders.size() + 1);
|
||||
}
|
||||
|
||||
FavoritesFolder folder;
|
||||
folder.id = ++max;
|
||||
folder.name = name;
|
||||
folder.apps.append(appId);
|
||||
|
||||
insertFolder(folder);
|
||||
forceSync();
|
||||
Q_EMIT folderAdded(folder.id, FavoritesConfig::instance().getOrderById(appId));
|
||||
|
||||
EventTrack::instance()->sendDefaultEvent("add_app_to_new_folder", "AppView");
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::addAppsToNewFolder(const QString &idFrom, const QString &idTo, const QString &folderName)
|
||||
{
|
||||
if (idFrom.isEmpty() || idTo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: max越界处理
|
||||
int max = m_folders.isEmpty() ? -1 : m_folders.lastKey();
|
||||
QString name = folderName;
|
||||
if (name.isEmpty()) {
|
||||
name = tr("New Folder %1").arg(m_folders.size() + 1);
|
||||
}
|
||||
|
||||
FavoritesFolder folder;
|
||||
folder.id = ++max;
|
||||
folder.name = name;
|
||||
folder.apps.append(idFrom);
|
||||
folder.apps.append(idTo);
|
||||
|
||||
insertFolder(folder);
|
||||
Q_EMIT folderAdded(folder.id, FavoritesConfig::instance().getOrderById(idTo));
|
||||
forceSync();
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::removeAppFromFolder(const QString& appId)
|
||||
{
|
||||
if (appId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int folderId;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
for (const auto &folder: m_folders) {
|
||||
if (folder.apps.contains(appId)) {
|
||||
folderId = folder.getId();
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_folders.contains(folderId)) {
|
||||
return;
|
||||
}
|
||||
FavoritesFolder &folder = m_folders[folderId];
|
||||
if (!folder.apps.contains(appId)) {
|
||||
return;
|
||||
}
|
||||
folder.apps.removeOne(appId);
|
||||
}
|
||||
|
||||
if (m_folders[folderId].getApps().isEmpty()) {
|
||||
deleteFolder(folderId);
|
||||
}
|
||||
|
||||
forceSync();
|
||||
Q_EMIT folderDataChanged(folderId, appId);
|
||||
}
|
||||
|
||||
bool FavoriteFolderHelper::deleteFolder(const int& folderId)
|
||||
{
|
||||
Q_EMIT folderToBeDeleted(folderId, m_folders[folderId].getApps());
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!m_folders.contains(folderId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_folders.remove(folderId)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
forceSync();
|
||||
EventTrack::instance()->sendDefaultEvent("delete_folder", "AppView");
|
||||
return true;
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::renameFolder(const int &folderId, const QString &folderName)
|
||||
{
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!m_folders.contains(folderId)) {
|
||||
return;
|
||||
}
|
||||
if (m_folders[folderId].name == folderName) {
|
||||
return;
|
||||
}
|
||||
m_folders[folderId].name = folderName;
|
||||
}
|
||||
|
||||
Q_EMIT folderDataChanged(folderId, "");
|
||||
forceSync();
|
||||
}
|
||||
|
||||
QList<FavoritesFolder> FavoriteFolderHelper::folderData()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return m_folders.values();
|
||||
}
|
||||
|
||||
bool FavoriteFolderHelper::getFolderFromId(const int &folderId, FavoritesFolder& folder)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (!m_folders.contains(folderId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const FavoritesFolder &tmp = m_folders[folderId];
|
||||
folder = tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FavoriteFolderHelper::containApp(const QString &appId)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
return std::any_of(m_folders.constBegin(), m_folders.constEnd(), [appId] (const FavoritesFolder &folder) {
|
||||
return folder.apps.contains(appId);
|
||||
});
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::forceSync()
|
||||
{
|
||||
saveData();
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::readData()
|
||||
{
|
||||
QFile file(s_folderConfigFile);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取json数据
|
||||
QByteArray byteArray = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonDocument jsonDocument(QJsonDocument::fromJson(byteArray));
|
||||
if (jsonDocument.isNull() || jsonDocument.isEmpty() || !jsonDocument.isArray()) {
|
||||
qWarning() << "FavoriteFolderHelper: Incorrect configuration files are ignored.";
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_folders.clear();
|
||||
}
|
||||
|
||||
// 遍历json数据节点
|
||||
QJsonArray jsonArray = jsonDocument.array();
|
||||
for (const auto &value : jsonArray) {
|
||||
QJsonObject object = value.toObject();
|
||||
if (object.contains("name") && object.contains("id") && object.contains("apps")) {
|
||||
FavoritesFolder folder;
|
||||
folder.name = object.value(QLatin1String("name")).toString();
|
||||
folder.id = object.value(QLatin1String("id")).toInt();
|
||||
|
||||
QJsonArray apps = object.value(QLatin1String("apps")).toArray();
|
||||
for (const auto &app : apps) {
|
||||
folder.apps.append(app.toString());
|
||||
}
|
||||
|
||||
if (!folder.apps.isEmpty()) {
|
||||
insertFolder(folder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FavoriteFolderHelper::saveData()
|
||||
{
|
||||
QFile file(s_folderConfigFile);
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonDocument jsonDocument;
|
||||
QJsonArray folderArray;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
for (const auto &folder : m_folders) {
|
||||
QJsonObject object;
|
||||
QJsonArray apps;
|
||||
|
||||
for (const auto &app : folder.apps) {
|
||||
apps.append(app);
|
||||
}
|
||||
|
||||
object.insert("name", folder.name);
|
||||
object.insert("id", folder.id);
|
||||
object.insert("apps", apps);
|
||||
|
||||
folderArray.append(object);
|
||||
}
|
||||
}
|
||||
|
||||
jsonDocument.setArray(folderArray);
|
||||
|
||||
if (file.write(jsonDocument.toJson()) == -1) {
|
||||
qWarning() << "Error saving configuration file.";
|
||||
}
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
QStringList FavoriteFolderHelper::folderIcon(const FavoritesFolder &folder)
|
||||
{
|
||||
// TODO: 使用绘图API生成图片
|
||||
QStringList icons;
|
||||
DataEntity app;
|
||||
|
||||
int count = qMin(folder.apps.count(), FOLDER_MAX_ICON_NUM);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (AppDataManager::instance()->getApp(folder.apps.at(i), app)) {
|
||||
icons.append(app.icon());
|
||||
}
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (C) 2022, 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_FAVORITE_FOLDER_HELPER_H
|
||||
#define UKUI_MENU_FAVORITE_FOLDER_HELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QMutexLocker>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
#define FOLDER_MAX_ICON_NUM 16
|
||||
|
||||
class FavoriteFolderHelper;
|
||||
|
||||
class FavoritesFolder
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROPERTY(int id READ getId WRITE setId)
|
||||
Q_PROPERTY(QString name READ getName)
|
||||
Q_PROPERTY(QStringList apps READ getApps)
|
||||
friend class FavoriteFolderHelper;
|
||||
public:
|
||||
void setId(int folderId) {id = folderId;}
|
||||
int getId() const { return id; }
|
||||
QString getName() const { return name; }
|
||||
QStringList getApps() const { return apps; }
|
||||
|
||||
private:
|
||||
int id; // 文件夹唯一Id,文件夹排序值
|
||||
QString name; // 名称
|
||||
QStringList apps; // 应用列表
|
||||
};
|
||||
|
||||
class FavoriteFolderHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static FavoriteFolderHelper *instance();
|
||||
static QStringList folderIcon(const FavoritesFolder &folder);
|
||||
~FavoriteFolderHelper() override;
|
||||
|
||||
bool getFolderFromId(const int& folderId, FavoritesFolder& folder);
|
||||
bool containApp(const QString& appId);
|
||||
|
||||
QList<FavoritesFolder> folderData();
|
||||
|
||||
void addAppToFolder(const QString& appId, const int& folderId);
|
||||
void addAppToNewFolder(const QString& appId, const QString& folderName);
|
||||
void addAppsToNewFolder(const QString& idFrom, const QString& idTo, const QString& folderName);
|
||||
void removeAppFromFolder(const QString& appId);
|
||||
bool deleteFolder(const int& folderId);
|
||||
void renameFolder(const int& folderId, const QString& folderName);
|
||||
|
||||
void forceSync();
|
||||
|
||||
Q_SIGNALS:
|
||||
void folderAdded(int folderId, const int& order);
|
||||
void folderToBeDeleted(int folderId, const QStringList& apps);
|
||||
void folderDataChanged(int folderId, const QString& app);
|
||||
|
||||
private:
|
||||
FavoriteFolderHelper();
|
||||
void readData();
|
||||
void saveData();
|
||||
void insertFolder(const FavoritesFolder& folder);
|
||||
// TODO 配置文件监听
|
||||
|
||||
private:
|
||||
QMutex m_mutex;
|
||||
//TODO 指针
|
||||
QMap<int, FavoritesFolder> m_folders;
|
||||
static QString s_folderConfigFile;
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_FAVORITE_FOLDER_HELPER_H
|
|
@ -17,6 +17,8 @@
|
|||
*/
|
||||
|
||||
#include "favorite-widget.h"
|
||||
#include "app-favorite-model.h"
|
||||
#include "favorites-model.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
|
@ -31,6 +33,10 @@ FavoriteWidget::FavoriteWidget(QObject *parent) : WidgetExtension(parent)
|
|||
m_metadata.insert(WidgetMetadata::Main, "qrc:///qml/extensions/FavoriteExtension.qml");
|
||||
m_metadata.insert(WidgetMetadata::Type, WidgetMetadata::Widget);
|
||||
m_metadata.insert(WidgetMetadata::Flag, WidgetMetadata::Normal);
|
||||
|
||||
FavoritesModel::instance().setSourceModel(&AppFavoritesModel::instance());
|
||||
FavoritesModel::instance().sort(0);
|
||||
m_data.insert("favoriteAppsModel", QVariant::fromValue(&FavoritesModel::instance()));
|
||||
}
|
||||
|
||||
int FavoriteWidget::index() const
|
||||
|
@ -45,7 +51,7 @@ MetadataMap FavoriteWidget::metadata() const
|
|||
|
||||
QVariantMap FavoriteWidget::data()
|
||||
{
|
||||
return WidgetExtension::data();
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void FavoriteWidget::receive(const QVariantMap &data)
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
|
||||
private:
|
||||
MetadataMap m_metadata;
|
||||
QVariantMap m_data;
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-27.
|
||||
//
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include "favorites-config.h"
|
||||
|
||||
#define FOLDER_FILE_PATH ".config/ukui-menu/"
|
||||
#define FOLDER_FILE_NAME "favorite.json"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
QString FavoritesConfig::s_favoritesConfigFile = QDir::homePath() + "/" + FOLDER_FILE_PATH + FOLDER_FILE_NAME;
|
||||
|
||||
FavoritesConfig &FavoritesConfig::instance()
|
||||
{
|
||||
static FavoritesConfig favoritesConfig;
|
||||
return favoritesConfig;
|
||||
}
|
||||
|
||||
FavoritesConfig::FavoritesConfig(QObject *parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QJsonObject FavoritesConfig::getValue(const int &index) const
|
||||
{
|
||||
if (index < 0 || index > arrayFromConfigFile().count()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return arrayFromConfigFile().at(index).toObject();
|
||||
}
|
||||
|
||||
void FavoritesConfig::insertValue(const QString &id, const int &index)
|
||||
{
|
||||
QJsonArray array = arrayFromConfigFile();
|
||||
if (indexOfObject(id, array) > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject object;
|
||||
object.insert("id", id);
|
||||
array.insert(index, object);
|
||||
|
||||
setArrayToConfigFile(array);
|
||||
}
|
||||
|
||||
void FavoritesConfig::removeValueById(const QString &id)
|
||||
{
|
||||
QJsonArray array = arrayFromConfigFile();
|
||||
int index = indexOfObject(id, array);
|
||||
|
||||
if (index > -1 && index < array.size()) {
|
||||
array.removeAt(index);
|
||||
}
|
||||
|
||||
setArrayToConfigFile(array);
|
||||
}
|
||||
|
||||
void FavoritesConfig::forceSync()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString FavoritesConfig::configFile() const
|
||||
{
|
||||
return s_favoritesConfigFile;
|
||||
}
|
||||
|
||||
void FavoritesConfig::initConfig(const QStringList &apps)
|
||||
{
|
||||
QJsonArray favoritesArray;
|
||||
|
||||
for (const auto &appId : apps) {
|
||||
QJsonObject object;
|
||||
object.insert("id", appId);
|
||||
favoritesArray.append(object);
|
||||
}
|
||||
|
||||
setArrayToConfigFile(favoritesArray);
|
||||
}
|
||||
|
||||
void FavoritesConfig::setArrayToConfigFile(const QJsonArray &array)
|
||||
{
|
||||
QDir dir;
|
||||
QString folderConfigDir(QDir::homePath() + "/" + FOLDER_FILE_PATH);
|
||||
if (!dir.exists(folderConfigDir)) {
|
||||
if (!dir.mkdir(folderConfigDir)) {
|
||||
qWarning() << "Unable to create profile favorites.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file(s_favoritesConfigFile);
|
||||
file.open(QFile::WriteOnly);
|
||||
|
||||
QJsonDocument jsonDocument;
|
||||
jsonDocument.setArray(array);
|
||||
|
||||
if (file.write(jsonDocument.toJson()) == -1) {
|
||||
qWarning() << "Error saving configuration file.";
|
||||
}
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
Q_EMIT configChanged();
|
||||
}
|
||||
|
||||
QJsonArray FavoritesConfig::arrayFromConfigFile() const
|
||||
{
|
||||
QFile file(s_favoritesConfigFile);
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
QJsonDocument jsonDocument(QJsonDocument::fromJson(file.readAll()));
|
||||
file.close();
|
||||
|
||||
if (jsonDocument.isNull() || jsonDocument.isEmpty() || !jsonDocument.isArray()) {
|
||||
qWarning() << "AppFolderHelper: Incorrect configuration files are ignored.";
|
||||
return {};
|
||||
}
|
||||
|
||||
return jsonDocument.array();
|
||||
}
|
||||
|
||||
int FavoritesConfig::indexOfObject(const QString &id, const QJsonArray &array)
|
||||
{
|
||||
if (id.isEmpty()) {
|
||||
qWarning() << "id is unavailable!";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
if (array.at(i).toObject().contains("id")) {
|
||||
if (array.at(i).toObject().value("id").toString() == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FavoritesConfig::getOrderById(const QString &id)
|
||||
{
|
||||
return indexOfObject(id, arrayFromConfigFile());
|
||||
}
|
||||
|
||||
void FavoritesConfig::changeOrder(const int &indexFrom, const int &indexTo)
|
||||
{
|
||||
QVariantList list = arrayFromConfigFile().toVariantList();
|
||||
list.move(indexFrom, indexTo);
|
||||
setArrayToConfigFile(QJsonArray::fromVariantList(list));
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-27.
|
||||
//
|
||||
|
||||
#ifndef UKUI_MENU_FAVORITES_CONFIG_H
|
||||
#define UKUI_MENU_FAVORITES_CONFIG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class FavoritesConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static FavoritesConfig &instance();
|
||||
|
||||
QJsonObject getValue(const int &index) const;
|
||||
void insertValue(const QString &id, const int &index = 0);
|
||||
void removeValueById(const QString &id);
|
||||
int getOrderById(const QString &id);
|
||||
void changeOrder(const int &indexFrom, const int &indexTo);
|
||||
|
||||
void forceSync();
|
||||
QString configFile() const;
|
||||
void initConfig(const QStringList &apps);
|
||||
|
||||
Q_SIGNALS:
|
||||
void configChanged();
|
||||
|
||||
private:
|
||||
explicit FavoritesConfig(QObject *parent = nullptr);
|
||||
void setArrayToConfigFile(const QJsonArray &array);
|
||||
QJsonArray arrayFromConfigFile() const;
|
||||
int indexOfObject(const QString &id, const QJsonArray &array);
|
||||
|
||||
private:
|
||||
static QString s_favoritesConfigFile;
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_FAVORITES_CONFIG_H
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-28.
|
||||
//
|
||||
#include <QDir>
|
||||
|
||||
#include "../context-menu-manager.h"
|
||||
#include "favorites-model.h"
|
||||
#include "app-favorite-model.h"
|
||||
#include "favorite-folder-helper.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
FavoritesModel &FavoritesModel::instance()
|
||||
{
|
||||
static FavoritesModel favoritesModel;
|
||||
return favoritesModel;
|
||||
}
|
||||
|
||||
FavoritesModel::FavoritesModel(QObject *parent) : QSortFilterProxyModel(parent)
|
||||
{
|
||||
connect(&FavoritesConfig::instance(), &FavoritesConfig::configChanged, this, &FavoritesModel::invalidate);
|
||||
}
|
||||
|
||||
bool FavoritesModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
QVariant leftId = sourceModel()->data(source_left, DataEntity::Id);
|
||||
QVariant rightId = sourceModel()->data(source_right, DataEntity::Id);
|
||||
|
||||
int leftIndex = -1;
|
||||
int rightIndex = -1;
|
||||
for (int i = 0; i < sourceModel()->rowCount(); i++) {
|
||||
QJsonObject object = FavoritesConfig::instance().getValue(i);
|
||||
if (object.contains("id")) {
|
||||
if (object.value(QLatin1String("id")).toString() == leftId) {
|
||||
leftIndex = i;
|
||||
} else if (object.value(QLatin1String("id")).toString() == rightId) {
|
||||
rightIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((leftIndex != -1) && (rightIndex != -1)) {
|
||||
return leftIndex < rightIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// 对应Id没有在配置文件中找到
|
||||
return true;
|
||||
}
|
||||
|
||||
void FavoritesModel::openMenu(const int &row)
|
||||
{
|
||||
if (row < 0 || row >= sourceModel()->rowCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DataEntity data;
|
||||
data.setId(sourceModel()->data(mapToSource(index(row, 0)), DataEntity::Id).toString());
|
||||
data.setFavorite(sourceModel()->data(mapToSource(index(row, 0)), DataEntity::Favorite).toInt());
|
||||
data.setType(sourceModel()->data(mapToSource(index(row, 0)), DataEntity::Type).value<DataType::Type>());
|
||||
|
||||
ContextMenuManager::instance()->showMenu(data, MenuInfo::Extension, "favorite");
|
||||
}
|
||||
|
||||
void FavoritesModel::addAppToFavorites(const QString &id, const int &index)
|
||||
{
|
||||
AppFavoritesModel::instance().changeAppState(id, index);
|
||||
}
|
||||
|
||||
void FavoritesModel::removeAppFromFavorites(const QString &id)
|
||||
{
|
||||
AppFavoritesModel::instance().changeAppState(id, 0);
|
||||
}
|
||||
|
||||
void FavoritesModel::exchangedAppsOrder(const int &indexFrom, const int &indexTo)
|
||||
{
|
||||
FavoritesConfig::instance().changeOrder(indexFrom, indexTo);
|
||||
}
|
||||
|
||||
void FavoritesModel::addAppsToNewFolder(const QString &idFrom, const QString &idTo)
|
||||
{
|
||||
FavoriteFolderHelper::instance()->addAppsToNewFolder(idFrom, idTo, "");
|
||||
}
|
||||
|
||||
void FavoritesModel::addAppToFolder(const QString &appId, const QString &folderId)
|
||||
{
|
||||
if (folderId == "") {
|
||||
FavoriteFolderHelper::instance()->addAppToNewFolder(appId, "");
|
||||
return;
|
||||
}
|
||||
|
||||
FavoriteFolderHelper::instance()->addAppToFolder(appId, folderId.toInt());
|
||||
}
|
||||
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Created by qiqi on 23-12-28.
|
||||
//
|
||||
|
||||
#ifndef UKUI_MENU_FAVORITES_MODEL_H
|
||||
#define UKUI_MENU_FAVORITES_MODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include "favorites-config.h"
|
||||
#include "app-favorite-model.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class FavoritesModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static FavoritesModel &instance();
|
||||
|
||||
Q_INVOKABLE void openMenu(const int &row);
|
||||
Q_INVOKABLE void addAppToFavorites(const QString &id, const int &index = 1);
|
||||
Q_INVOKABLE void removeAppFromFavorites(const QString &id);
|
||||
/**
|
||||
* 拖拽交换位置。
|
||||
* @param indexFrom
|
||||
* @param indexTo
|
||||
*/
|
||||
Q_INVOKABLE void exchangedAppsOrder(const int &indexFrom, const int &indexTo);
|
||||
/**
|
||||
* 两个应用推拽合并为应用组。
|
||||
* @param idFrom
|
||||
* @param idTo 拖拽至某一应用,并在该位置创建应用组
|
||||
*/
|
||||
Q_INVOKABLE void addAppsToNewFolder(const QString &idFrom, const QString &idTo);
|
||||
/**
|
||||
* 添加应用到应用组,包括新建应用组。
|
||||
* @param appId
|
||||
* @param folderId id为""时,新建应用组;id为数值时,添加至对应应用组
|
||||
*/
|
||||
Q_INVOKABLE void addAppToFolder(const QString &appId, const QString& folderId);
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
|
||||
private:
|
||||
explicit FavoritesModel(QObject *parent = nullptr);
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_FAVORITES_MODEL_H
|
|
@ -71,7 +71,7 @@ QList<QAction *> AppContentMenu::actions(const DataEntity &data, QMenu *parent,
|
|||
case MenuInfo::Extension:
|
||||
case MenuInfo::FolderPage:
|
||||
case MenuInfo::FullScreen:
|
||||
case MenuInfo::FullScreenFolder:
|
||||
case MenuInfo::Folder:
|
||||
// 卸载
|
||||
addToPanelAction(parent, appId, list);
|
||||
// 添加到任务栏
|
||||
|
|
|
@ -38,6 +38,7 @@ class AppDatabaseWorkerPrivate : public QObject
|
|||
public:
|
||||
explicit AppDatabaseWorkerPrivate(AppDatabaseInterface *parent = nullptr);
|
||||
DataEntityVector getAllApps();
|
||||
bool getApp(const QString &appid, DataEntity &app);
|
||||
|
||||
// 数据库操作函数
|
||||
void setAppProperty(const QString &appid, const UkuiSearch::ApplicationPropertyMap &propertyMap);
|
||||
|
@ -317,6 +318,17 @@ void AppDatabaseWorkerPrivate::setAppProperty(const QString &appid, const UkuiSe
|
|||
}
|
||||
}
|
||||
|
||||
bool AppDatabaseWorkerPrivate::getApp(const QString &appid, DataEntity &app)
|
||||
{
|
||||
if (appid.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const UkuiSearch::ApplicationPropertyMap appInfo = appDatabase->getInfo(appid, properties);
|
||||
addInfoToApp(appInfo, app);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ====== AppDatabaseInterface ====== //
|
||||
AppDatabaseInterface::AppDatabaseInterface(QObject *parent) : QObject(parent), d(new AppDatabaseWorkerPrivate(this))
|
||||
{
|
||||
|
@ -328,7 +340,7 @@ DataEntityVector AppDatabaseInterface::apps() const
|
|||
return d->getAllApps();
|
||||
}
|
||||
|
||||
void AppDatabaseInterface::fixAppToTop(const QString &appid, int index)
|
||||
void AppDatabaseInterface::fixAppToTop(const QString &appid, int index) const
|
||||
{
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
|
@ -337,7 +349,7 @@ void AppDatabaseInterface::fixAppToTop(const QString &appid, int index)
|
|||
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Top, index);
|
||||
}
|
||||
|
||||
void AppDatabaseInterface::fixAppToFavorite(const QString &appid, int index)
|
||||
void AppDatabaseInterface::fixAppToFavorite(const QString &appid, int index) const
|
||||
{
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
|
@ -346,11 +358,16 @@ void AppDatabaseInterface::fixAppToFavorite(const QString &appid, int index)
|
|||
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Favorites, index);
|
||||
}
|
||||
|
||||
void AppDatabaseInterface::updateApLaunchedState(const QString &appid, bool state)
|
||||
void AppDatabaseInterface::updateApLaunchedState(const QString &appid, bool state) const
|
||||
{
|
||||
d->setAppProperty(appid, UkuiSearch::ApplicationProperty::Launched, state);
|
||||
}
|
||||
|
||||
bool AppDatabaseInterface::getApp(const QString &appid, DataEntity &app) const
|
||||
{
|
||||
return d->getApp(appid, app);
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#include "app-database-interface.moc"
|
||||
|
|
|
@ -45,26 +45,32 @@ public:
|
|||
* @return
|
||||
*/
|
||||
DataEntityVector apps() const;
|
||||
/**
|
||||
* 从数据库获取单个应用
|
||||
* @param appid 应用id
|
||||
* @param app 获取应用
|
||||
*/
|
||||
bool getApp(const QString &appid, DataEntity &app) const;
|
||||
|
||||
/**
|
||||
* 置顶应用
|
||||
* @param appid 应用id
|
||||
* @param index 置顶后的位置,小于或等于0将会取消置顶
|
||||
*/
|
||||
void fixAppToTop(const QString &appid, int index);
|
||||
void fixAppToTop(const QString &appid, int index) const;
|
||||
|
||||
/**
|
||||
* 收藏应用
|
||||
* @param appid 应用id
|
||||
* @param index 收藏后的位置,小于或等于0将会取消收藏
|
||||
*/
|
||||
void fixAppToFavorite(const QString &appid, int index);
|
||||
void fixAppToFavorite(const QString &appid, int index) const;
|
||||
|
||||
/**
|
||||
* 设置应用是否已经被启动过
|
||||
* @param state 状态值,true已被启动,false未被启动
|
||||
*/
|
||||
void updateApLaunchedState(const QString &appid, bool state = true);
|
||||
void updateApLaunchedState(const QString &appid, bool state = true) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
|
|
|
@ -136,7 +136,7 @@ void BasicAppModel::onAppUpdated(const QVector<QPair<DataEntity, QVector<int> >
|
|||
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));
|
||||
app.setValue(static_cast<DataEntity::PropertyName>(role), pair.first.getValue(static_cast<DataEntity::PropertyName>(role)));
|
||||
}
|
||||
} else {
|
||||
app = pair.first;
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
*/
|
||||
const AppDatabaseInterface *databaseInterface() const;
|
||||
DataEntity appOfIndex(int row) const;
|
||||
int indexOfApp(const QString &appid) const;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
|
@ -55,7 +56,6 @@ private Q_SLOTS:
|
|||
|
||||
private:
|
||||
explicit BasicAppModel(QObject *parent = nullptr);
|
||||
int indexOfApp(const QString &appid) const;
|
||||
AppDatabaseInterface *m_databaseInterface {nullptr};
|
||||
|
||||
QVector<DataEntity> m_apps;
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
#include "folder-model.h"
|
||||
#include "app-folder-helper.h"
|
||||
#include "app-data-manager.h"
|
||||
#include "favorite/favorite-folder-helper.h"
|
||||
#include "context-menu-manager.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
FolderModel::FolderModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
connect(AppFolderHelper::instance(), &AppFolderHelper::folderDataChanged, this, &FolderModel::loadFolderData);
|
||||
connect(AppFolderHelper::instance(), &AppFolderHelper::folderDeleted, this, [this] (int id) {
|
||||
connect(FavoriteFolderHelper::instance(), &FavoriteFolderHelper::folderDataChanged, this, &FolderModel::loadFolderData);
|
||||
connect(FavoriteFolderHelper::instance(), &FavoriteFolderHelper::folderToBeDeleted, this, [this] (int id) {
|
||||
if (id == m_folderId) {
|
||||
beginResetModel();
|
||||
m_folderId = -1;
|
||||
|
@ -48,13 +50,13 @@ void FolderModel::setFolderId(const QString &folderId)
|
|||
|
||||
void FolderModel::renameFolder(const QString &folderName)
|
||||
{
|
||||
AppFolderHelper::instance()->renameFolder(m_folderId, folderName);
|
||||
FavoriteFolderHelper::instance()->renameFolder(m_folderId, folderName);
|
||||
}
|
||||
|
||||
void FolderModel::loadFolderData(int id)
|
||||
{
|
||||
Folder folder;
|
||||
if (!AppFolderHelper::instance()->searchFolder(id, folder)) {
|
||||
FavoritesFolder folder;
|
||||
if (!FavoriteFolderHelper::instance()->getFolderFromId(id, folder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue