diff --git a/CMakeLists.txt b/CMakeLists.txt
index d0a6fe4..dc8f481 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -92,6 +92,7 @@ set(SOURCE_FILES
src/appdata/plugin/all-app-data-provider.cpp src/appdata/plugin/all-app-data-provider.h
src/appdata/plugin/app-search-plugin.cpp src/appdata/plugin/app-search-plugin.h
src/appdata/plugin/app-category-plugin.cpp src/appdata/plugin/app-category-plugin.h
+ src/appdata/plugin/app-letter-sort-plugin.cpp src/appdata/plugin/app-letter-sort-plugin.h
src/extension/menu-extension-iface.h
src/extension/menu-extension.cpp src/extension/menu-extension.h
src/extension/extensions/folder-extension.cpp src/extension/extensions/folder-extension.h
diff --git a/src/appdata/data-provider-manager.cpp b/src/appdata/data-provider-manager.cpp
index db6de64..f5189cd 100644
--- a/src/appdata/data-provider-manager.cpp
+++ b/src/appdata/data-provider-manager.cpp
@@ -20,6 +20,7 @@
#include "plugin/all-app-data-provider.h"
#include "plugin/app-search-plugin.h"
#include "plugin/app-category-plugin.h"
+#include "plugin/app-letter-sort-plugin.h"
namespace UkuiMenu {
@@ -51,10 +52,14 @@ void DataProviderManager::initProviders()
auto *category = new AppCategoryPlugin;
registerProvider(category);
+ auto *sort = new AppLetterSortPlugin;
+ registerProvider(sort);
+
activateProvider(allProvider->id());
allProvider->moveToThread(&m_worker);
search->moveToThread(&m_worker);
category->moveToThread(&m_worker);
+ sort->moveToThread(&m_worker);
}
void DataProviderManager::registerProvider(DataProviderPluginIFace *provider)
diff --git a/src/appdata/plugin/app-letter-sort-plugin.cpp b/src/appdata/plugin/app-letter-sort-plugin.cpp
new file mode 100644
index 0000000..ccc8c36
--- /dev/null
+++ b/src/appdata/plugin/app-letter-sort-plugin.cpp
@@ -0,0 +1,181 @@
+/*
+ * 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 "app-letter-sort-plugin.h"
+#include "app-data-manager.h"
+
+#include
+
+namespace UkuiMenu {
+
+AppLetterSortPlugin::AppLetterSortPlugin()
+{
+ loadAppData();
+ connect(AppDataManager::instance(), &AppDataManager::appAdded, this, &AppLetterSortPlugin::onAppAdded);
+ connect(AppDataManager::instance(), &AppDataManager::appDeleted, this, &AppLetterSortPlugin::onAppDeleted);
+ connect(AppDataManager::instance(), &AppDataManager::appUpdated, this, &AppLetterSortPlugin::onAppUpdated);
+}
+
+int AppLetterSortPlugin::index()
+{
+ return 2;
+}
+
+QString AppLetterSortPlugin::id()
+{
+ return "letterSort";
+}
+
+QString AppLetterSortPlugin::name()
+{
+ return tr("Letter Sort");
+}
+
+QString AppLetterSortPlugin::icon()
+{
+ return "image://appicon/text-plain";
+}
+
+QString AppLetterSortPlugin::title()
+{
+ return tr("Letter Sort");
+}
+
+PluginGroup::Group AppLetterSortPlugin::group()
+{
+ return PluginGroup::SortMenuItem;
+}
+
+QVector AppLetterSortPlugin::data()
+{
+ return m_appData;
+}
+
+void AppLetterSortPlugin::forceUpdate()
+{
+ updateAppData();
+}
+
+QVector AppLetterSortPlugin::labels()
+{
+ return m_labels;
+}
+
+void AppLetterSortPlugin::onAppAdded(const QList &apps)
+{
+ Q_UNUSED(apps);
+ updateAppData();
+}
+
+void AppLetterSortPlugin::onAppDeleted(QStringList idList)
+{
+ Q_UNUSED(idList);
+ updateAppData();
+}
+
+void AppLetterSortPlugin::onAppUpdated(const QList &apps)
+{
+ Q_UNUSED(apps);
+ updateAppData();
+}
+
+void AppLetterSortPlugin::updateAppData()
+{
+ loadAppData();
+ sendChangeSignal();
+}
+
+void AppLetterSortPlugin::sendChangeSignal()
+{
+ Q_EMIT labelChanged();
+ Q_EMIT dataChanged(m_appData);
+}
+
+void AppLetterSortPlugin::loadAppData()
+{
+ QMutexLocker locker(&m_mutex);
+ m_appData.clear();
+ m_labels.clear();
+ QList appData;
+ appData = AppDataManager::instance()->normalApps();
+
+ if (appData.isEmpty()) {
+ return;
+ }
+ sortAppData(appData);
+}
+
+void AppLetterSortPlugin::sortAppData(QList &apps)
+{
+ QVector appVector[28];
+
+ for (int i = 0; i < apps.length(); i++) {
+ QString letter = apps.at(i).firstLetter();
+ char firstLetter;
+
+ if (!letter.isEmpty())
+ {
+ firstLetter = letter.at(0).toUpper().toLatin1();
+ } else {
+ firstLetter = '&';
+ }
+
+ if (firstLetter >= 'A' && firstLetter <= 'Z') {
+ appVector[(static_cast(firstLetter) - 65)].append(apps.at(i));
+ } else if (firstLetter >= '1' && firstLetter <= '9') {
+ appVector[26].append(apps.at(i));
+ } else {
+ appVector[27].append(apps.at(i));
+ }
+ }
+
+ for (int i = 0; i < 26; i++) {
+ addAppToLabel(QString(QChar(static_cast(i + 65))), appVector[i]);
+ }
+ addAppToLabel(QString("#"), appVector[26]);
+ addAppToLabel(QString("&"), appVector[27]);
+}
+
+void AppLetterSortPlugin::addAppToLabel(const QString &labelName, QVector &apps)
+{
+ LabelItem labelItem;
+ labelItem.setDisable(!apps.isEmpty());
+ labelItem.setIndex(m_labels.size());
+ labelItem.setId(labelName);
+ labelItem.setDisplayName(labelName);
+ m_labels.append(labelItem);
+
+ if (!apps.isEmpty()) {
+ DataEntity dataEntity;
+ dataEntity.setComment(tr("Letter sort button"));
+ dataEntity.setName(labelName);
+ dataEntity.setId(labelName);
+ dataEntity.setType(DataType::Label);
+ m_appData.append(dataEntity);
+
+ std::sort(apps.begin(), apps.end(), [](const DataEntity &a, const DataEntity &b) {
+ return !(a.firstLetter().compare(b.firstLetter(), Qt::CaseInsensitive) > 0);
+ });
+
+ m_appData.append(apps);
+ }
+}
+
+
+
+} // UkuiMenu
diff --git a/src/appdata/plugin/app-letter-sort-plugin.h b/src/appdata/plugin/app-letter-sort-plugin.h
new file mode 100644
index 0000000..48e9da4
--- /dev/null
+++ b/src/appdata/plugin/app-letter-sort-plugin.h
@@ -0,0 +1,62 @@
+/*
+ * 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_APP_LETTER_SORT_PLUGIN_H
+#define UKUI_MENU_APP_LETTER_SORT_PLUGIN_H
+
+#include "data-provider-plugin-iface.h"
+
+namespace UkuiMenu {
+
+class AppLetterSortPlugin : public DataProviderPluginIFace
+{
+ Q_OBJECT
+public:
+ explicit AppLetterSortPlugin();
+
+ int index() override;
+ QString id() override;
+ QString name() override;
+ QString icon() override;
+ QString title() override;
+ PluginGroup::Group group() override;
+ QVector data() override;
+ void forceUpdate() override;
+ QVector labels() override;
+
+private Q_SLOTS:
+ void onAppAdded(const QList& apps);
+ void onAppDeleted(QStringList idList);
+ void onAppUpdated(const QList& apps);
+
+private:
+ void updateAppData();
+ void sendChangeSignal();
+ void loadAppData();
+ void sortAppData(QList &apps);
+ void addAppToLabel(const QString &labelName, QVector &apps);
+
+private:
+ QMutex m_mutex;
+ QVector m_appData;
+ QVector m_labels;
+};
+
+} // UkuiMenu
+
+#endif // UKUI_MENU_APP_LETTER_SORT_PLUGIN_H