diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,13 @@ find_package(Phonon4Qt5 CONFIG REQUIRED) +find_package(PackageKitQt5) +set_package_properties(PackageKitQt5 + PROPERTIES DESCRIPTION "Software Manager integration" + TYPE REQUIRED + PURPOSE "Needed for the service menu installer" + ) + find_package(KF5Baloo ${KF5_MIN_VERSION}) set_package_properties(KF5Baloo PROPERTIES DESCRIPTION "Baloo Core libraries" URL "https://www.kde.org" diff --git a/src/settings/services/servicemenuinstaller/CMakeLists.txt b/src/settings/services/servicemenuinstaller/CMakeLists.txt --- a/src/settings/services/servicemenuinstaller/CMakeLists.txt +++ b/src/settings/services/servicemenuinstaller/CMakeLists.txt @@ -6,5 +6,6 @@ Qt5::Core Qt5::Gui KF5::I18n + PK::packagekitqt5 ) install(TARGETS servicemenuinstaller ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp --- a/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp +++ b/src/settings/services/servicemenuinstaller/servicemenuinstaller.cpp @@ -26,11 +26,14 @@ #include #include #include -#include #include #include +#include +#include +#include + // @param msg Error that gets logged to CLI Q_NORETURN void fail(const QString &str) { @@ -52,6 +55,61 @@ return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus"); } +void packageKitInstall(const QString &fileName) +{ + PackageKit::Transaction *transaction = PackageKit::Daemon::installFile(fileName); + + QObject::connect(transaction, &PackageKit::Transaction::finished, + [](PackageKit::Transaction::Exit status, uint) { + if (status == PackageKit::Transaction::ExitSuccess) { + exit(0); + } + fail(i18n("Package installation exited with status \"%1\"", + QVariant::fromValue(status).toString())); + }); +} + +void packageKitUninstall(const QString &fileName) +{ + PackageKit::Transaction *transaction = PackageKit::Daemon::getDetailsLocal(fileName); + QObject::connect(transaction, &PackageKit::Transaction::details, + [=](const PackageKit::Details &details) { + PackageKit::Transaction *transaction = PackageKit::Daemon::removePackage(details.packageId()); + QObject::connect(transaction, &PackageKit::Transaction::finished, + [=](PackageKit::Transaction::Exit status, uint) { + if (status == PackageKit::Transaction::ExitSuccess) { + exit(0); + } + fail(i18n("Package removal exited with status \"%1\"", + QVariant::fromValue(status).toString())); + }); + }); + + QObject::connect(transaction, &PackageKit::Transaction::finished, + [](PackageKit::Transaction::Exit status, uint) { + if (status != PackageKit::Transaction::ExitSuccess) { + fail(i18n("Package removal failed exited with status \"%1\"", + QVariant::fromValue(status).toString())); + } + }); +} + +Q_NORETURN void packageKit(bool install, const QString &fileName) +{ + QFile file(fileName); + if (!file.exists()) { + fail(i18n("The file does not exist!")); + } + const QString absPath = QFileInfo(file).absoluteFilePath(); + if (install) { + packageKitInstall(absPath); + } else { + packageKitUninstall(absPath); + } + QGuiApplication::exec(); // For event handling, no return after signals finish + fail(i18n("Unknown error when installing package")); +} + struct UncompressCommand { QString command; @@ -204,7 +262,7 @@ } else { const QStringList binaryPackages = {"application/vnd.debian.binary-package", "application/x-rpm"}; if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) { - return QDesktopServices::openUrl(QUrl(archive)); + packageKit(true, archive); } const QString dir = generateDirPath(archive); if (QFile::exists(dir)) { @@ -268,6 +326,10 @@ return false; } } else { + const QStringList binaryPackages = {"application/vnd.debian.binary-package", "application/x-rpm"}; + if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) { + packageKit(false, archive); + } const QString dir = generateDirPath(archive); // Try "deinstall" first