Merge tag 'upstream/4.0.0.3' into packaging/openkylin/yangtze

4.0.0.3-release
This commit is contained in:
hewenfei 2023-06-06 11:33:46 +08:00
commit c337510482
31 changed files with 325 additions and 201 deletions

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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:

View File

@ -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>

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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: {

View File

@ -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

View File

@ -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
} }
} }

View File

@ -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

View File

@ -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: {

View File

@ -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: {

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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());

View File

@ -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();

View File

@ -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:
/** /**
* *

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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);

View File

@ -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

View File

@ -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();
} }

View File

@ -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;
} }

View File

@ -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();
} }

View File

@ -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);
}; };

View File

@ -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)

View File

@ -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>