From 4832564558c3310cad890a5ce122885db2fef38a Mon Sep 17 00:00:00 2001 From: hewenfei Date: Wed, 4 Jan 2023 17:28:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=9C=80=E8=BF=91=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=89=A9=E5=B1=95=E7=9A=84=E6=9C=80=E8=BF=91=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=AE=BF=E9=97=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 +- .../extensions/recent-file-extension.cpp | 176 ++++++++++++++++++ .../extensions/recent-file-extension.h | 49 +++++ 3 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 src/extension/extensions/recent-file-extension.cpp create mode 100644 src/extension/extensions/recent-file-extension.h 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