diff --git a/CMakeLists.txt b/CMakeLists.txt
index a29fa18..d991a26 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,7 +27,7 @@ find_package(PkgConfig REQUIRED)
set(UKUI_MENU_EXTERNAL_LIBS "")
# glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper
-set(UKUI_MENU_PC_PKGS gsettings-qt x11 kysdk-waylandhelper)
+set(UKUI_MENU_PC_PKGS glib-2.0 gio-unix-2.0 gsettings-qt x11 kysdk-waylandhelper)
foreach(external_lib IN ITEMS ${UKUI_MENU_PC_PKGS})
pkg_check_modules(${external_lib} REQUIRED ${external_lib})
@@ -88,6 +88,7 @@ set(SOURCE_FILES
src/extension/menu-extension-iface.h
src/appdata/data-provider-plugin-iface.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
)
# qrc文件
diff --git a/src/extension/extensions/recent-file-extension.cpp b/src/extension/extensions/recent-file-extension.cpp
new file mode 100644
index 0000000..a6954b9
--- /dev/null
+++ b/src/extension/extensions/recent-file-extension.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 .
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+#include "recent-file-extension.h"
+
+namespace UkuiMenu {
+
+// GVFS 最近文件获取工具
+class GVFSRecentFileData
+{
+public:
+ static int s_queryFileNum;
+ static GCancellable *s_cancellable;
+ static void loadRecentFileASync(RecentFileExtension *p_extension);
+
+private:
+ static GFile *s_recentFileRootDir;
+ static GAsyncReadyCallback enumerateFinish(GFile *file, GAsyncResult *res, RecentFileExtension *p_extension);
+ static GAsyncReadyCallback parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileExtension *p_extension);
+};
+
+int GVFSRecentFileData::s_queryFileNum = 100;
+GCancellable *GVFSRecentFileData::s_cancellable = g_cancellable_new();
+GFile *GVFSRecentFileData::s_recentFileRootDir = g_file_new_for_uri("recent:///");
+
+void GVFSRecentFileData::loadRecentFileASync(RecentFileExtension *p_extension)
+{
+ if (!s_recentFileRootDir) {
+ qWarning() << "Can not find 'recent:///' dir.";
+ return;
+ }
+
+ g_file_enumerate_children_async(s_recentFileRootDir,
+ "*",
+ G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
+ s_cancellable, GAsyncReadyCallback(enumerateFinish),
+ p_extension);
+}
+
+GAsyncReadyCallback
+GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFileExtension *p_extension)
+{
+ GError *error = nullptr;
+ GFileEnumerator *enumerator = g_file_enumerate_children_finish(file, res, &error);
+ if (error) {
+ qWarning() << "GVFSRecentFileData::enumerateFinish Error:" << error->message;
+ g_error_free(error);
+ return nullptr;
+ }
+
+ g_file_enumerator_next_files_async(enumerator, s_queryFileNum, G_PRIORITY_DEFAULT,
+ s_cancellable, GAsyncReadyCallback(parseRecentFiles), p_extension);
+
+ g_object_unref(enumerator);
+
+ return nullptr;
+}
+
+GAsyncReadyCallback
+GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileExtension *p_extension)
+{
+ GError *error = nullptr;
+ GList *fileList = g_file_enumerator_next_files_finish(enumerator, res, &error);
+ if (error) {
+ qWarning() << "GVFSRecentFileData::parseRecentFiles Error:" << error->message;
+ g_error_free(error);
+ return nullptr;
+ }
+
+ if (!fileList) {
+ return nullptr;
+ }
+
+ QVector recentFiles;
+ auto listIterator = fileList;
+ while (listIterator) {
+ RecentFile recentFile;
+ GFileInfo *info = static_cast(listIterator->data);
+
+ char *attribute = g_file_info_get_attribute_as_string(info, G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
+ if (attribute) {
+ recentFile.uri = attribute;
+ g_free(attribute);
+ }
+
+ const char *fileName = g_file_info_get_display_name(info);
+ if (fileName) {
+ recentFile.name = fileName;
+ }
+
+ // in seconds since the UNIX epoch.
+ recentFile.accessTime = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_ACCESS);
+
+ GIcon *icon = g_file_info_get_icon(info);
+ if (icon) {
+ const gchar* const *iconNames = g_themed_icon_get_names(G_THEMED_ICON(icon));
+ if (iconNames) {
+ auto iconNameIterator = iconNames;
+ while(*iconNameIterator) {
+ if(QIcon::hasThemeIcon(*iconNameIterator)) {
+ recentFile.icon = *iconNameIterator;
+ break;
+ } else {
+ ++iconNameIterator;
+ }
+ }
+ }
+ g_object_unref(icon);
+ }
+
+ if (recentFile.icon.isEmpty()) {
+ recentFile.icon = "text-plain";
+ }
+
+ recentFiles.append(recentFile);
+ g_object_unref(info);
+ listIterator = listIterator->next;
+ }
+
+ g_list_free(fileList);
+
+ return nullptr;
+}
+
+// RecentFileExtension
+RecentFileExtension::RecentFileExtension(QObject *parent) : MenuExtensionIFace(parent)
+{
+
+}
+
+int RecentFileExtension::index()
+{
+ return 0;
+}
+
+QString RecentFileExtension::name()
+{
+ return {};
+}
+
+QUrl RecentFileExtension::url()
+{
+ return {};
+}
+
+QVariantMap RecentFileExtension::data()
+{
+ return {};
+}
+
+void RecentFileExtension::receive(QVariantMap data)
+{
+
+}
+
+} // UkuiMenu
diff --git a/src/extension/extensions/recent-file-extension.h b/src/extension/extensions/recent-file-extension.h
new file mode 100644
index 0000000..f78f8f0
--- /dev/null
+++ b/src/extension/extensions/recent-file-extension.h
@@ -0,0 +1,49 @@
+/*
+ * 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 .
+ *
+ */
+
+#ifndef UKUI_MENU_RECENT_FILE_EXTENSION_H
+#define UKUI_MENU_RECENT_FILE_EXTENSION_H
+
+#include "../menu-extension-iface.h"
+
+namespace UkuiMenu {
+
+class RecentFile
+{
+public:
+ quint64 accessTime{0};
+ QString uri;
+ QString name;
+ QString icon;
+};
+
+class RecentFileExtension : public MenuExtensionIFace
+{
+ Q_OBJECT
+public:
+ explicit RecentFileExtension(QObject *parent = nullptr);
+ int index() override;
+ QString name() override;
+ QUrl url() override;
+ QVariantMap data() override;
+ void receive(QVariantMap data) override;
+};
+
+} // UkuiMenu
+
+#endif //UKUI_MENU_RECENT_FILE_EXTENSION_H