添加开始菜单应用项右键菜单功能
This commit is contained in:
parent
19eefc13fd
commit
92a4badea3
|
@ -65,12 +65,14 @@ message(STATUS "QML_IMPORT_PATH: ${QML_IMPORT_PATH}")
|
||||||
set(UKUI_MENU_DATA_DIR "/usr/share/ukui-menu")
|
set(UKUI_MENU_DATA_DIR "/usr/share/ukui-menu")
|
||||||
set(UKUI_MENU_TRANSLATION_DIR "${UKUI_MENU_DATA_DIR}/translations")
|
set(UKUI_MENU_TRANSLATION_DIR "${UKUI_MENU_DATA_DIR}/translations")
|
||||||
set(UKUI_MENU_EXTENSION_DIR "${UKUI_MENU_DATA_DIR}/extensions")
|
set(UKUI_MENU_EXTENSION_DIR "${UKUI_MENU_DATA_DIR}/extensions")
|
||||||
|
set(UKUI_MENU_GLOBAL_CONFIG_FILE "${UKUI_MENU_DATA_DIR}/ukui-menu-global-config.conf")
|
||||||
#set(UKUI_MENU_EXTENSION_IFACE_QML_DIR "/usr/lib/x86_64-linux-gnu/qt5/qml/org/ukui/menu/extension")
|
#set(UKUI_MENU_EXTENSION_IFACE_QML_DIR "/usr/lib/x86_64-linux-gnu/qt5/qml/org/ukui/menu/extension")
|
||||||
|
|
||||||
# 宏定义
|
# 宏定义
|
||||||
add_compile_definitions(UKUI_MENU_TRANSLATION_DIR="${UKUI_MENU_TRANSLATION_DIR}"
|
add_compile_definitions(UKUI_MENU_TRANSLATION_DIR="${UKUI_MENU_TRANSLATION_DIR}"
|
||||||
UKUI_MENU_DATA_DIR="${UKUI_MENU_DATA_DIR}"
|
UKUI_MENU_DATA_DIR="${UKUI_MENU_DATA_DIR}"
|
||||||
UKUI_MENU_EXTENSION_DIR="${UKUI_MENU_EXTENSION_DIR}"
|
UKUI_MENU_EXTENSION_DIR="${UKUI_MENU_EXTENSION_DIR}"
|
||||||
|
UKUI_MENU_GLOBAL_CONFIG_FILE="${UKUI_MENU_GLOBAL_CONFIG_FILE}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ukui-menu的源码
|
# ukui-menu的源码
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# can not uninstall "System Apps"
|
||||||
|
[System Apps]
|
||||||
|
kylin-screenshot.desktop=0
|
||||||
|
ukui-notebook.desktop=0
|
||||||
|
ukui-clock.desktop=0
|
||||||
|
kylin-calculator.desktop=0
|
||||||
|
kylin-recorder.desktop=0
|
||||||
|
kylin-software-center.desktop=0
|
||||||
|
kylin-camera.desktop=0
|
||||||
|
biometric-manager.desktop=0
|
||||||
|
yhkylin-backup-tools.desktop=0
|
||||||
|
box-manager.desktop=0
|
||||||
|
ukui-system-monitor.desktop=0
|
||||||
|
ksc-defender.desktop=0
|
||||||
|
logview.desktop=0
|
||||||
|
kylin-service-support.desktop=0
|
||||||
|
kylin-user-guide.desktop=0
|
||||||
|
ukui-control-center.desktop=0
|
||||||
|
peony.desktop=0
|
||||||
|
engrampa.desktop=0
|
|
@ -24,12 +24,11 @@ StyleBackground {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
console.log("RightButtononPressed:",mouse.x,mouse.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
appListView.model.openMenu(index);
|
||||||
|
return
|
||||||
|
}
|
||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
appListView.model.appClicked(index);
|
appListView.model.appClicked(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,135 @@
|
||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDBusReply>
|
||||||
|
|
||||||
namespace UkuiMenu {
|
namespace UkuiMenu {
|
||||||
|
|
||||||
|
class AppMenuProvider : public MenuProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AppMenuProvider();
|
||||||
|
int index() override { return 1024; }
|
||||||
|
QList<QAction *> generateActions(QObject *parent, const RequestType &type, const QVariant &data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addToPanelAction(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||||
|
void addToDesktopAction(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||||
|
void addUninstall(QObject *parent, const QString &appId, QList<QAction *> &list);
|
||||||
|
private:
|
||||||
|
QStringList m_systemApps;
|
||||||
|
};
|
||||||
|
|
||||||
|
AppMenuProvider::AppMenuProvider()
|
||||||
|
{
|
||||||
|
if (QFile::exists(UKUI_MENU_GLOBAL_CONFIG_FILE)) {
|
||||||
|
QSettings settings(UKUI_MENU_GLOBAL_CONFIG_FILE, QSettings::IniFormat);
|
||||||
|
settings.beginGroup("System Apps");
|
||||||
|
m_systemApps.append(settings.allKeys());
|
||||||
|
settings.endGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAction *>
|
||||||
|
AppMenuProvider::generateActions(QObject *parent, const MenuProvider::RequestType &type, const QVariant &data)
|
||||||
|
{
|
||||||
|
if (!parent || (type != DataType)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
DataEntity app = data.value<DataEntity>();
|
||||||
|
if (app.type() != DataType::Normal) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAction *> list;
|
||||||
|
QString appId = app.id();
|
||||||
|
|
||||||
|
// 添加到任务栏
|
||||||
|
addToPanelAction(parent, appId, list);
|
||||||
|
|
||||||
|
//添加到桌面快捷方式
|
||||||
|
addToDesktopAction(parent, appId, list);
|
||||||
|
|
||||||
|
// 卸载
|
||||||
|
addUninstall(parent, appId, list);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppMenuProvider::addToPanelAction(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||||
|
{
|
||||||
|
QDBusInterface iface("com.ukui.panel.desktop", "/", "com.ukui.panel.desktop", QDBusConnection::sessionBus());
|
||||||
|
|
||||||
|
if (!iface.isValid()) {
|
||||||
|
qWarning() << "Panel desktop dbusinterface error";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iface.setTimeout(1);
|
||||||
|
QDBusReply<bool> isFixedOnTaskBar = iface.call("CheckIfExist", appId);
|
||||||
|
|
||||||
|
if (!isFixedOnTaskBar.isValid()) {
|
||||||
|
qWarning() << "Panel desktop dbusinterface call CheckIfExist timeout";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString actionName = isFixedOnTaskBar ? QObject::tr("Remove From Taskbar") : QObject::tr("Add To Taskbar");
|
||||||
|
QString functionName = isFixedOnTaskBar ? "RemoveFromTaskbar" : "AddToTaskbar";
|
||||||
|
list << new QAction(actionName);
|
||||||
|
|
||||||
|
QObject::connect(list.last(), &QAction::triggered, parent, [appId, functionName] {
|
||||||
|
QDBusInterface iface("com.ukui.panel.desktop", "/", "com.ukui.panel.desktop", QDBusConnection::sessionBus());
|
||||||
|
|
||||||
|
if (!iface.isValid()) {
|
||||||
|
qWarning() << "Panel desktop dbusinterface error";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iface.setTimeout(1);
|
||||||
|
QDBusReply<bool> ret = iface.call(functionName, appId);
|
||||||
|
|
||||||
|
if (!ret.isValid() || !ret) {
|
||||||
|
qWarning() << "Add/Remove from taskbar error";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppMenuProvider::addToDesktopAction(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||||
|
{
|
||||||
|
list << new QAction(QObject::tr("Add to desktop shortcuts"));
|
||||||
|
|
||||||
|
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
|
QString path = QString(desktopPath + "/" + QFileInfo(appId).fileName());
|
||||||
|
|
||||||
|
if (QFile::exists(path)) {
|
||||||
|
list.last()->setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(list.last(), &QAction::triggered, parent, [appId, path] {
|
||||||
|
QFile file(appId);
|
||||||
|
bool ret = file.copy(path);
|
||||||
|
if (ret) {
|
||||||
|
QProcess::startDetached("chmod a+x " + path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppMenuProvider::addUninstall(QObject *parent, const QString &appId, QList<QAction *> &list)
|
||||||
|
{
|
||||||
|
bool isSystemApp = std::any_of(m_systemApps.constBegin(), m_systemApps.constEnd(), [&appId](const QString &appName) {
|
||||||
|
return appId.contains(appName);
|
||||||
|
});
|
||||||
|
if (!isSystemApp) {
|
||||||
|
list << new QAction(QObject::tr("Uninstall")); //QIcon::fromTheme("edit-delete-symbolic")
|
||||||
|
QObject::connect(list.last(), &QAction::triggered, parent, [appId] {
|
||||||
|
AppManager::instance()->launchBinaryApp("kylin-uninstaller", appId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MenuManager *MenuManager::instance()
|
MenuManager *MenuManager::instance()
|
||||||
{
|
{
|
||||||
static MenuManager manager;
|
static MenuManager manager;
|
||||||
|
@ -32,7 +158,7 @@ MenuManager *MenuManager::instance()
|
||||||
|
|
||||||
MenuManager::MenuManager()
|
MenuManager::MenuManager()
|
||||||
{
|
{
|
||||||
|
registerMenuProvider(new AppMenuProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuManager::~MenuManager()
|
MenuManager::~MenuManager()
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "app-manager.h"
|
#include "app-manager.h"
|
||||||
|
#include "menu-manager.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
using namespace UkuiMenu;
|
||||||
namespace UkuiMenu {
|
|
||||||
|
|
||||||
AppModel::AppModel(QObject *parent) : QAbstractListModel(parent)
|
AppModel::AppModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
@ -175,4 +175,11 @@ void AppModel::insertData(QVector<DataEntity> &data, int index)
|
||||||
Q_EMIT endInsertRows();
|
Q_EMIT endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // UkuiMenu
|
void AppModel::openMenu(const int &index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= m_apps.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuManager::instance()->showMenu(m_apps.at(index));
|
||||||
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
Q_INVOKABLE int currentAppIndex(const QString &id);
|
Q_INVOKABLE int currentAppIndex(const QString &id);
|
||||||
Q_INVOKABLE QVariantList folderApps(const QString &folderName);
|
Q_INVOKABLE QVariantList folderApps(const QString &folderName);
|
||||||
Q_INVOKABLE void appClicked(const int &index);
|
Q_INVOKABLE void appClicked(const int &index);
|
||||||
|
Q_INVOKABLE void openMenu(const int &index);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void onPluginDataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
|
void onPluginDataChanged(QVector<DataEntity> data, DataUpdateMode::Mode mode, quint32 index);
|
||||||
|
|
|
@ -61,13 +61,28 @@ bool AppManager::launchApp(const QString &desktopFilePath)
|
||||||
return QProcess::startDetached(cmd);
|
return QProcess::startDetached(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppManager::launchAppWithDBus(const QString &desktopFilePath)
|
bool AppManager::launchBinaryApp(const QString &app, const QString &args)
|
||||||
|
{
|
||||||
|
if (app.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString cmd = app + " " + args;
|
||||||
|
// qDebug() << "launchBinaryApp" << cmd;
|
||||||
|
if (launchAppWithDBus(cmd)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QProcess::startDetached(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppManager::launchAppWithDBus(const QString &app)
|
||||||
{
|
{
|
||||||
if (!m_appManagerDbusInterface) {
|
if (!m_appManagerDbusInterface) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDBusReply<bool> status = m_appManagerDbusInterface->call("LaunchApp", desktopFilePath);
|
QDBusReply<bool> status = m_appManagerDbusInterface->call("LaunchApp", app);
|
||||||
return status.value();
|
return status.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,11 @@ public:
|
||||||
AppManager &operator = (const AppManager &obj) = delete;
|
AppManager &operator = (const AppManager &obj) = delete;
|
||||||
|
|
||||||
bool launchApp(const QString &desktopFilePath);
|
bool launchApp(const QString &desktopFilePath);
|
||||||
|
bool launchBinaryApp(const QString &app, const QString &args = QString());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit AppManager(QObject *parent = nullptr);
|
explicit AppManager(QObject *parent = nullptr);
|
||||||
bool launchAppWithDBus(const QString &desktopFilePath);
|
bool launchAppWithDBus(const QString &app);
|
||||||
static QString parseDesktopFile(const QString &desktopFilePath);
|
static QString parseDesktopFile(const QString &desktopFilePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue