diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,18 @@ find_package(Phonon4Qt5 CONFIG REQUIRED) +find_package(PackageKitQt5) +set_package_properties(PackageKitQt5 + PROPERTIES DESCRIPTION "Software Manager integration" + TYPE OPTIONAL + PURPOSE "Used in the service menu installer" + ) +if(PackageKitQt5_FOUND) + set(PACKAGEKIT_AVAILABLE true) + add_definitions(-DPACKAGEKIT_AVAILABLE=true) +else() + add_definitions(-DPACKAGEKIT_AVAILABLE=false) +endif() 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 @@ -2,9 +2,12 @@ add_definitions(-DTRANSLATION_DOMAIN=\"dolphin_servicemenuinstaller\") add_executable(servicemenuinstaller servicemenuinstaller.cpp) -target_link_libraries(servicemenuinstaller PRIVATE +target_link_libraries(servicemenuinstaller Qt5::Core Qt5::Gui KF5::I18n ) +if(PACKAGEKIT_AVAILABLE) + target_link_libraries(servicemenuinstaller PK::packagekitqt5) +endif() 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,19 @@ #include #include #include -#include #include #include +static QStringList binaryPackages = {"application/vnd.debian.binary-package", "application/x-rpm"}; +#if PACKAGEKIT_AVAILABLE +#include +#include +#include +#else +#include +#endif + // @param msg Error that gets logged to CLI Q_NORETURN void fail(const QString &str) { @@ -52,6 +60,70 @@ return QDir(dataLocation).absoluteFilePath("kservices5/ServiceMenus"); } +#if PACKAGEKIT_AVAILABLE +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("Failed to install \"%1\", exited with status \"%2\"", + fileName, QVariant::fromValue(status).toString())); + }); +} + +void packageKitUninstall(const QString &fileName) +{ + const auto uninstallLambda = [=](PackageKit::Transaction::Exit status, uint) { + if (status == PackageKit::Transaction::ExitSuccess) { + exit(0); + } + fail(i18n("Failed to remove \"%1\", exited with status \"%2\"", + fileName, QVariant::fromValue(status).toString())); + }; + + 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, uninstallLambda); + }); + + const auto uninstallDetailsErrorLambda = [=](PackageKit::Transaction::Exit status, uint) { + if (status != PackageKit::Transaction::ExitSuccess) { + fail(i18n("Failed to remove \"%1\", exited with status \"%2\"", + fileName, QVariant::fromValue(status).toString())); + } + }; + QObject::connect(transaction, &PackageKit::Transaction::finished, uninstallDetailsErrorLambda); +} +#endif + +Q_NORETURN void packageKit(bool install, const QString &fileName) +{ +#if PACKAGEKIT_AVAILABLE + 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")); +#else + Q_UNUSED(install) + QDesktopServices::openUrl(QUrl(fileName)); + exit(0); +#endif +} + struct UncompressCommand { QString command; @@ -202,9 +274,8 @@ return false; } } 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 +339,9 @@ return false; } } else { + if (binaryPackages.contains(QMimeDatabase().mimeTypeForFile(archive).name())) { + packageKit(false, archive); + } const QString dir = generateDirPath(archive); // Try "deinstall" first