diff --git a/CMakeLists.txt b/CMakeLists.txt index b1d24c5..513ef30 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,12 +65,14 @@ message(STATUS "QML_IMPORT_PATH: ${QML_IMPORT_PATH}") set(UKUI_MENU_DATA_DIR "/usr/share/ukui-menu") set(UKUI_MENU_TRANSLATION_DIR "${UKUI_MENU_DATA_DIR}/translations") 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") # 宏定义 add_compile_definitions(UKUI_MENU_TRANSLATION_DIR="${UKUI_MENU_TRANSLATION_DIR}" UKUI_MENU_DATA_DIR="${UKUI_MENU_DATA_DIR}" UKUI_MENU_EXTENSION_DIR="${UKUI_MENU_EXTENSION_DIR}" + UKUI_MENU_GLOBAL_CONFIG_FILE="${UKUI_MENU_GLOBAL_CONFIG_FILE}" ) # ukui-menu的源码 diff --git a/data/ukui-menu-global-config.conf b/data/ukui-menu-global-config.conf new file mode 100644 index 0000000..8b6914f --- /dev/null +++ b/data/ukui-menu-global-config.conf @@ -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 diff --git a/qml/AppControls2/AppItem.qml b/qml/AppControls2/AppItem.qml index c2b3523..8274c88 100644 --- a/qml/AppControls2/AppItem.qml +++ b/qml/AppControls2/AppItem.qml @@ -24,12 +24,11 @@ StyleBackground { hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton - onPressed: { - if (mouse.button === Qt.RightButton) { - console.log("RightButtononPressed:",mouse.x,mouse.y); - } - } onClicked: { + if (mouse.button === Qt.RightButton) { + appListView.model.openMenu(index); + return + } if (mouse.button === Qt.LeftButton) { appListView.model.appClicked(index); } diff --git a/src/menu/menu-manager.cpp b/src/menu/menu-manager.cpp index d0e31ce..e159d4a 100644 --- a/src/menu/menu-manager.cpp +++ b/src/menu/menu-manager.cpp @@ -21,9 +21,135 @@ #include #include +#include +#include namespace UkuiMenu { +class AppMenuProvider : public MenuProvider +{ +public: + AppMenuProvider(); + int index() override { return 1024; } + QList generateActions(QObject *parent, const RequestType &type, const QVariant &data) override; + +private: + void addToPanelAction(QObject *parent, const QString &appId, QList &list); + void addToDesktopAction(QObject *parent, const QString &appId, QList &list); + void addUninstall(QObject *parent, const QString &appId, QList &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 +AppMenuProvider::generateActions(QObject *parent, const MenuProvider::RequestType &type, const QVariant &data) +{ + if (!parent || (type != DataType)) { + return {}; + } + + DataEntity app = data.value(); + if (app.type() != DataType::Normal) { + return {}; + } + + QList 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 &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 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 ret = iface.call(functionName, appId); + + if (!ret.isValid() || !ret) { + qWarning() << "Add/Remove from taskbar error"; + } + }); +} + +void AppMenuProvider::addToDesktopAction(QObject *parent, const QString &appId, QList &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 &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() { static MenuManager manager; @@ -32,7 +158,7 @@ MenuManager *MenuManager::instance() MenuManager::MenuManager() { - + registerMenuProvider(new AppMenuProvider); } MenuManager::~MenuManager() diff --git a/src/model/model.cpp b/src/model/model.cpp index 131b84c..26e1ad8 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -18,12 +18,12 @@ #include "model.h" #include "app-manager.h" +#include "menu-manager.h" #include #include #include - -namespace UkuiMenu { +using namespace UkuiMenu; AppModel::AppModel(QObject *parent) : QAbstractListModel(parent) { @@ -175,4 +175,11 @@ void AppModel::insertData(QVector &data, int index) 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)); +} diff --git a/src/model/model.h b/src/model/model.h index 391bf60..ca681d3 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -40,6 +40,7 @@ public: Q_INVOKABLE int currentAppIndex(const QString &id); Q_INVOKABLE QVariantList folderApps(const QString &folderName); Q_INVOKABLE void appClicked(const int &index); + Q_INVOKABLE void openMenu(const int &index); private Q_SLOTS: void onPluginDataChanged(QVector data, DataUpdateMode::Mode mode, quint32 index); diff --git a/src/utils/app-manager.cpp b/src/utils/app-manager.cpp index 677a262..f663579 100644 --- a/src/utils/app-manager.cpp +++ b/src/utils/app-manager.cpp @@ -61,13 +61,28 @@ bool AppManager::launchApp(const QString &desktopFilePath) 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) { return false; } - QDBusReply status = m_appManagerDbusInterface->call("LaunchApp", desktopFilePath); + QDBusReply status = m_appManagerDbusInterface->call("LaunchApp", app); return status.value(); } diff --git a/src/utils/app-manager.h b/src/utils/app-manager.h index 78fada2..eabcbf0 100644 --- a/src/utils/app-manager.h +++ b/src/utils/app-manager.h @@ -33,10 +33,11 @@ public: AppManager &operator = (const AppManager &obj) = delete; bool launchApp(const QString &desktopFilePath); + bool launchBinaryApp(const QString &app, const QString &args = QString()); private: explicit AppManager(QObject *parent = nullptr); - bool launchAppWithDBus(const QString &desktopFilePath); + bool launchAppWithDBus(const QString &app); static QString parseDesktopFile(const QString &desktopFilePath); private: