Merge tag 'upstream/4.0.0.3' into packaging/openkylin/yangtze
4.0.0.3-release
This commit is contained in:
commit
c337510482
|
@ -169,14 +169,8 @@ add_executable(
|
||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:UKUI_MENU_LOG_FILE_DISABLE>)
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
|
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<CONFIG:Debug>:QT_QML_DEBUG>)
|
||||||
if (${BUILD_TYPE} STREQUAL "debug")
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE UKUI_MENU_LOG_FILE_DISABLE)
|
|
||||||
endif ()
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
Qt5::Core
|
Qt5::Core
|
||||||
|
|
|
@ -35,7 +35,6 @@ UkuiMenuExtension {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onContainsMouseChanged: {
|
onContainsMouseChanged: {
|
||||||
|
|
||||||
if (containsMouse) {
|
if (containsMouse) {
|
||||||
scrollBar.visible = true
|
scrollBar.visible = true
|
||||||
}
|
}
|
||||||
|
@ -59,6 +58,11 @@ UkuiMenuExtension {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: 12
|
anchors.leftMargin: 12
|
||||||
spacing: 4
|
spacing: 4
|
||||||
|
focus: true
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
onActiveFocusChanged: currentIndex = 0
|
||||||
|
onCountChanged: currentIndex = 0
|
||||||
|
keyNavigationWraps: true
|
||||||
|
|
||||||
ScrollBar.vertical: AppControls2.ScrollBar {
|
ScrollBar.vertical: AppControls2.ScrollBar {
|
||||||
id: scrollBar
|
id: scrollBar
|
||||||
|
@ -68,11 +72,21 @@ UkuiMenuExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: AppControls2.StyleBackground {
|
delegate: AppControls2.StyleBackground {
|
||||||
|
id: delegateItem
|
||||||
width: ListView.view.width - 18
|
width: ListView.view.width - 18
|
||||||
height: 40
|
height: 40
|
||||||
useStyleTransparent: false
|
useStyleTransparent: false
|
||||||
alpha: itemArea.pressed ? 1 : itemArea.hovered ? 0.65 : 0
|
alpha: itemArea.pressed ? 1 : itemArea.hovered ? 0.65 : 0
|
||||||
radius: 8
|
radius: 8
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
when: delegateItem.activeFocus
|
||||||
|
PropertyChanges {
|
||||||
|
target: delegateItem
|
||||||
|
alpha: 0.65
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -87,6 +101,7 @@ UkuiMenuExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControls2.StyleText {
|
AppControls2.StyleText {
|
||||||
|
id: fileText
|
||||||
width: parent.width - x
|
width: parent.width - x
|
||||||
height: 20
|
height: 20
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
@ -95,6 +110,35 @@ UkuiMenuExtension {
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ToolTip {
|
||||||
|
visible: itemArea.containsMouse
|
||||||
|
delay: 500
|
||||||
|
contentItem: Column {
|
||||||
|
width: childrenRect.width
|
||||||
|
height: childrenRect.height
|
||||||
|
Text {
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
visible: fileText.truncated
|
||||||
|
wrapMode: Text.WrapAnywhere
|
||||||
|
text: model.name
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (contentWidth > recentFileView.width) {
|
||||||
|
width = recentFileView.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
text: qsTr("Path: ") + model.path
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (contentWidth > recentFileView.width) {
|
||||||
|
width = recentFileView.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: itemArea
|
id: itemArea
|
||||||
|
|
|
@ -27,6 +27,10 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusMessage>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
#include "recent-file-extension.h"
|
#include "recent-file-extension.h"
|
||||||
|
|
||||||
|
@ -39,6 +43,51 @@
|
||||||
|
|
||||||
namespace UkuiMenu {
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
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 &fileUrl);
|
||||||
|
|
||||||
|
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,
|
||||||
|
PathRole = Qt::UserRole + 3
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
QString getInfoId(const int &index);
|
||||||
|
QStringList getAllInfoId();
|
||||||
|
Q_INVOKABLE void updateData();
|
||||||
|
|
||||||
|
public Q_SLOT:
|
||||||
|
void updateRecentFiles(QVector<RecentFile> recentFiles);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<RecentFile> m_recentFileData;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void updateRecentData();
|
||||||
|
};
|
||||||
|
|
||||||
// GVFS 最近文件获取工具
|
// GVFS 最近文件获取工具
|
||||||
class GVFSRecentFileData
|
class GVFSRecentFileData
|
||||||
{
|
{
|
||||||
|
@ -68,9 +117,9 @@ void GVFSRecentFileData::fileMonitor(RecentFileProvider *p_recentFileProvider)
|
||||||
{
|
{
|
||||||
GError *error = nullptr;
|
GError *error = nullptr;
|
||||||
s_recentFileMonitor = g_file_monitor_directory(GVFSRecentFileData::s_recentFileRootDir,
|
s_recentFileMonitor = g_file_monitor_directory(GVFSRecentFileData::s_recentFileRootDir,
|
||||||
G_FILE_MONITOR_NONE,
|
G_FILE_MONITOR_NONE,
|
||||||
nullptr,
|
nullptr,
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
qWarning() << "recentFile monitor creat error";
|
qWarning() << "recentFile monitor creat error";
|
||||||
|
@ -149,7 +198,8 @@ GVFSRecentFileData::enumerateFinish(GFile *file, GAsyncResult *res, RecentFilePr
|
||||||
}
|
}
|
||||||
|
|
||||||
GAsyncReadyCallback
|
GAsyncReadyCallback
|
||||||
GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *res, RecentFileProvider *p_recentFileProvider)
|
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);
|
||||||
|
@ -189,11 +239,11 @@ GVFSRecentFileData::parseRecentFiles(GFileEnumerator *enumerator, GAsyncResult *
|
||||||
|
|
||||||
GIcon *icon = g_file_info_get_icon(info);
|
GIcon *icon = g_file_info_get_icon(info);
|
||||||
if (icon) {
|
if (icon) {
|
||||||
const gchar* const *iconNames = g_themed_icon_get_names(G_THEMED_ICON(icon));
|
const gchar *const *iconNames = g_themed_icon_get_names(G_THEMED_ICON(icon));
|
||||||
if (iconNames) {
|
if (iconNames) {
|
||||||
auto iconNameIterator = iconNames;
|
auto iconNameIterator = iconNames;
|
||||||
while(*iconNameIterator) {
|
while (*iconNameIterator) {
|
||||||
if(QIcon::hasThemeIcon(*iconNameIterator)) {
|
if (QIcon::hasThemeIcon(*iconNameIterator)) {
|
||||||
recentFile.icon = "image://appicon/" + QString(*iconNameIterator);
|
recentFile.icon = "image://appicon/" + QString(*iconNameIterator);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -229,15 +279,15 @@ RecentFileExtension::RecentFileExtension(QObject *parent) : MenuExtensionIFace(p
|
||||||
QCoreApplication::installTranslator(translator);
|
QCoreApplication::installTranslator(translator);
|
||||||
}
|
}
|
||||||
|
|
||||||
qRegisterMetaType<UkuiMenu::RecentFilesModel*>("RecentFilesModel*");
|
qRegisterMetaType<UkuiMenu::RecentFilesModel *>("RecentFilesModel*");
|
||||||
qRegisterMetaType<QVector<RecentFile> >("QVector<RecentFile>");
|
qRegisterMetaType<QVector<RecentFile> >("QVector<RecentFile>");
|
||||||
|
|
||||||
m_recentFilesProviderThread = new QThread(this);
|
m_recentFilesProviderThread = new QThread(this);
|
||||||
m_recentFilesModel = new RecentFilesModel(this);
|
m_recentFilesModel = new RecentFilesModel(this);
|
||||||
m_recentFileProvider = new RecentFileProvider();
|
m_recentFileProvider = new RecentFileProvider();
|
||||||
|
|
||||||
if ((m_recentFilesProviderThread == nullptr) || (m_recentFilesModel == nullptr) || (m_recentFileProvider == nullptr)) {
|
if (!m_recentFilesProviderThread || !m_recentFilesModel || !m_recentFileProvider) {
|
||||||
qWarning() << "recentfile construction error" ;
|
qWarning() << "recentfile construction error";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,12 +295,13 @@ RecentFileExtension::RecentFileExtension(QObject *parent) : MenuExtensionIFace(p
|
||||||
m_recentFileProvider->moveToThread(m_recentFilesProviderThread);
|
m_recentFileProvider->moveToThread(m_recentFilesProviderThread);
|
||||||
|
|
||||||
connect(this, &RecentFileExtension::loadRecentFiles, m_recentFileProvider, &RecentFileProvider::getRecentData);
|
connect(this, &RecentFileExtension::loadRecentFiles, m_recentFileProvider, &RecentFileProvider::getRecentData);
|
||||||
connect(m_recentFilesModel, &RecentFilesModel::updateRecentData, m_recentFileProvider, &RecentFileProvider::getRecentData);
|
connect(m_recentFilesModel, &RecentFilesModel::updateRecentData, m_recentFileProvider,
|
||||||
connect(m_recentFileProvider, &RecentFileProvider::dataLoadCompleted, m_recentFilesModel, &RecentFilesModel::updateRecentFiles);
|
&RecentFileProvider::getRecentData);
|
||||||
|
connect(m_recentFileProvider, &RecentFileProvider::dataLoadCompleted, m_recentFilesModel,
|
||||||
|
&RecentFilesModel::updateRecentFiles);
|
||||||
connect(this, &RecentFileExtension::openFileASync, m_recentFileProvider, &RecentFileProvider::openFileByGFile);
|
connect(this, &RecentFileExtension::openFileASync, m_recentFileProvider, &RecentFileProvider::openFileByGFile);
|
||||||
|
|
||||||
m_data.insert("recentFilesModel", QVariant::fromValue(m_recentFilesModel));
|
m_data.insert("recentFilesModel", QVariant::fromValue(m_recentFilesModel));
|
||||||
initFileDbus();
|
|
||||||
|
|
||||||
GVFSRecentFileData::fileMonitor(m_recentFileProvider);
|
GVFSRecentFileData::fileMonitor(m_recentFileProvider);
|
||||||
Q_EMIT loadRecentFiles();
|
Q_EMIT loadRecentFiles();
|
||||||
|
@ -305,40 +356,24 @@ void RecentFileExtension::receive(QVariantMap data)
|
||||||
creatMenu(path, index);
|
creatMenu(path, index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!openFile(path)) {
|
|
||||||
Q_EMIT openFileASync(path);
|
openFile(path);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecentFileExtension::initFileDbus()
|
void RecentFileExtension::openFile(const QString &fileUrl)
|
||||||
{
|
{
|
||||||
m_appManagerDbusInterface = new QDBusInterface(KYLIN_APP_MANAGER_NAME,
|
QDBusMessage message = QDBusMessage::createMethodCall(KYLIN_APP_MANAGER_NAME, KYLIN_APP_MANAGER_PATH, KYLIN_APP_MANAGER_INTERFACE, "LaunchDefaultAppWithUrl");
|
||||||
KYLIN_APP_MANAGER_PATH,
|
message << fileUrl;
|
||||||
KYLIN_APP_MANAGER_INTERFACE,
|
|
||||||
QDBusConnection::sessionBus());
|
|
||||||
|
|
||||||
m_fileManagerDbusInterface = new QDBusInterface(FREEDESKTOP_FILEMANAGER_NAME,
|
auto watcher = new QDBusPendingCallWatcher(QDBusConnection::sessionBus().asyncCall(message), this);
|
||||||
FREEDESKTOP_FILEMANAGER_PATH,
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, [fileUrl, this] (QDBusPendingCallWatcher *self) {
|
||||||
FREEDESKTOP_FILEMANAGER_INTERFACE,
|
QDBusPendingReply<bool> reply = *self;
|
||||||
QDBusConnection::sessionBus());
|
if (reply.isError() || !reply.value()) {
|
||||||
|
Q_EMIT openFileASync(fileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_appManagerDbusInterface) {
|
self->deleteLater();
|
||||||
qWarning() << "recentfile open failed: appmanager dbus does not exists.";
|
});
|
||||||
}
|
|
||||||
if (!m_fileManagerDbusInterface) {
|
|
||||||
qWarning() << "recentfile directory open failed: filemanager 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecentFileExtension::creatMenu(const QString &path, const int &index)
|
void RecentFileExtension::creatMenu(const QString &path, const int &index)
|
||||||
|
@ -351,28 +386,27 @@ void RecentFileExtension::creatMenu(const QString &path, const int &index)
|
||||||
QAction directory(tr("Open the directory where the file is located"));
|
QAction directory(tr("Open the directory where the file is located"));
|
||||||
|
|
||||||
connect(&open, &QAction::triggered, this, [this, path]() {
|
connect(&open, &QAction::triggered, this, [this, path]() {
|
||||||
if (!openFile(path)) {
|
openFile(path);
|
||||||
Q_EMIT openFileASync(path);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(&remove, &QAction::triggered, this, [this, index]() {
|
connect(&remove, &QAction::triggered, this, [this, index]() {
|
||||||
GVFSRecentFileData::removeRecentFileByInfoId(m_recentFilesModel->getInfoId(index));
|
GVFSRecentFileData::removeRecentFileByInfoId(m_recentFilesModel->getInfoId(index));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&clear, &QAction::triggered, this, [this]() {
|
connect(&clear, &QAction::triggered, this, [this]() {
|
||||||
QStringList infoIdList = m_recentFilesModel->getAllInfoId();
|
QStringList infoIdList = m_recentFilesModel->getAllInfoId();
|
||||||
for (const QString &infoId : infoIdList) {
|
for (const QString &infoId : infoIdList) {
|
||||||
GVFSRecentFileData::removeRecentFileByInfoId(infoId);
|
GVFSRecentFileData::removeRecentFileByInfoId(infoId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&directory, &QAction::triggered, this, [this, path]() {
|
connect(&directory, &QAction::triggered, this, [this, path]() {
|
||||||
if (!m_fileManagerDbusInterface) { return; }
|
QDBusMessage message = QDBusMessage::createMethodCall(FREEDESKTOP_FILEMANAGER_NAME,
|
||||||
QStringList pathList;
|
FREEDESKTOP_FILEMANAGER_PATH,
|
||||||
pathList.append(path);
|
FREEDESKTOP_FILEMANAGER_INTERFACE, "ShowFolders");
|
||||||
m_fileManagerDbusInterface->call("ShowFolders", pathList, "arg");
|
message << QStringList(path);
|
||||||
});
|
QDBusConnection::sessionBus().asyncCall(message);
|
||||||
|
});
|
||||||
|
|
||||||
menu.addAction(&open);
|
menu.addAction(&open);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
|
@ -407,6 +441,10 @@ QVariant RecentFilesModel::data(const QModelIndex &index, int role) const
|
||||||
return m_recentFileData.at(row).name;
|
return m_recentFileData.at(row).name;
|
||||||
case IconRole:
|
case IconRole:
|
||||||
return m_recentFileData.at(row).icon;
|
return m_recentFileData.at(row).icon;
|
||||||
|
case PathRole: {
|
||||||
|
QUrl baseUrl(m_recentFileData.at(row).uri);
|
||||||
|
return baseUrl.adjusted(QUrl::RemoveFilename).path();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -420,6 +458,7 @@ QHash<int, QByteArray> RecentFilesModel::roleNames() const
|
||||||
names.insert(UriRole, "uri");
|
names.insert(UriRole, "uri");
|
||||||
names.insert(NameRole, "name");
|
names.insert(NameRole, "name");
|
||||||
names.insert(IconRole, "icon");
|
names.insert(IconRole, "icon");
|
||||||
|
names.insert(PathRole, "path");
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,19 +507,16 @@ void RecentFileProvider::getRecentData()
|
||||||
GVFSRecentFileData::loadRecentFileASync(this);
|
GVFSRecentFileData::loadRecentFileASync(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecentFileProvider::openFileByGFile(const QString &path)
|
void RecentFileProvider::openFileByGFile(const QString &fileUrl)
|
||||||
{
|
{
|
||||||
GFile *file = g_file_new_for_uri(path.toUtf8().constData());
|
GFile *file = g_file_new_for_uri(fileUrl.toUtf8().constData());
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFileInfo *fileInfo = g_file_query_info(file,
|
GFileInfo *fileInfo = g_file_query_info(file, "standard::*," G_FILE_ATTRIBUTE_ID_FILE, G_FILE_QUERY_INFO_NONE, nullptr, nullptr);
|
||||||
"standard::*," "time::*," "access::*," "mountable::*," "metadata::*," "trash::*," G_FILE_ATTRIBUTE_ID_FILE,
|
|
||||||
G_FILE_QUERY_INFO_NONE,
|
|
||||||
nullptr,
|
|
||||||
nullptr);
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
|
g_object_unref(file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,62 +528,49 @@ void RecentFileProvider::openFileByGFile(const QString &path)
|
||||||
}
|
}
|
||||||
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GAppInfo *info = NULL;
|
GAppInfo *info = NULL;
|
||||||
|
|
||||||
QString mimeAppsListPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/mimeapps.list";
|
QString mimeAppsListPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/mimeapps.list";
|
||||||
GKeyFile *keyfile = g_key_file_new();
|
GKeyFile *keyfile = g_key_file_new();
|
||||||
gboolean ret = g_key_file_load_from_file(keyfile, mimeAppsListPath.toUtf8(), G_KEY_FILE_NONE, &error);
|
gboolean ret = g_key_file_load_from_file(keyfile, mimeAppsListPath.toUtf8(), G_KEY_FILE_NONE, &error);
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
qWarning()<< "load mimeapps list error msg" << error->message;
|
qWarning() << "load mimeapps list error msg" << error->message;
|
||||||
info = g_app_info_get_default_for_type(mimeType.toUtf8().constData(), false);
|
info = g_app_info_get_default_for_type(mimeType.toUtf8().constData(), false);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
}
|
|
||||||
else {
|
} else {
|
||||||
gchar *desktopApp = g_key_file_get_string(keyfile, "Default Applications", mimeType.toUtf8(), &error);
|
gchar *desktopApp = g_key_file_get_string(keyfile, "Default Applications", mimeType.toUtf8(), &error);
|
||||||
|
|
||||||
if (NULL != desktopApp) {
|
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);
|
info = g_app_info_get_default_for_type(mimeType.toUtf8().constData(), false);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
info = (GAppInfo *) g_desktop_app_info_new(desktopApp);
|
||||||
|
g_free(desktopApp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_key_file_free (keyfile);
|
g_key_file_free(keyfile);
|
||||||
|
|
||||||
if(G_IS_APP_INFO(info)) {
|
bool success = false;
|
||||||
bool isSuccess(false);
|
if (G_IS_APP_INFO(info)) {
|
||||||
QDBusInterface * appLaunchInterface = new QDBusInterface(KYLIN_APP_MANAGER_NAME,
|
GList *files = g_list_alloc();
|
||||||
KYLIN_APP_MANAGER_PATH,
|
g_list_append(files, file);
|
||||||
KYLIN_APP_MANAGER_INTERFACE,
|
|
||||||
QDBusConnection::sessionBus());
|
success = g_app_info_launch(info, files, nullptr, nullptr);
|
||||||
if(!appLaunchInterface->isValid()) {
|
|
||||||
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
|
g_list_free(files);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
QDesktopServices::openUrl(fileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref(file);
|
||||||
g_object_unref(info);
|
g_object_unref(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // UkuiMenu
|
} // UkuiMenu
|
||||||
|
|
||||||
|
#include "recent-file-extension.moc"
|
||||||
|
|
|
@ -19,14 +19,15 @@
|
||||||
#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>
|
class QThread;
|
||||||
#include <QDBusInterface>
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
|
|
||||||
#include "menu-extension-iface.h"
|
#include "menu-extension-iface.h"
|
||||||
|
|
||||||
namespace UkuiMenu {
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
class RecentFilesModel;
|
||||||
|
class RecentFileProvider;
|
||||||
|
|
||||||
class RecentFile
|
class RecentFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,52 +38,6 @@ public:
|
||||||
QString infoId;
|
QString infoId;
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
QString getInfoId(const int &index);
|
|
||||||
QStringList getAllInfoId();
|
|
||||||
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
|
||||||
|
@ -100,14 +55,11 @@ public:
|
||||||
private:
|
private:
|
||||||
QVector<RecentFile> m_recentFile;
|
QVector<RecentFile> m_recentFile;
|
||||||
QVariantMap m_data;
|
QVariantMap m_data;
|
||||||
QDBusInterface *m_appManagerDbusInterface = nullptr;
|
|
||||||
RecentFilesModel *m_recentFilesModel = nullptr;
|
RecentFilesModel *m_recentFilesModel = nullptr;
|
||||||
QThread *m_recentFilesProviderThread = nullptr;
|
QThread *m_recentFilesProviderThread = nullptr;
|
||||||
RecentFileProvider *m_recentFileProvider = nullptr;
|
RecentFileProvider *m_recentFileProvider = nullptr;
|
||||||
QDBusInterface *m_fileManagerDbusInterface = nullptr;
|
|
||||||
|
|
||||||
void initFileDbus();
|
void openFile(const QString& fileUrl);
|
||||||
bool openFile(const QString& desktopFile);
|
|
||||||
void creatMenu(const QString &path, const int &index);
|
void creatMenu(const QString &path, const int &index);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="zh_CN">
|
<TS version="2.1" language="zh_CN">
|
||||||
|
<context>
|
||||||
|
<name>RecentFileExtension</name>
|
||||||
|
<message>
|
||||||
|
<source>Path: </source>
|
||||||
|
<translation>路径: </translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>UkuiMenu::RecentFileExtension</name>
|
<name>UkuiMenu::RecentFileExtension</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -9,19 +16,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Open</source>
|
<source>Open</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>打开</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Remove from list</source>
|
<source>Remove from list</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>从列表删除</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Clear list</source>
|
<source>Clear list</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>清空全部</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Open the directory where the file is located</source>
|
<source>Open the directory where the file is located</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>打开文件所在目录</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -22,6 +22,7 @@ MouseArea {
|
||||||
alpha: isSelect ? 1.00 : control.containsPress ? 0.82 : control.containsMouse ? 0.55 : 0.00
|
alpha: isSelect ? 1.00 : control.containsPress ? 0.82 : control.containsMouse ? 0.55 : 0.00
|
||||||
ToolTip.visible: content.textTruncated && control.containsMouse
|
ToolTip.visible: content.textTruncated && control.containsMouse
|
||||||
ToolTip.text: name
|
ToolTip.text: name
|
||||||
|
ToolTip.delay: 500
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -12,6 +12,7 @@ MouseArea {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
ToolTip.visible: !editStatus && truncate && control.containsMouse
|
ToolTip.visible: !editStatus && truncate && control.containsMouse
|
||||||
ToolTip.text: name
|
ToolTip.text: name
|
||||||
|
ToolTip.delay: 500
|
||||||
states: State {
|
states: State {
|
||||||
when: control.activeFocus
|
when: control.activeFocus
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
|
|
|
@ -5,8 +5,9 @@ import QtQuick.Controls 2.5
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: control
|
id: control
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
ToolTip.text: qsTr("Open the label selection interface")
|
ToolTip.text: comment
|
||||||
ToolTip.visible: control.containsMouse
|
ToolTip.visible: control.containsMouse
|
||||||
|
ToolTip.delay: 500
|
||||||
states: State {
|
states: State {
|
||||||
when: control.activeFocus
|
when: control.activeFocus
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
|
|
|
@ -64,6 +64,7 @@ Item {
|
||||||
property string id: model.id
|
property string id: model.id
|
||||||
property string name: model.name
|
property string name: model.name
|
||||||
property string icon: model.icon
|
property string icon: model.icon
|
||||||
|
property string comment: model.comment // label tooltip
|
||||||
property int toTop: model.top
|
property int toTop: model.top
|
||||||
property bool recentInstall: model.recentInstall
|
property bool recentInstall: model.recentInstall
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
|
|
|
@ -196,8 +196,12 @@ Item {
|
||||||
|
|
||||||
model: appPageHeaderUtils.model(PluginGroup.Button)
|
model: appPageHeaderUtils.model(PluginGroup.Button)
|
||||||
delegate: AppControls2.RoundButton {
|
delegate: AppControls2.RoundButton {
|
||||||
width: height; height: ListView.view ? ListView.view.height : 0
|
width: height
|
||||||
|
height: ListView.view ? ListView.view.height : 0
|
||||||
buttonIcon: model.icon
|
buttonIcon: model.icon
|
||||||
|
ToolTip.text: qsTr("Search App")
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.visible: containsMouse
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.state = "search";
|
root.state = "search";
|
||||||
// 后续添加需求,可以用model数据设置
|
// 后续添加需求,可以用model数据设置
|
||||||
|
|
|
@ -224,7 +224,9 @@ RowLayout {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
width: 170; height: width
|
width: 170; height: width
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: name
|
||||||
|
ToolTip.visible: iconText.truncated && containsMouse
|
||||||
AppControls2.StyleBackground {
|
AppControls2.StyleBackground {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
useStyleTransparent: false
|
useStyleTransparent: false
|
||||||
|
@ -323,7 +325,9 @@ RowLayout {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
width: 170; height: width
|
width: 170; height: width
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: name
|
||||||
|
ToolTip.visible: folderText.truncated && containsMouse
|
||||||
AppControls2.StyleBackground {
|
AppControls2.StyleBackground {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
useStyleTransparent: false
|
useStyleTransparent: false
|
||||||
|
@ -350,8 +354,8 @@ RowLayout {
|
||||||
|
|
||||||
AppControls2.FolderIcon {
|
AppControls2.FolderIcon {
|
||||||
id: folderIcon
|
id: folderIcon
|
||||||
width: 96
|
width: 86
|
||||||
height: 96
|
height: 86
|
||||||
rows: 4; columns: 4
|
rows: 4; columns: 4
|
||||||
spacing: 2; padding: 8
|
spacing: 2; padding: 8
|
||||||
icons: icon
|
icons: icon
|
||||||
|
@ -361,6 +365,7 @@ RowLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppControls2.StyleText {
|
AppControls2.StyleText {
|
||||||
|
id: folderText
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: 20
|
anchors.bottomMargin: 20
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -465,6 +470,7 @@ RowLayout {
|
||||||
height: GridView.view.cellHeight
|
height: GridView.view.cellHeight
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
id: labelAppsMouseArea
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
width: 170; height: width
|
width: 170; height: width
|
||||||
|
@ -483,6 +489,9 @@ RowLayout {
|
||||||
appIcon: modelData.icon
|
appIcon: modelData.icon
|
||||||
spacing: 8
|
spacing: 8
|
||||||
textHighLight: true
|
textHighLight: true
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: modelData.name
|
||||||
|
ToolTip.visible: textTruncated && labelAppsMouseArea.containsMouse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ Row {
|
||||||
id: powerButtonArea
|
id: powerButtonArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
ToolTip.delay: 500
|
||||||
ToolTip.visible: containsMouse
|
ToolTip.visible: containsMouse
|
||||||
ToolTip.text: powerButtonBase.toolTip
|
ToolTip.text: powerButtonBase.toolTip
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
|
@ -59,6 +59,9 @@ Item {
|
||||||
id: buttonMouseArea
|
id: buttonMouseArea
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: qsTr("Contract")
|
||||||
|
ToolTip.visible: containsMouse
|
||||||
onClicked: mainWindow.exitFullScreen()
|
onClicked: mainWindow.exitFullScreen()
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
|
|
|
@ -40,6 +40,9 @@ RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.maximumWidth: height
|
Layout.maximumWidth: height
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: qsTr("Switch Sort Type")
|
||||||
|
ToolTip.visible: containsMouse
|
||||||
|
|
||||||
highlight: mainWindow.isFullScreen
|
highlight: mainWindow.isFullScreen
|
||||||
autoHighLight: !mainWindow.isFullScreen
|
autoHighLight: !mainWindow.isFullScreen
|
||||||
|
@ -62,6 +65,10 @@ RowLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.maximumWidth: 16
|
Layout.maximumWidth: 16
|
||||||
Layout.maximumHeight: 16
|
Layout.maximumHeight: 16
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: qsTr("Sort Type Options")
|
||||||
|
ToolTip.visible: containsMouse
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
|
|
|
@ -106,8 +106,8 @@ AppControls2.StyleBackground {
|
||||||
appPage.content.resetFocus();
|
appPage.content.resetFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onEditingFinished: changeFocusToListView()
|
|
||||||
Keys.onDownPressed: changeFocusToListView()
|
Keys.onDownPressed: changeFocusToListView()
|
||||||
|
Keys.onReturnPressed: changeFocusToListView()
|
||||||
|
|
||||||
//字体选中跟随主题高亮
|
//字体选中跟随主题高亮
|
||||||
property int textColor: mainWindow.isFullScreen ? Palette.HighlightedText : Palette.Text
|
property int textColor: mainWindow.isFullScreen ? Palette.HighlightedText : Palette.Text
|
||||||
|
|
|
@ -76,6 +76,10 @@ Item {
|
||||||
id: buttonMouseArea
|
id: buttonMouseArea
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
ToolTip.delay: 500
|
||||||
|
ToolTip.text: qsTr("Expand")
|
||||||
|
ToolTip.visible: containsMouse
|
||||||
|
|
||||||
onClicked: mainWindow.isFullScreen = true
|
onClicked: mainWindow.isFullScreen = true
|
||||||
activeFocusOnTab: true
|
activeFocusOnTab: true
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
|
@ -135,6 +139,7 @@ Item {
|
||||||
id: powerButtonArea
|
id: powerButtonArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
ToolTip.delay: 500
|
||||||
ToolTip.visible: containsMouse
|
ToolTip.visible: containsMouse
|
||||||
ToolTip.text: powerButtonBase.toolTip
|
ToolTip.text: powerButtonBase.toolTip
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
|
@ -141,6 +141,9 @@ UkuiMenuExtension {
|
||||||
appIcon: model.icon
|
appIcon: model.icon
|
||||||
display: Display.TextUnderIcon
|
display: Display.TextUnderIcon
|
||||||
scale: (control.containsPress && !icon.hold) ? 1.1 : 1.0
|
scale: (control.containsPress && !icon.hold) ? 1.1 : 1.0
|
||||||
|
ToolTip.visible: textTruncated && control.containsMouse
|
||||||
|
ToolTip.text: model.name
|
||||||
|
ToolTip.delay: 500
|
||||||
|
|
||||||
Behavior on scale {
|
Behavior on scale {
|
||||||
NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
|
NumberAnimation { duration: 300; easing.type: Easing.InOutCubic }
|
||||||
|
|
|
@ -44,15 +44,19 @@ DataProviderManager::DataProviderManager()
|
||||||
void DataProviderManager::initProviders()
|
void DataProviderManager::initProviders()
|
||||||
{
|
{
|
||||||
auto *allProvider = new AllAppDataProvider;
|
auto *allProvider = new AllAppDataProvider;
|
||||||
|
connect(this, &DataProviderManager::toUpdate, allProvider, &AllAppDataProvider::update);
|
||||||
registerProvider(allProvider);
|
registerProvider(allProvider);
|
||||||
|
|
||||||
auto *search = new AppSearchPlugin;
|
auto *search = new AppSearchPlugin;
|
||||||
|
connect(this, &DataProviderManager::toUpdate, search, &AppSearchPlugin::update);
|
||||||
registerProvider(search);
|
registerProvider(search);
|
||||||
|
|
||||||
auto *category = new AppCategoryPlugin;
|
auto *category = new AppCategoryPlugin;
|
||||||
|
connect(this, &DataProviderManager::toUpdate, category, &AppCategoryPlugin::update);
|
||||||
registerProvider(category);
|
registerProvider(category);
|
||||||
|
|
||||||
auto *sort = new AppLetterSortPlugin;
|
auto *sort = new AppLetterSortPlugin;
|
||||||
|
connect(this, &DataProviderManager::toUpdate, sort, &AppLetterSortPlugin::update);
|
||||||
registerProvider(sort);
|
registerProvider(sort);
|
||||||
|
|
||||||
activateProvider(allProvider->id());
|
activateProvider(allProvider->id());
|
||||||
|
|
|
@ -59,6 +59,7 @@ Q_SIGNALS:
|
||||||
void pluginChanged(const QString &id, PluginGroup::Group group);
|
void pluginChanged(const QString &id, PluginGroup::Group group);
|
||||||
void dataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
|
void dataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
|
||||||
void labelChanged();
|
void labelChanged();
|
||||||
|
void toUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataProviderManager();
|
DataProviderManager();
|
||||||
|
|
|
@ -79,6 +79,9 @@ public:
|
||||||
virtual void forceUpdate() = 0;
|
virtual void forceUpdate() = 0;
|
||||||
virtual void forceUpdate(QString &key) {};
|
virtual void forceUpdate(QString &key) {};
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
virtual void update() {};
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* 数据变化
|
* 数据变化
|
||||||
|
|
|
@ -83,6 +83,24 @@ void AllAppDataProvider::forceUpdate()
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AllAppDataProvider::update()
|
||||||
|
{
|
||||||
|
bool isRecentDataChanged = false;
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
for (DataEntity & appdata : m_appData) {
|
||||||
|
bool info = appdata.isRecentInstall();
|
||||||
|
setRecentState(appdata);
|
||||||
|
if (appdata.isRecentInstall() != info) {
|
||||||
|
isRecentDataChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isRecentDataChanged) {
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AllAppDataProvider::reloadAppData()
|
void AllAppDataProvider::reloadAppData()
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
|
@ -39,6 +39,9 @@ public:
|
||||||
QVector<DataEntity> data() override;
|
QVector<DataEntity> data() override;
|
||||||
void forceUpdate() override;
|
void forceUpdate() override;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void update() override;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onAppAdded(const QList<DataEntity>& apps);
|
void onAppAdded(const QList<DataEntity>& apps);
|
||||||
void onAppDeleted(QStringList idList);
|
void onAppDeleted(QStringList idList);
|
||||||
|
|
|
@ -201,6 +201,7 @@ void AppCategoryPlugin::generateData(QVector<DataEntity> &data)
|
||||||
}
|
}
|
||||||
|
|
||||||
DataEntity label;
|
DataEntity label;
|
||||||
|
label.setComment(tr("Open Function Sort Menu"));
|
||||||
label.setType(DataType::Label);
|
label.setType(DataType::Label);
|
||||||
label.setId(item.label.id());
|
label.setId(item.label.id());
|
||||||
label.setName(item.label.displayName());
|
label.setName(item.label.displayName());
|
||||||
|
|
|
@ -162,7 +162,7 @@ void AppLetterSortPlugin::addAppToLabel(const QString &labelName, QVector<DataEn
|
||||||
|
|
||||||
if (!apps.isEmpty()) {
|
if (!apps.isEmpty()) {
|
||||||
DataEntity dataEntity;
|
DataEntity dataEntity;
|
||||||
dataEntity.setComment(tr("Letter sort button"));
|
dataEntity.setComment(tr("Open Letter Sort Menu"));
|
||||||
dataEntity.setName(labelName);
|
dataEntity.setName(labelName);
|
||||||
dataEntity.setId(labelName);
|
dataEntity.setId(labelName);
|
||||||
dataEntity.setType(DataType::Label);
|
dataEntity.setType(DataType::Label);
|
||||||
|
|
|
@ -119,8 +119,8 @@ void messageOutput(QtMsgType type, const QMessageLogContext &context, const QStr
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
startupTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
startupTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
|
||||||
initLogFile();
|
|
||||||
#ifndef UKUI_MENU_LOG_FILE_DISABLE
|
#ifndef UKUI_MENU_LOG_FILE_DISABLE
|
||||||
|
initLogFile();
|
||||||
qInstallMessageHandler(messageOutput);
|
qInstallMessageHandler(messageOutput);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -157,8 +157,13 @@ void GlobalSetting::initGlobalSettings()
|
||||||
|
|
||||||
//=
|
//=
|
||||||
settings.beginGroup("Default Favorite Apps");
|
settings.beginGroup("Default Favorite Apps");
|
||||||
|
QMap<int, QString> apps;
|
||||||
for (const auto &key : settings.allKeys()) {
|
for (const auto &key : settings.allKeys()) {
|
||||||
m_defaultFavoriteApps.append(settings.value(key).toString());
|
apps.insert(key.toInt(), settings.value(key).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &app : apps) {
|
||||||
|
m_defaultFavoriteApps.append(app);
|
||||||
}
|
}
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "items/theme-icon.h"
|
#include "items/theme-icon.h"
|
||||||
#include "app-manager.h"
|
#include "app-manager.h"
|
||||||
#include "menu-manager.h"
|
#include "menu-manager.h"
|
||||||
|
#include "data-provider-manager.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QCommandLineParser>
|
#include <QCommandLineParser>
|
||||||
|
@ -135,12 +136,16 @@ void UkuiMenuApplication::execCommand(Command command)
|
||||||
case Active: {
|
case Active: {
|
||||||
if (m_mainWindow) {
|
if (m_mainWindow) {
|
||||||
m_mainWindow->setVisible(!m_mainWindow->isVisible());
|
m_mainWindow->setVisible(!m_mainWindow->isVisible());
|
||||||
|
if (m_mainWindow->isVisible()) {
|
||||||
|
DataProviderManager::instance()->toUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Show: {
|
case Show: {
|
||||||
if (m_mainWindow) {
|
if (m_mainWindow) {
|
||||||
m_mainWindow->setVisible(true);
|
m_mainWindow->setVisible(true);
|
||||||
|
DataProviderManager::instance()->toUpdate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDBusReply>
|
#include <QDBusReply>
|
||||||
#include <QDBusInterface>
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusMessage>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
#define KYLIN_APP_MANAGER_NAME "com.kylin.AppManager"
|
#define KYLIN_APP_MANAGER_NAME "com.kylin.AppManager"
|
||||||
|
@ -38,13 +39,7 @@ AppManager *AppManager::instance()
|
||||||
|
|
||||||
AppManager::AppManager(QObject *parent) : QObject(parent)
|
AppManager::AppManager(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
m_appManagerDbusInterface = new QDBusInterface(KYLIN_APP_MANAGER_NAME,
|
|
||||||
KYLIN_APP_MANAGER_PATH,
|
|
||||||
KYLIN_APP_MANAGER_INTERFACE,
|
|
||||||
QDBusConnection::sessionBus());
|
|
||||||
if (!m_appManagerDbusInterface) {
|
|
||||||
qWarning() << "appManager dbus does not exists.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppManager::launchApp(const QString &desktopFilePath)
|
bool AppManager::launchApp(const QString &desktopFilePath)
|
||||||
|
@ -62,7 +57,7 @@ bool AppManager::launchApp(const QString &desktopFilePath)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QProcess::startDetached(cmd);
|
return QProcess::startDetached(cmd, QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppManager::launchBinaryApp(const QString &app, const QString &args)
|
bool AppManager::launchBinaryApp(const QString &app, const QString &args)
|
||||||
|
@ -77,16 +72,15 @@ bool AppManager::launchBinaryApp(const QString &app, const QString &args)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QProcess::startDetached(cmd);
|
return QProcess::startDetached(app, {args});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppManager::launchAppWithDBus(const QString &app)
|
bool AppManager::launchAppWithDBus(const QString &app)
|
||||||
{
|
{
|
||||||
if (!m_appManagerDbusInterface) {
|
QDBusMessage message = QDBusMessage::createMethodCall(KYLIN_APP_MANAGER_NAME, KYLIN_APP_MANAGER_PATH, KYLIN_APP_MANAGER_INTERFACE, "LaunchApp");
|
||||||
return false;
|
message << app;
|
||||||
}
|
|
||||||
|
|
||||||
QDBusReply<bool> status = m_appManagerDbusInterface->call("LaunchApp", app);
|
QDBusReply<bool> status(QDBusConnection::sessionBus().call(message));
|
||||||
return status.value();
|
return status.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@ private:
|
||||||
bool launchAppWithDBus(const QString &app);
|
bool launchAppWithDBus(const QString &app);
|
||||||
static QString parseDesktopFile(const QString &desktopFilePath);
|
static QString parseDesktopFile(const QString &desktopFilePath);
|
||||||
|
|
||||||
private:
|
|
||||||
QDBusInterface *m_appManagerDbusInterface = nullptr;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void request(UkuiMenuApplication::Command command);
|
void request(UkuiMenuApplication::Command command);
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,12 +102,9 @@ void WindowHelper::setWindowAttribute(QWindow *window)
|
||||||
|
|
||||||
// kwin
|
// kwin
|
||||||
KWindowSystem::setType(window->winId(), NET::Normal);
|
KWindowSystem::setType(window->winId(), NET::Normal);
|
||||||
KWindowSystem::setState(window->winId(), NET::SkipTaskbar | NET::SkipPager | NET::SkipSwitcher);
|
// 设置跳过多任务视图,设置跳过任务栏
|
||||||
if (!QX11Info::isPlatformX11()) {
|
kdk::WindowManager::setSkipTaskBar(window, true);
|
||||||
// wayland环境 设置跳过多任务视图,设置跳过任务栏s
|
kdk::WindowManager::setSkipSwitcher(window, true);
|
||||||
kdk::WindowManager::setSkipTaskBar(window, true);
|
|
||||||
kdk::WindowManager::setSkipSwitcher(window, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowHelper::removeHeaderBar(QWindow *window)
|
void WindowHelper::removeHeaderBar(QWindow *window)
|
||||||
|
|
|
@ -1,11 +1,36 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!DOCTYPE TS>
|
<!DOCTYPE TS>
|
||||||
<TS version="2.1" language="zh_CN">
|
<TS version="2.1" language="zh_CN">
|
||||||
|
<context>
|
||||||
|
<name>AppPageHeader</name>
|
||||||
|
<message>
|
||||||
|
<source>Search App</source>
|
||||||
|
<translation>搜索应用</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>FullScreenHeader</name>
|
||||||
|
<message>
|
||||||
|
<source>Contract</source>
|
||||||
|
<translation>收缩</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>LabelItem</name>
|
<name>LabelItem</name>
|
||||||
<message>
|
<message>
|
||||||
<source>Open the label selection interface</source>
|
<source>Open the label selection interface</source>
|
||||||
<translation>打开标签选择界面</translation>
|
<translation type="vanished">打开标签选择界面</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>PluginSelectMenu</name>
|
||||||
|
<message>
|
||||||
|
<source>Switch Sort Type</source>
|
||||||
|
<translation>切换排序类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Sort Type Options</source>
|
||||||
|
<translation>排序类型选项</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -90,6 +115,13 @@
|
||||||
<translation>搜索应用</translation>
|
<translation>搜索应用</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Sidebar</name>
|
||||||
|
<message>
|
||||||
|
<source>Expand</source>
|
||||||
|
<translation>展开</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>UkuiMenu::AllAppDataProvider</name>
|
<name>UkuiMenu::AllAppDataProvider</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -165,6 +197,10 @@
|
||||||
<source>Other</source>
|
<source>Other</source>
|
||||||
<translation>其他</translation>
|
<translation>其他</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open Function Sort Menu</source>
|
||||||
|
<translation>打开功能排序菜单</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>UkuiMenu::AppFolderHelper</name>
|
<name>UkuiMenu::AppFolderHelper</name>
|
||||||
|
@ -181,7 +217,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Letter sort button</source>
|
<source>Letter sort button</source>
|
||||||
<translation>字母排序按钮</translation>
|
<translation type="vanished">字母排序按钮</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Open Letter Sort Menu</source>
|
||||||
|
<translation>打开字母排序菜单</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -210,11 +250,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Hibernate</source>
|
<source>Hibernate</source>
|
||||||
<translation>睡眠</translation>
|
<translation>休眠</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Suspend</source>
|
<source>Suspend</source>
|
||||||
<translation>休眠</translation>
|
<translation>睡眠</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Lock Screen</source>
|
<source>Lock Screen</source>
|
||||||
|
|
Loading…
Reference in New Issue