diff --git a/CMakeLists.txt b/CMakeLists.txt
index 723fdee..ade39f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,6 +88,7 @@ set(SOURCE_FILES
src/extension/menu-extension-iface.h
src/appdata/data-provider-plugin-iface.h
src/appdata/app-data-manager.cpp src/appdata/app-data-manager.h
+ src/appdata/plugin/all-app-data-provider.cpp src/appdata/plugin/all-app-data-provider.h
src/extension/extensions/folder-extension.cpp src/extension/extensions/folder-extension.h
src/extension/extensions/recent-file-extension.cpp src/extension/extensions/recent-file-extension.h
)
diff --git a/src/appdata/plugin/all-app-data-provider.cpp b/src/appdata/plugin/all-app-data-provider.cpp
new file mode 100644
index 0000000..a8935cc
--- /dev/null
+++ b/src/appdata/plugin/all-app-data-provider.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2023, 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 .
+ *
+ */
+
+#include "all-app-data-provider.h"
+#include "app-data-manager.h"
+#include "app-folder-helper.h"
+
+#include
+
+namespace UkuiMenu {
+
+AllAppDataProvider::AllAppDataProvider() : DataProviderPluginIFace()
+{
+ reloadFolderData();
+ reloadAppData();
+
+ connect(AppDataManager::instance(), &AppDataManager::appAdded, this, &AllAppDataProvider::onAppAdded);
+ connect(AppDataManager::instance(), &AppDataManager::appDeleted, this, &AllAppDataProvider::onAppDeleted);
+ connect(AppDataManager::instance(), &AppDataManager::appUpdated, this, &AllAppDataProvider::onAppUpdated);
+ connect(AppFolderHelper::instance(), &AppFolderHelper::folderDataChanged, this, &AllAppDataProvider::onAppFolderChanged);
+}
+
+int AllAppDataProvider::index()
+{
+ return 0;
+}
+
+QString AllAppDataProvider::name()
+{
+ return tr("All");
+}
+
+QString AllAppDataProvider::icon()
+{
+ return "text-plain";
+}
+
+QString AllAppDataProvider::title()
+{
+ return "Recently installed";
+}
+
+PluginGroup::Group AllAppDataProvider::group()
+{
+ return PluginGroup::SortMenuItem;
+}
+
+QVector AllAppDataProvider::data()
+{
+ QVector data;
+ mergeData(data);
+ return data;
+}
+
+void AllAppDataProvider::forceUpdate()
+{
+ reloadFolderData();
+ reloadAppData();
+ sendData();
+}
+
+void AllAppDataProvider::reloadAppData()
+{
+ QMutexLocker locker(&m_mutex);
+ m_appData.clear();
+
+ // TODO 验证多线程间隐式共享数复制后导致迭代器实现问题
+ QList apps = AppDataManager::instance()->normalApps();
+ if (apps.isEmpty()) {
+ return;
+ }
+
+ for (const auto &app : apps) {
+ if (!m_folderApps.contains(app.id())) {
+ m_appData.append(app);
+ }
+ }
+
+ std::sort(m_appData.begin(), m_appData.end(), [](const DataEntity &a, const DataEntity &b) {
+ return (a.top() > b.top()) || (a.launchTimes() > b.launchTimes());
+ });
+}
+
+void AllAppDataProvider::reloadFolderData()
+{
+ QMutexLocker locker(&m_mutex);
+
+ m_folderApps.clear();
+ m_folderData.clear();
+
+ QVector folders = AppFolderHelper::instance()->folderData();
+ if (folders.isEmpty()) {
+ return;
+ }
+
+ std::sort(folders.begin(), folders.end(), [](const Folder &a, const Folder &b) {
+ return a.index < b.index;
+ });
+
+ DataEntity folderItem;
+ for (const auto &folder : folders) {
+ folderItem.setType(DataType::Folder);
+ folderItem.setIcon("image://appicon/text-plain");
+ folderItem.setName(folder.name);
+
+ m_folderApps.unite(folder.apps.toSet());
+ m_folderData.append(folderItem);
+ }
+}
+
+void AllAppDataProvider::mergeData(QVector &data)
+{
+ QMutexLocker locker(&m_mutex);
+ data.append(m_folderData);
+ data.append(m_appData.toVector());
+}
+
+void AllAppDataProvider::sendData()
+{
+ QVector data;
+ mergeData(data);
+ Q_EMIT dataChanged(data);
+}
+
+void AllAppDataProvider::onAppFolderChanged()
+{
+ reloadFolderData();
+ sendData();
+}
+
+void AllAppDataProvider::onAppAdded(const QList& apps)
+{
+ {
+ QMutexLocker locker(&m_mutex);
+ m_appData.append(apps);
+ }
+ sendData();
+}
+
+void AllAppDataProvider::onAppDeleted(QStringList idList)
+{
+ removeApps(idList);
+ sendData();
+}
+
+void AllAppDataProvider::removeApps(QStringList &idList)
+{
+ QMutexLocker locker(&m_mutex);
+
+ QList::iterator iterator = m_appData.begin();
+ while (iterator != m_appData.end() && !idList.isEmpty()) {
+ if (idList.removeOne((*iterator).id())) {
+ iterator = m_appData.erase(iterator);
+ continue;
+ }
+ ++iterator;
+ }
+}
+
+void AllAppDataProvider::onAppUpdated(const QList& apps)
+{
+ Q_UNUSED(apps);
+ reloadAppData();
+ sendData();
+}
+
+} // UkuiMenu
diff --git a/src/appdata/plugin/all-app-data-provider.h b/src/appdata/plugin/all-app-data-provider.h
new file mode 100644
index 0000000..b2c9498
--- /dev/null
+++ b/src/appdata/plugin/all-app-data-provider.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2023, 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 .
+ *
+ */
+
+#ifndef UKUI_MENU_ALL_APP_DATA_PROVIDER_H
+#define UKUI_MENU_ALL_APP_DATA_PROVIDER_H
+
+#include "data-provider-plugin-iface.h"
+#include
+#include
+
+namespace UkuiMenu {
+
+class AllAppDataProvider : public DataProviderPluginIFace
+{
+ Q_OBJECT
+public:
+ explicit AllAppDataProvider();
+ int index() override;
+ QString name() override;
+ QString icon() override;
+ QString title() override;
+ PluginGroup::Group group() override;
+ QVector data() override;
+ void forceUpdate() override;
+
+private Q_SLOTS:
+ void onAppAdded(const QList& apps);
+ void onAppDeleted(QStringList idList);
+ void onAppUpdated(const QList& apps);
+ // TODO 文件夹数据新增,删除信号处理
+ void onAppFolderChanged();
+
+private:
+ inline void sendData();
+ void removeApps(QStringList& idList);
+ void reloadAppData();
+ void reloadFolderData();
+ void mergeData(QVector &data);
+
+private:
+ QMutex m_mutex;
+ QSet m_folderApps;
+ QList m_appData;
+ QVector m_folderData;
+};
+
+} // UkuiMenu
+
+#endif //UKUI_MENU_ALL_APP_DATA_PROVIDER_H