diff --git a/src/libappdata/app-category-plugin.cpp b/src/libappdata/app-category-plugin.cpp new file mode 100644 index 0000000..4d8c900 --- /dev/null +++ b/src/libappdata/app-category-plugin.cpp @@ -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 . + * + * Authors: hxf + * + */ + +#include "app-category-plugin.h" +#include "combined-list-model.h" +#include "app-category-model.h" +#include "recently-installed-model.h" + +#include +#include + +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 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 diff --git a/src/libappdata/app-category-plugin.h b/src/libappdata/app-category-plugin.h new file mode 100644 index 0000000..74b72ee --- /dev/null +++ b/src/libappdata/app-category-plugin.h @@ -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 . + * + * Authors: hxf + * + */ + +#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 actions() override; + QAbstractItemModel *dataModel() override; + +private: + void setTitle(const QString &title); + +private: + QString m_title; + QList m_actions; + CombinedListModel *m_dataModel {nullptr}; +}; + +} // UkuiMenu + +#endif //UKUI_MENU_APP_CATEGORY_PLUGIN_H diff --git a/src/libappdata/app-list-model.cpp b/src/libappdata/app-list-model.cpp new file mode 100644 index 0000000..2b85098 --- /dev/null +++ b/src/libappdata/app-list-model.cpp @@ -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 . + * + * Authors: hxf + * + */ + +#include "app-list-model.h" +#include "data-entity.h" +#include "context-menu-manager.h" + +#include + +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 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(); + qRegisterMetaType(); +} + +QHash 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(), location); + } +} + +} // UkuiMenu diff --git a/src/libappdata/app-list-model.h b/src/libappdata/app-list-model.h new file mode 100644 index 0000000..a2df63d --- /dev/null +++ b/src/libappdata/app-list-model.h @@ -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 . + * + * Authors: hxf + * + */ + +#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 +#include + +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 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 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 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 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 diff --git a/src/libappdata/app-list-plugin.cpp b/src/libappdata/app-list-plugin.cpp new file mode 100644 index 0000000..e321fa3 --- /dev/null +++ b/src/libappdata/app-list-plugin.cpp @@ -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 . + * + * Authors: hxf + * + */ + +#include "app-list-plugin.h" +#include + +namespace UkuiMenu { + +// ====== AppListPluginInterface ====== // +AppListPluginInterface::AppListPluginInterface(QObject *parent) : QObject(parent) +{ + +} + +void AppListPluginInterface::search(const QString &keyword) +{ + Q_UNUSED(keyword) +} + +} // UkuiMenu diff --git a/src/libappdata/app-list-plugin.h b/src/libappdata/app-list-plugin.h new file mode 100644 index 0000000..53f56ca --- /dev/null +++ b/src/libappdata/app-list-plugin.h @@ -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 . + * + * Authors: hxf + * + */ + +#ifndef UKUI_MENU_APP_LIST_PLUGIN_H +#define UKUI_MENU_APP_LIST_PLUGIN_H + +#include +#include + +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 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 diff --git a/src/libappdata/app-page-backend.cpp b/src/libappdata/app-page-backend.cpp new file mode 100644 index 0000000..3c615c8 --- /dev/null +++ b/src/libappdata/app-page-backend.cpp @@ -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 . + * + * Authors: hxf + * + */ + +#include "app-page-backend.h" + +#include "app-list-model.h" +#include "app-category-plugin.h" +#include "app-search-plugin.h" + +#include + +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 diff --git a/src/libappdata/app-page-backend.h b/src/libappdata/app-page-backend.h new file mode 100644 index 0000000..613114c --- /dev/null +++ b/src/libappdata/app-page-backend.h @@ -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 . + * + * Authors: hxf + * + */ + +#ifndef UKUI_MENU_APP_PAGE_BACKEND_H +#define UKUI_MENU_APP_PAGE_BACKEND_H + +#include +#include +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 m_plugins; + +}; + +} // UkuiMenu + +#endif //UKUI_MENU_APP_PAGE_BACKEND_H diff --git a/src/libappdata/app-search-plugin.cpp b/src/libappdata/app-search-plugin.cpp new file mode 100644 index 0000000..ee59541 --- /dev/null +++ b/src/libappdata/app-search-plugin.cpp @@ -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 . + * + * Authors: hxf + * + */ +#include "app-search-plugin.h" +#include "data-entity.h" + +#include +#include +#include +#include +#include + +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 *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 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(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 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" diff --git a/src/libappdata/app-search-plugin.h b/src/libappdata/app-search-plugin.h new file mode 100644 index 0000000..d870369 --- /dev/null +++ b/src/libappdata/app-search-plugin.h @@ -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 . + * + * Authors: hxf + * + */ + +#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 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