feat: 添加应用列表插件接口,搜索插件和分类插件
This commit is contained in:
parent
f3e9858b88
commit
1e34114387
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "app-category-plugin.h"
|
||||
#include "combined-list-model.h"
|
||||
#include "app-category-model.h"
|
||||
#include "recently-installed-model.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
AppCategoryPlugin::AppCategoryPlugin(QObject *parent) : AppListPluginInterface(parent)
|
||||
, m_dataModel(new CombinedListModel(this))
|
||||
{
|
||||
auto categoryModel = new AppCategoryModel(this);
|
||||
auto recentlyModel = new RecentlyInstalledModel(this);
|
||||
|
||||
m_dataModel->insertSubModel(recentlyModel);
|
||||
m_dataModel->insertSubModel(categoryModel);
|
||||
|
||||
auto categoryAction = new QAction(QIcon::fromTheme("applications-utilities-symbolic"), tr("Category"), this);
|
||||
auto firstLatterAction = new QAction(QIcon::fromTheme("ukui-capslock-symbolic"), tr("Letter Sort"), this);
|
||||
|
||||
categoryAction->setCheckable(true);
|
||||
firstLatterAction->setCheckable(true);
|
||||
|
||||
connect(categoryAction, &QAction::triggered, this, [=] {
|
||||
categoryModel->setMode(AppCategoryModel::Category);
|
||||
categoryAction->setChecked(true);
|
||||
firstLatterAction->setChecked(false);
|
||||
setTitle(categoryAction->text());
|
||||
});
|
||||
connect(firstLatterAction, &QAction::triggered, this, [=] {
|
||||
categoryModel->setMode(AppCategoryModel::FirstLatter);
|
||||
categoryAction->setChecked(false);
|
||||
firstLatterAction->setChecked(true);
|
||||
setTitle(firstLatterAction->text());
|
||||
});
|
||||
|
||||
m_actions.append(categoryAction);
|
||||
m_actions.append(firstLatterAction);
|
||||
|
||||
categoryAction->setChecked(true);
|
||||
setTitle(categoryAction->text());
|
||||
}
|
||||
|
||||
QString AppCategoryPlugin::name()
|
||||
{
|
||||
return QStringLiteral("AppCategoryPlugin");
|
||||
}
|
||||
|
||||
QList<QAction *> AppCategoryPlugin::actions()
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
QAbstractItemModel *AppCategoryPlugin::dataModel()
|
||||
{
|
||||
return m_dataModel;
|
||||
}
|
||||
|
||||
AppListPluginGroup::Group AppCategoryPlugin::group()
|
||||
{
|
||||
return AppListPluginGroup::Display;
|
||||
}
|
||||
|
||||
QString AppCategoryPlugin::title()
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void AppCategoryPlugin::setTitle(const QString &title)
|
||||
{
|
||||
if (title == m_title) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_title = title;
|
||||
Q_EMIT titleChanged();
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_APP_CATEGORY_PLUGIN_H
|
||||
#define UKUI_MENU_APP_CATEGORY_PLUGIN_H
|
||||
|
||||
#include "app-list-plugin.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class CombinedListModel;
|
||||
|
||||
class AppCategoryPlugin : public AppListPluginInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppCategoryPlugin(QObject *parent = nullptr);
|
||||
|
||||
AppListPluginGroup::Group group() override;
|
||||
QString name() override;
|
||||
QString title() override;
|
||||
QList<QAction *> actions() override;
|
||||
QAbstractItemModel *dataModel() override;
|
||||
|
||||
private:
|
||||
void setTitle(const QString &title);
|
||||
|
||||
private:
|
||||
QString m_title;
|
||||
QList<QAction *> m_actions;
|
||||
CombinedListModel *m_dataModel {nullptr};
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_APP_CATEGORY_PLUGIN_H
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "app-list-model.h"
|
||||
#include "data-entity.h"
|
||||
#include "context-menu-manager.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
AppListHeader::AppListHeader(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString AppListHeader::title() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void AppListHeader::setTitle(const QString &title)
|
||||
{
|
||||
if (title == m_title) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_title = title;
|
||||
Q_EMIT titleChanged();
|
||||
}
|
||||
|
||||
QList<QAction*> AppListHeader::actions() const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
void AppListHeader::addAction(QAction *action)
|
||||
{
|
||||
if (m_actions.indexOf(action) >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_actions.append(action);
|
||||
Q_EMIT actionsChanged();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
bool AppListHeader::visible() const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
void AppListHeader::setVisible(bool visible)
|
||||
{
|
||||
if (m_visible == visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_visible = visible;
|
||||
Q_EMIT visibleChanged();
|
||||
}
|
||||
|
||||
void AppListHeader::removeAction(QAction *action)
|
||||
{
|
||||
if (m_actions.removeOne(action)) {
|
||||
Q_EMIT actionsChanged();
|
||||
setVisible(!m_actions.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
void AppListHeader::removeAllAction()
|
||||
{
|
||||
m_actions.clear();
|
||||
Q_EMIT actionsChanged();
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
// ====== //
|
||||
AppListModel::AppListModel(QObject *parent) : QSortFilterProxyModel(parent), m_header(new AppListHeader(this))
|
||||
{
|
||||
qRegisterMetaType<UkuiMenu::AppListModel*>();
|
||||
qRegisterMetaType<UkuiMenu::AppListHeader*>();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> AppListModel::roleNames() const
|
||||
{
|
||||
return DataEntity::AppRoleNames();
|
||||
}
|
||||
|
||||
AppListHeader *AppListModel::getHeader() const
|
||||
{
|
||||
return m_header;
|
||||
}
|
||||
|
||||
void AppListModel::installPlugin(AppListPluginInterface *plugin)
|
||||
{
|
||||
if (!plugin || m_plugin == plugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
unInstallPlugin();
|
||||
|
||||
m_plugin = plugin;
|
||||
QSortFilterProxyModel::setSourceModel(plugin->dataModel());
|
||||
|
||||
for (const auto &action : plugin->actions()) {
|
||||
m_header->addAction(action);
|
||||
}
|
||||
|
||||
m_header->setTitle(plugin->title());
|
||||
connect(m_plugin, &AppListPluginInterface::titleChanged, this, [this, plugin] {
|
||||
m_header->setTitle(plugin->title());
|
||||
});
|
||||
}
|
||||
|
||||
void AppListModel::unInstallPlugin()
|
||||
{
|
||||
if (!m_plugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_header->setTitle("");
|
||||
m_header->removeAllAction();
|
||||
QSortFilterProxyModel::setSourceModel(nullptr);
|
||||
disconnect(m_plugin, nullptr, this, nullptr);
|
||||
m_plugin = nullptr;
|
||||
}
|
||||
|
||||
void AppListModel::openMenu(const int &index, MenuInfo::Location location) const
|
||||
{
|
||||
QModelIndex idx = AppListModel::index(index, 0);
|
||||
if (checkIndex(idx, CheckIndexOption::IndexIsValid)) {
|
||||
ContextMenuManager::instance()->showMenu(idx.data(DataEntity::Entity).value<DataEntity>(), location);
|
||||
}
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_APP_LIST_MODEL_H
|
||||
#define UKUI_MENU_APP_LIST_MODEL_H
|
||||
|
||||
#include "app-list-plugin.h"
|
||||
#include "context-menu-extension.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
/**
|
||||
* @class AppListHeader
|
||||
*
|
||||
* 应用列表顶部功能区域
|
||||
* 显示当前插件的操作选项,如果插件的action为空,那么不显示header.
|
||||
*/
|
||||
class AppListHeader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
|
||||
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
|
||||
Q_PROPERTY(QList<QAction*> actions READ actions NOTIFY actionsChanged)
|
||||
friend class AppListModel;
|
||||
public:
|
||||
explicit AppListHeader(QObject *parent = nullptr);
|
||||
|
||||
bool visible() const;
|
||||
void setVisible(bool visible);
|
||||
|
||||
QString title() const;
|
||||
void setTitle(const QString &title);
|
||||
|
||||
QList<QAction*> actions() const;
|
||||
void addAction(QAction *actions);
|
||||
void removeAction(QAction *actions);
|
||||
void removeAllAction();
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleChanged();
|
||||
void actionsChanged();
|
||||
void visibleChanged();
|
||||
|
||||
private:
|
||||
bool m_visible {false};
|
||||
QString m_title;
|
||||
QList<QAction*> m_actions;
|
||||
};
|
||||
|
||||
class AppListModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(UkuiMenu::AppListHeader *header READ getHeader NOTIFY headerChanged)
|
||||
public:
|
||||
explicit AppListModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* 覆盖全部roles,子model必须返回相同的roles
|
||||
* @return
|
||||
*/
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
AppListHeader *getHeader() const;
|
||||
|
||||
void installPlugin(AppListPluginInterface *plugin);
|
||||
// reset
|
||||
void unInstallPlugin();
|
||||
|
||||
Q_INVOKABLE void openMenu(const int &index, MenuInfo::Location location) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void headerChanged();
|
||||
|
||||
private:
|
||||
AppListHeader *m_header {nullptr};
|
||||
AppListPluginInterface *m_plugin {nullptr};
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
Q_DECLARE_METATYPE(UkuiMenu::AppListModel*)
|
||||
Q_DECLARE_METATYPE(UkuiMenu::AppListHeader*)
|
||||
|
||||
#endif //UKUI_MENU_APP_LIST_MODEL_H
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "app-list-plugin.h"
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
// ====== AppListPluginInterface ====== //
|
||||
AppListPluginInterface::AppListPluginInterface(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AppListPluginInterface::search(const QString &keyword)
|
||||
{
|
||||
Q_UNUSED(keyword)
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_APP_LIST_PLUGIN_H
|
||||
#define UKUI_MENU_APP_LIST_PLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
|
||||
class QAction;
|
||||
class QAbstractItemModel;
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class AppListPluginGroup
|
||||
{
|
||||
Q_GADGET
|
||||
public:
|
||||
enum Group {
|
||||
Display, /**> 应用展示模式 */
|
||||
Search /**> 应用搜索模式 */
|
||||
};
|
||||
Q_ENUM(Group)
|
||||
};
|
||||
|
||||
class AppListPluginInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppListPluginInterface(QObject *parent = nullptr);
|
||||
|
||||
virtual AppListPluginGroup::Group group() = 0;
|
||||
virtual QString name() = 0;
|
||||
virtual QString title() = 0;
|
||||
virtual QList<QAction*> actions() = 0;
|
||||
virtual QAbstractItemModel *dataModel() = 0;
|
||||
virtual void search(const QString &keyword);
|
||||
|
||||
Q_SIGNALS:
|
||||
void titleChanged();
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
Q_DECLARE_METATYPE(UkuiMenu::AppListPluginGroup::Group)
|
||||
|
||||
#endif //UKUI_MENU_APP_LIST_PLUGIN_H
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "app-page-backend.h"
|
||||
|
||||
#include "app-list-model.h"
|
||||
#include "app-category-plugin.h"
|
||||
#include "app-search-plugin.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
AppPageBackend::AppPageBackend(QObject *parent) : QObject(parent), m_appModel(new AppListModel(this))
|
||||
{
|
||||
auto searchPlugin = new AppSearchPlugin(this);
|
||||
auto categoryPlugin = new AppCategoryPlugin(this);
|
||||
|
||||
m_plugins.insert(searchPlugin->group(), searchPlugin);
|
||||
m_plugins.insert(categoryPlugin->group(), categoryPlugin);
|
||||
|
||||
switchGroup();
|
||||
}
|
||||
|
||||
AppListModel *AppPageBackend::appModel() const
|
||||
{
|
||||
return m_appModel;
|
||||
}
|
||||
|
||||
void AppPageBackend::startSearch(const QString &keyword)
|
||||
{
|
||||
if (m_group != AppListPluginGroup::Search) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto plugin = m_plugins.value(m_group, nullptr);
|
||||
if (plugin) {
|
||||
plugin->search(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
AppListPluginGroup::Group AppPageBackend::group() const
|
||||
{
|
||||
return AppListPluginGroup::Display;
|
||||
}
|
||||
|
||||
void AppPageBackend::setGroup(AppListPluginGroup::Group group)
|
||||
{
|
||||
if (m_group == group) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_group = group;
|
||||
switchGroup();
|
||||
Q_EMIT groupChanged();
|
||||
}
|
||||
|
||||
void AppPageBackend::switchGroup()
|
||||
{
|
||||
const auto plugin = m_plugins.value(m_group, nullptr);
|
||||
if (plugin) {
|
||||
m_appModel->installPlugin(plugin);
|
||||
} else {
|
||||
m_appModel->unInstallPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_APP_PAGE_BACKEND_H
|
||||
#define UKUI_MENU_APP_PAGE_BACKEND_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
class QAbstractItemModel;
|
||||
class QSortFilterProxyModel;
|
||||
|
||||
#include "app-list-plugin.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class AppListModel;
|
||||
|
||||
/**
|
||||
* 此类管理开始菜单的主体功能和接口
|
||||
*
|
||||
* 提供:应用搜索,应用分类模式的切换功能
|
||||
*
|
||||
*
|
||||
* AppPage
|
||||
* |
|
||||
* AppListHeader
|
||||
* AppList
|
||||
* / \
|
||||
* Search Display
|
||||
* | \
|
||||
* (Model Title Actions) (Model Title Actions)
|
||||
*
|
||||
*/
|
||||
class AppPageBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QAbstractItemModel *appModel READ appModel NOTIFY appModelChanged)
|
||||
Q_PROPERTY(UkuiMenu::AppListPluginGroup::Group group READ group WRITE setGroup NOTIFY groupChanged)
|
||||
public:
|
||||
explicit AppPageBackend(QObject *parent = nullptr);
|
||||
|
||||
// 开始菜单主要功能,显示应用列表
|
||||
AppListModel *appModel() const;
|
||||
Q_INVOKABLE void startSearch(const QString &keyword);
|
||||
|
||||
AppListPluginGroup::Group group() const;
|
||||
void setGroup(AppListPluginGroup::Group group);
|
||||
|
||||
Q_SIGNALS:
|
||||
void appModelChanged();
|
||||
void groupChanged();
|
||||
|
||||
private:
|
||||
void switchGroup();
|
||||
|
||||
private:
|
||||
AppListPluginGroup::Group m_group {AppListPluginGroup::Display};
|
||||
AppListModel *m_appModel {nullptr};
|
||||
QMap<AppListPluginGroup::Group, AppListPluginInterface*> m_plugins;
|
||||
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_APP_PAGE_BACKEND_H
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "app-search-plugin.h"
|
||||
#include "data-entity.h"
|
||||
|
||||
#include <UkuiSearchTask>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QAbstractListModel>
|
||||
#include <QDebug>
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
// ====== AppSearchPluginPrivate ======
|
||||
class AppSearchPluginPrivate : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppSearchPluginPrivate(QObject *parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void searchedOne(DataEntity app);
|
||||
|
||||
public Q_SLOTS:
|
||||
void startSearch(const QString &keyword);
|
||||
void stopSearch();
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
size_t m_searchId{0};
|
||||
QTimer *m_timer{nullptr};
|
||||
UkuiSearch::UkuiSearchTask *m_appSearchTask {nullptr};
|
||||
UkuiSearch::DataQueue<UkuiSearch::ResultItem> *m_dataQueue{nullptr};
|
||||
};
|
||||
|
||||
AppSearchPluginPrivate::AppSearchPluginPrivate(QObject *parent) : QThread(parent), m_appSearchTask(new UkuiSearch::UkuiSearchTask(this))
|
||||
{
|
||||
m_dataQueue = m_appSearchTask->init();
|
||||
|
||||
m_appSearchTask->initSearchPlugin(UkuiSearch::SearchProperty::SearchType::Application);
|
||||
m_appSearchTask->setSearchOnlineApps(false);
|
||||
|
||||
UkuiSearch::SearchResultProperties searchResultProperties;
|
||||
searchResultProperties << UkuiSearch::SearchProperty::SearchResultProperty::ApplicationDesktopPath
|
||||
<< UkuiSearch::SearchProperty::SearchResultProperty::ApplicationLocalName
|
||||
<< UkuiSearch::SearchProperty::SearchResultProperty::ApplicationIconName;
|
||||
m_appSearchTask->setResultProperties(UkuiSearch::SearchProperty::SearchType::Application, searchResultProperties);
|
||||
|
||||
m_timer = new QTimer;
|
||||
m_timer->setInterval(3000);
|
||||
m_timer->moveToThread(this);
|
||||
}
|
||||
|
||||
void AppSearchPluginPrivate::startSearch(const QString &keyword)
|
||||
{
|
||||
if (!this->isRunning()) {
|
||||
this->start();
|
||||
}
|
||||
|
||||
m_appSearchTask->clearKeyWords();
|
||||
m_appSearchTask->addKeyword(keyword);
|
||||
m_searchId = m_appSearchTask->startSearch(UkuiSearch::SearchProperty::SearchType::Application);
|
||||
}
|
||||
|
||||
void AppSearchPluginPrivate::stopSearch()
|
||||
{
|
||||
m_appSearchTask->stop();
|
||||
this->requestInterruption();
|
||||
}
|
||||
|
||||
void AppSearchPluginPrivate::run()
|
||||
{
|
||||
while (!isInterruptionRequested()) {
|
||||
UkuiSearch::ResultItem result = m_dataQueue->tryDequeue();
|
||||
if(result.getSearchId() == 0 && result.getItemKey().isEmpty() && result.getAllValue().isEmpty()) {
|
||||
if(!m_timer->isActive()) {
|
||||
// 超时退出
|
||||
m_timer->start();
|
||||
}
|
||||
msleep(100);
|
||||
} else {
|
||||
m_timer->stop();
|
||||
if (result.getSearchId() == m_searchId) {
|
||||
DataEntity app;
|
||||
app.setType(DataType::Normal);
|
||||
app.setId(result.getValue(UkuiSearch::SearchProperty::ApplicationDesktopPath).toString());
|
||||
app.setName(result.getValue(UkuiSearch::SearchProperty::ApplicationLocalName).toString());
|
||||
app.setIcon("image://appicon/" + result.getValue(UkuiSearch::SearchProperty::ApplicationIconName).toString());
|
||||
|
||||
Q_EMIT this->searchedOne(app);
|
||||
}
|
||||
}
|
||||
|
||||
if(m_timer->isActive() && m_timer->remainingTime() < 0.01 && m_dataQueue->isEmpty()) {
|
||||
this->requestInterruption();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====== AppSearchModel ====== //
|
||||
class AppSearchModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppSearchModel(QObject *parent = nullptr);
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
void appendApp(const DataEntity &app);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
QVector<DataEntity> m_apps;
|
||||
};
|
||||
|
||||
AppSearchModel::AppSearchModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int AppSearchModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_apps.size();
|
||||
}
|
||||
|
||||
int AppSearchModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant AppSearchModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const DataEntity &app = m_apps[index.row()];
|
||||
return app.getValue(static_cast<DataEntity::PropertyName>(role));
|
||||
}
|
||||
|
||||
void AppSearchModel::appendApp(const DataEntity &app)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_apps.size(), m_apps.size());
|
||||
m_apps.append(app);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void AppSearchModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
m_apps.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
// ====== AppSearchPlugin ====== //
|
||||
AppSearchPlugin::AppSearchPlugin(QObject *parent) : AppListPluginInterface(parent)
|
||||
, m_searchPluginPrivate(new AppSearchPluginPrivate(this)), m_model(new AppSearchModel(this))
|
||||
{
|
||||
connect(m_searchPluginPrivate, &AppSearchPluginPrivate::searchedOne, m_model, &AppSearchModel::appendApp);
|
||||
}
|
||||
|
||||
AppListPluginGroup::Group AppSearchPlugin::group()
|
||||
{
|
||||
return AppListPluginGroup::Search;
|
||||
}
|
||||
|
||||
QString AppSearchPlugin::name()
|
||||
{
|
||||
return "Search";
|
||||
}
|
||||
|
||||
QString AppSearchPlugin::title()
|
||||
{
|
||||
return "Search";
|
||||
}
|
||||
|
||||
QList<QAction *> AppSearchPlugin::actions()
|
||||
{
|
||||
// TODO: 搜索结果排序选项
|
||||
return {};
|
||||
}
|
||||
|
||||
QAbstractItemModel *AppSearchPlugin::dataModel()
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
void AppSearchPlugin::search(const QString &keyword)
|
||||
{
|
||||
m_model->clear();
|
||||
if (keyword.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_searchPluginPrivate->startSearch(keyword);
|
||||
}
|
||||
|
||||
AppSearchPlugin::~AppSearchPlugin()
|
||||
{
|
||||
m_searchPluginPrivate->stopSearch();
|
||||
m_searchPluginPrivate->quit();
|
||||
m_searchPluginPrivate->wait();
|
||||
m_searchPluginPrivate->deleteLater();
|
||||
}
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#include "app-search-plugin.moc"
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2024, 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/>.
|
||||
*
|
||||
* Authors: hxf <hewenfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UKUI_MENU_APP_SEARCH_PLUGIN_H
|
||||
#define UKUI_MENU_APP_SEARCH_PLUGIN_H
|
||||
|
||||
#include "app-list-plugin.h"
|
||||
|
||||
namespace UkuiMenu {
|
||||
|
||||
class AppSearchPluginPrivate;
|
||||
class AppSearchModel;
|
||||
|
||||
/**
|
||||
* @class AppSearchPlugin
|
||||
* 应用搜索插件,调用搜索接口进行应用搜索
|
||||
*/
|
||||
class AppSearchPlugin : public AppListPluginInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AppSearchPlugin(QObject *parent = nullptr);
|
||||
~AppSearchPlugin() override;
|
||||
|
||||
AppListPluginGroup::Group group() override;
|
||||
QString name() override;
|
||||
QString title() override;
|
||||
QList<QAction *> actions() override;
|
||||
QAbstractItemModel *dataModel() override;
|
||||
void search(const QString &keyword) override;
|
||||
|
||||
private:
|
||||
AppSearchModel *m_model {nullptr};
|
||||
AppSearchPluginPrivate * m_searchPluginPrivate {nullptr};
|
||||
};
|
||||
|
||||
} // UkuiMenu
|
||||
|
||||
#endif //UKUI_MENU_APP_SEARCH_PLUGIN_H
|
Loading…
Reference in New Issue