forked from openkylin/ukui-menu
添加最近文件功能
This commit is contained in:
parent
2efc02d651
commit
f276cbe74b
|
@ -1,2 +1,4 @@
|
||||||
module AppControls2
|
module AppControls2
|
||||||
AppTest 1.0 App.qml
|
AppTest 1.0 App.qml
|
||||||
|
StyleBackground 1.0 StyleBackground.qml
|
||||||
|
StyleText 1.0 StyleText.qml
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import org.ukui.menu.extension 1.0
|
||||||
|
import AppControls2 1.0 as AppControls2
|
||||||
|
|
||||||
|
UkuiMenuExtension {
|
||||||
|
Component.onCompleted: {
|
||||||
|
recentFileView.model = extensionData.recentFilesModel
|
||||||
|
extensionData.recentFilesModel.updateData()
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: recentFileView
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
anchors.rightMargin: 6
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
delegate: AppControls2.StyleBackground {
|
||||||
|
width: parent.width
|
||||||
|
height: 40
|
||||||
|
useStyleTransparent: false
|
||||||
|
alpha: itemArea.pressed ? 1 : itemArea.hovered ? 0.4 : 0
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 4
|
||||||
|
spacing: 12
|
||||||
|
|
||||||
|
Image {
|
||||||
|
width: 32
|
||||||
|
height: 32
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: model.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
AppControls2.StyleText {
|
||||||
|
width: parent.width - x
|
||||||
|
height: 20
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: model.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: itemArea
|
||||||
|
property bool hovered
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onEntered: {
|
||||||
|
hovered = true
|
||||||
|
}
|
||||||
|
onExited: {
|
||||||
|
hovered = false
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var data = {
|
||||||
|
"url": model.uri
|
||||||
|
}
|
||||||
|
send(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,5 +15,6 @@
|
||||||
<file>AppControls2/StyleText.qml</file>
|
<file>AppControls2/StyleText.qml</file>
|
||||||
<file>AppControls2/IconLabel.qml</file>
|
<file>AppControls2/IconLabel.qml</file>
|
||||||
<file>extensions/FolderExtension.qml</file>
|
<file>extensions/FolderExtension.qml</file>
|
||||||
|
<file>extensions/RecentFileExtension.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -20,9 +20,17 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QDBusReply>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <gio/gdesktopappinfo.h>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
#include "recent-file-extension.h"
|
#include "recent-file-extension.h"
|
||||||
|
|
||||||
|
#define KYLIN_APP_MANAGER_NAME "com.kylin.AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_PATH "/com/kylin/AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_INTERFACE "com.kylin.AppManager"
|
||||||
|
|
||||||
namespace UkuiMenu {
|
namespace UkuiMenu {
|
||||||
|
|
||||||
// GVFS 最近文件获取工具
|
// GVFS 最近文件获取工具
|
||||||
|
@ -31,19 +39,19 @@ class GVFSRecentFileData
|
||||||
public:
|
public:
|
||||||
static int s_queryFileNum;
|
static int s_queryFileNum;
|
||||||
static GCancellable *s_cancellable;
|
static GCancellable *s_cancellable;
|
||||||
static void loadRecentFileASync(RecentFileExtension *p_extension);
|
static void loadRecentFileASync(RecentFileProvider *p_recentFileProvider);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static GFile *s_recentFileRootDir;
|
static GFile *s_recentFileRootDir;
|
||||||
static GAsyncReadyCallback enumerateFinish(GFile *file, GAsyncResult *res, RecentFileExtension *p_extension);
|
static GAsyncReadyCallback enumerateFinish(GFile *file, GAsyncResult *res, RecentFileProvider *p_recentFileProvider);
|
||||||
static GAsyncReadyCallback parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileExtension *p_extension);
|
static GAsyncReadyCallback parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileProvider *p_recentFileProvider);
|
||||||
};
|
};
|
||||||
|
|
||||||
int GVFSRecentFileData::s_queryFileNum = 100;
|
int GVFSRecentFileData::s_queryFileNum = 100;
|
||||||
GCancellable *GVFSRecentFileData::s_cancellable = g_cancellable_new();
|
GCancellable *GVFSRecentFileData::s_cancellable = g_cancellable_new();
|
||||||
GFile *GVFSRecentFileData::s_recentFileRootDir = g_file_new_for_uri("recent:///");
|
GFile *GVFSRecentFileData::s_recentFileRootDir = g_file_new_for_uri("recent:///");
|
||||||
|
|
||||||
void GVFSRecentFileData::loadRecentFileASync(RecentFileExtension *p_extension)
|
void GVFSRecentFileData::loadRecentFileASync(RecentFileProvider *p_recentFileProvider)
|
||||||
{
|
{
|
||||||
if (!s_recentFileRootDir) {
|
if (!s_recentFileRootDir) {
|
||||||
qWarning() << "Can not find 'recent:///' dir.";
|
qWarning() << "Can not find 'recent:///' dir.";
|
||||||
|
@ -54,11 +62,11 @@ void GVFSRecentFileData::loadRecentFileASync(RecentFileExtension *p_extension)
|
||||||
"*",
|
"*",
|
||||||
G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
|
G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
|
||||||
s_cancellable, GAsyncReadyCallback(enumerateFinish),
|
s_cancellable, GAsyncReadyCallback(enumerateFinish),
|
||||||
p_extension);
|
p_recentFileProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
GAsyncReadyCallback
|
GAsyncReadyCallback
|
||||||
GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFileExtension *p_extension)
|
GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFileProvider *p_recentFileProvider)
|
||||||
{
|
{
|
||||||
GError *error = nullptr;
|
GError *error = nullptr;
|
||||||
GFileEnumerator *enumerator = g_file_enumerate_children_finish(file, res, &error);
|
GFileEnumerator *enumerator = g_file_enumerate_children_finish(file, res, &error);
|
||||||
|
@ -69,7 +77,7 @@ GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFileEx
|
||||||
}
|
}
|
||||||
|
|
||||||
g_file_enumerator_next_files_async(enumerator, s_queryFileNum, G_PRIORITY_DEFAULT,
|
g_file_enumerator_next_files_async(enumerator, s_queryFileNum, G_PRIORITY_DEFAULT,
|
||||||
s_cancellable, GAsyncReadyCallback(parseRecentFiles), p_extension);
|
s_cancellable, GAsyncReadyCallback(parseRecentFiles), p_recentFileProvider);
|
||||||
|
|
||||||
g_object_unref(enumerator);
|
g_object_unref(enumerator);
|
||||||
|
|
||||||
|
@ -77,7 +85,7 @@ GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFileEx
|
||||||
}
|
}
|
||||||
|
|
||||||
GAsyncReadyCallback
|
GAsyncReadyCallback
|
||||||
GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileExtension *p_extension)
|
GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileProvider *p_recentFileProvider)
|
||||||
{
|
{
|
||||||
GError *error = nullptr;
|
GError *error = nullptr;
|
||||||
GList *fileList = g_file_enumerator_next_files_finish(enumerator, res, &error);
|
GList *fileList = g_file_enumerator_next_files_finish(enumerator, res, &error);
|
||||||
|
@ -118,7 +126,7 @@ GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *
|
||||||
auto iconNameIterator = iconNames;
|
auto iconNameIterator = iconNames;
|
||||||
while(*iconNameIterator) {
|
while(*iconNameIterator) {
|
||||||
if(QIcon::hasThemeIcon(*iconNameIterator)) {
|
if(QIcon::hasThemeIcon(*iconNameIterator)) {
|
||||||
recentFile.icon = *iconNameIterator;
|
recentFile.icon = "image://appicon/" + QString(*iconNameIterator);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
++iconNameIterator;
|
++iconNameIterator;
|
||||||
|
@ -129,48 +137,264 @@ GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recentFile.icon.isEmpty()) {
|
if (recentFile.icon.isEmpty()) {
|
||||||
recentFile.icon = "text-plain";
|
recentFile.icon = "image://appicon/text-plain";
|
||||||
}
|
}
|
||||||
|
|
||||||
recentFiles.append(recentFile);
|
recentFiles.append(recentFile);
|
||||||
g_object_unref(info);
|
g_object_unref(info);
|
||||||
listIterator = listIterator->next;
|
listIterator = listIterator->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_list_free(fileList);
|
g_list_free(fileList);
|
||||||
|
|
||||||
|
p_recentFileProvider->dataProcess(recentFiles);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecentFileExtension
|
// RecentFileExtension
|
||||||
RecentFileExtension::RecentFileExtension(QObject *parent) : MenuExtensionIFace(parent)
|
RecentFileExtension::RecentFileExtension(QObject *parent) : MenuExtensionIFace(parent)
|
||||||
{
|
{
|
||||||
|
qRegisterMetaType<UkuiMenu::RecentFilesModel*>("RecentFilesModel*");
|
||||||
|
qRegisterMetaType<QVector<RecentFile> >("QVector<RecentFile>");
|
||||||
|
|
||||||
|
m_recentFilesProviderThread = new QThread(this);
|
||||||
|
m_recentFilesModel = new RecentFilesModel(this);
|
||||||
|
m_recentFileProvider = new RecentFileProvider();
|
||||||
|
|
||||||
|
if ((m_recentFilesProviderThread == nullptr) || (m_recentFilesModel == nullptr) || (m_recentFileProvider == nullptr)) {
|
||||||
|
qWarning() << "recentfile construction error" ;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_recentFilesProviderThread->start();
|
||||||
|
m_recentFileProvider->moveToThread(m_recentFilesProviderThread);
|
||||||
|
|
||||||
|
connect(this, &RecentFileExtension::loadRecentFiles, m_recentFileProvider, &RecentFileProvider::getRecentData);
|
||||||
|
connect(m_recentFilesModel, &RecentFilesModel::updateRecentData, m_recentFileProvider, &RecentFileProvider::getRecentData);
|
||||||
|
connect(m_recentFileProvider, &RecentFileProvider::dataLoadCompleted, m_recentFilesModel, &RecentFilesModel::updateRecentFiles);
|
||||||
|
connect(this, &RecentFileExtension::openFileASync, m_recentFileProvider, &RecentFileProvider::openFileByGFile);
|
||||||
|
|
||||||
|
m_data.insert("recentFilesModel", QVariant::fromValue(m_recentFilesModel));
|
||||||
|
initFileDbus();
|
||||||
|
|
||||||
|
Q_EMIT loadRecentFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
RecentFileExtension::~RecentFileExtension()
|
||||||
|
{
|
||||||
|
if (m_recentFilesProviderThread) {
|
||||||
|
m_recentFilesProviderThread->quit();
|
||||||
|
m_recentFilesProviderThread->wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_recentFileProvider) {
|
||||||
|
delete m_recentFileProvider;
|
||||||
|
m_recentFileProvider = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RecentFileExtension::index()
|
int RecentFileExtension::index()
|
||||||
{
|
{
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString RecentFileExtension::name()
|
QString RecentFileExtension::name()
|
||||||
{
|
{
|
||||||
return {};
|
return tr("Recent Files");
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl RecentFileExtension::url()
|
QUrl RecentFileExtension::url()
|
||||||
{
|
{
|
||||||
return {};
|
return {"qrc:///qml/extensions/RecentFileExtension.qml"};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap RecentFileExtension::data()
|
QVariantMap RecentFileExtension::data()
|
||||||
{
|
{
|
||||||
return {};
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecentFileExtension::receive(QVariantMap data)
|
void RecentFileExtension::receive(QVariantMap data)
|
||||||
|
{
|
||||||
|
QString path = data.value("url").toString();
|
||||||
|
if (!openFile(path)) {
|
||||||
|
Q_EMIT openFileASync(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFileExtension::initFileDbus()
|
||||||
|
{
|
||||||
|
m_appManagerDbusInterface = new QDBusInterface(KYLIN_APP_MANAGER_NAME,
|
||||||
|
KYLIN_APP_MANAGER_PATH,
|
||||||
|
KYLIN_APP_MANAGER_INTERFACE,
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
|
||||||
|
if (!m_appManagerDbusInterface) {
|
||||||
|
qWarning() << "recentfile open failed: appmanager dbus does not exists.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecentFileExtension::openFile(const QString &desktopFile)
|
||||||
|
{
|
||||||
|
if (m_appManagerDbusInterface != nullptr) {
|
||||||
|
QDBusReply<bool> status = m_appManagerDbusInterface->call("LaunchApp", desktopFile);
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
qWarning()<<"LaunchApp is failed,return false";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecentFilesModel::RecentFilesModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RecentFilesModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return m_recentFileData.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RecentFilesModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
int row = index.row();
|
||||||
|
if (row < 0 || row >= m_recentFileData.count()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case UriRole:
|
||||||
|
return m_recentFileData.at(row).uri;
|
||||||
|
case NameRole:
|
||||||
|
return m_recentFileData.at(row).name;
|
||||||
|
case IconRole:
|
||||||
|
return m_recentFileData.at(row).icon;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> RecentFilesModel::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> names;
|
||||||
|
names.insert(UriRole, "uri");
|
||||||
|
names.insert(NameRole, "name");
|
||||||
|
names.insert(IconRole, "icon");
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFilesModel::updateData()
|
||||||
|
{
|
||||||
|
Q_EMIT updateRecentData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFilesModel::updateRecentFiles(QVector<RecentFile> recentFiles)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_recentFileData.swap(recentFiles);
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
RecentFileProvider::RecentFileProvider(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFileProvider::dataProcess(QVector<RecentFile> &recentFiles)
|
||||||
|
{
|
||||||
|
std::sort(recentFiles.begin(), recentFiles.end(), [](const RecentFile &a, const RecentFile &b) {
|
||||||
|
return a.accessTime > b.accessTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
Q_EMIT dataLoadCompleted(recentFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFileProvider::getRecentData()
|
||||||
|
{
|
||||||
|
GVFSRecentFileData::loadRecentFileASync(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecentFileProvider::openFileByGFile(const QString &path)
|
||||||
|
{
|
||||||
|
GFile *file = g_file_new_for_uri(path.toUtf8().constData());
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GFileInfo *fileInfo = g_file_query_info(file,
|
||||||
|
"standard::*," "time::*," "access::*," "mountable::*," "metadata::*," "trash::*," G_FILE_ATTRIBUTE_ID_FILE,
|
||||||
|
G_FILE_QUERY_INFO_NONE,
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
if (!fileInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString mimeType(g_file_info_get_content_type(fileInfo));
|
||||||
|
if (mimeType.isEmpty()) {
|
||||||
|
if (g_file_info_has_attribute(fileInfo, "standard::fast-content-type")) {
|
||||||
|
mimeType = g_file_info_get_attribute_string(fileInfo, "standard::fast-content-type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GError *error = NULL;
|
||||||
|
GAppInfo *info = NULL;
|
||||||
|
|
||||||
|
QString mimeAppsListPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/mimeapps.list";
|
||||||
|
GKeyFile *keyfile = g_key_file_new();
|
||||||
|
gboolean ret = g_key_file_load_from_file(keyfile, mimeAppsListPath.toUtf8(), G_KEY_FILE_NONE, &error);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
qWarning()<< "load mimeapps list error msg" << error->message;
|
||||||
|
info = g_app_info_get_default_for_type(mimeType.toUtf8().constData(), false);
|
||||||
|
g_error_free(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gchar *desktopApp = g_key_file_get_string(keyfile, "Default Applications", mimeType.toUtf8(), &error);
|
||||||
|
|
||||||
|
if (NULL != desktopApp) {
|
||||||
|
info = (GAppInfo*)g_desktop_app_info_new(desktopApp);
|
||||||
|
g_free (desktopApp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info = g_app_info_get_default_for_type(mimeType.toUtf8().constData(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_key_file_free (keyfile);
|
||||||
|
|
||||||
|
if(G_IS_APP_INFO(info)) {
|
||||||
|
bool isSuccess(false);
|
||||||
|
QDBusInterface * appLaunchInterface = new QDBusInterface(KYLIN_APP_MANAGER_NAME,
|
||||||
|
KYLIN_APP_MANAGER_PATH,
|
||||||
|
KYLIN_APP_MANAGER_INTERFACE,
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
if(!appLaunchInterface->isValid()) {
|
||||||
|
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
|
||||||
|
isSuccess = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appLaunchInterface->setTimeout(10000);
|
||||||
|
QDBusReply<bool> reply = appLaunchInterface->call("LaunchDefaultAppWithUrl", path);
|
||||||
|
if(reply.isValid()) {
|
||||||
|
isSuccess = reply;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qWarning() << "recentfile used appmanager dbus called failed!";
|
||||||
|
isSuccess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(appLaunchInterface) {
|
||||||
|
delete appLaunchInterface;
|
||||||
|
}
|
||||||
|
appLaunchInterface = NULL;
|
||||||
|
if (!isSuccess){
|
||||||
|
QDesktopServices::openUrl(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(info);
|
||||||
|
}
|
||||||
|
|
||||||
} // UkuiMenu
|
} // UkuiMenu
|
||||||
|
|
|
@ -19,12 +19,26 @@
|
||||||
#ifndef UKUI_MENU_RECENT_FILE_EXTENSION_H
|
#ifndef UKUI_MENU_RECENT_FILE_EXTENSION_H
|
||||||
#define UKUI_MENU_RECENT_FILE_EXTENSION_H
|
#define UKUI_MENU_RECENT_FILE_EXTENSION_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
#include "../menu-extension-iface.h"
|
#include "../menu-extension-iface.h"
|
||||||
|
|
||||||
namespace UkuiMenu {
|
namespace UkuiMenu {
|
||||||
|
|
||||||
class RecentFile
|
class RecentFile
|
||||||
{
|
{
|
||||||
|
Q_GADGET
|
||||||
|
Q_PROPERTY(QString uri READ getUri)
|
||||||
|
Q_PROPERTY(QString name READ getName)
|
||||||
|
Q_PROPERTY(QString icon READ getIcon)
|
||||||
|
|
||||||
|
public:
|
||||||
|
QString getUri() { return uri; }
|
||||||
|
QString getName() { return name; }
|
||||||
|
QString getIcon() { return icon; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
quint64 accessTime{0};
|
quint64 accessTime{0};
|
||||||
QString uri;
|
QString uri;
|
||||||
|
@ -32,16 +46,76 @@ public:
|
||||||
QString icon;
|
QString icon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RecentFileProvider : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RecentFileProvider(QObject *parent = nullptr);
|
||||||
|
void dataProcess(QVector<RecentFile> &recentFiles);
|
||||||
|
|
||||||
|
public Q_SLOT:
|
||||||
|
void getRecentData();
|
||||||
|
void openFileByGFile(const QString &path);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void dataLoadCompleted(QVector<RecentFile> recentFiles);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RecentFilesModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum RoleMessage {
|
||||||
|
UriRole = Qt::UserRole,
|
||||||
|
NameRole = Qt::UserRole + 1,
|
||||||
|
IconRole = Qt::UserRole + 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit RecentFilesModel(QObject *parent = nullptr);
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
Q_INVOKABLE void updateData();
|
||||||
|
|
||||||
|
public Q_SLOT:
|
||||||
|
void updateRecentFiles(QVector<RecentFile> recentFiles);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<RecentFile> m_recentFileData;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void updateRecentData();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class RecentFileExtension : public MenuExtensionIFace
|
class RecentFileExtension : public MenuExtensionIFace
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit RecentFileExtension(QObject *parent = nullptr);
|
explicit RecentFileExtension(QObject *parent = nullptr);
|
||||||
|
~RecentFileExtension();
|
||||||
int index() override;
|
int index() override;
|
||||||
QString name() override;
|
QString name() override;
|
||||||
QUrl url() override;
|
QUrl url() override;
|
||||||
QVariantMap data() override;
|
QVariantMap data() override;
|
||||||
void receive(QVariantMap data) override;
|
void receive(QVariantMap data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<RecentFile> m_recentFile;
|
||||||
|
QVariantMap m_data;
|
||||||
|
QDBusInterface *m_appManagerDbusInterface = nullptr;
|
||||||
|
RecentFilesModel *m_recentFilesModel = nullptr;
|
||||||
|
QThread *m_recentFilesProviderThread = nullptr;
|
||||||
|
RecentFileProvider *m_recentFileProvider = nullptr;
|
||||||
|
|
||||||
|
void initFileDbus();
|
||||||
|
bool openFile(const QString& desktopFile);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void loadRecentFiles();
|
||||||
|
void openFileASync(const QString &path);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // UkuiMenu
|
} // UkuiMenu
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "menu-extension.h"
|
#include "menu-extension.h"
|
||||||
#include "extensions/folder-extension.h"
|
#include "extensions/folder-extension.h"
|
||||||
|
#include "extensions/recent-file-extension.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -38,6 +39,7 @@ MenuExtension::MenuExtension()
|
||||||
|
|
||||||
// register extension.
|
// register extension.
|
||||||
registerExtension(new FolderExtension(this));
|
registerExtension(new FolderExtension(this));
|
||||||
|
registerExtension(new RecentFileExtension(this));
|
||||||
|
|
||||||
initModel();
|
initModel();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue