2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8 #include "dolphinpackageinstaller.h"
10 #include <KLocalizedString>
13 #include <PackageKit/Daemon>
15 #include <QDesktopServices>
21 DolphinPackageInstaller::DolphinPackageInstaller(const QString
&packageName
,
22 const QUrl
&fallBackInstallationPageUrl
,
23 std::function
<bool()> isPackageInstalledCheck
,
26 , m_packageName
{packageName
}
27 , m_fallBackInstallationPageUrl
{fallBackInstallationPageUrl
}
28 , m_isPackageInstalledCheck
{isPackageInstalledCheck
}
32 void DolphinPackageInstaller::start()
34 if (m_isPackageInstalledCheck()) {
40 PackageKit::Daemon::setHints(PackageKit::Daemon::hints() + QStringList
{QStringLiteral("interactive=true")});
41 const PackageKit::Transaction
*resolveTransaction
= PackageKit::Daemon::resolve(m_packageName
);
43 connect(resolveTransaction
, &PackageKit::Transaction::errorCode
, this, &DolphinPackageInstaller::slotInstallationFailed
);
44 connect(resolveTransaction
, &PackageKit::Transaction::finished
, this, [this]() { // Will be disconnected if we find a package.
45 slotInstallationFailed(PackageKit::Transaction::ErrorPackageNotFound
,
46 i18nc("@info:shell about system packages", "Could not find package %1.", m_packageName
));
48 connect(resolveTransaction
,
49 &PackageKit::Transaction::package
,
51 [this, resolveTransaction
](PackageKit::Transaction::Info
/* info */, const QString
&packageId
) {
52 disconnect(resolveTransaction
, nullptr, this, nullptr); // We only care about the first package.
56 QDesktopServices::openUrl(m_fallBackInstallationPageUrl
);
57 auto waitForSuccess
= new QTimer(this);
58 connect(waitForSuccess
, &QTimer::timeout
, this, [this]() {
59 if (m_isPackageInstalledCheck()) {
63 waitForSuccess
->start(3000);
68 void DolphinPackageInstaller::install(const QString
&packageId
)
70 const PackageKit::Transaction
*installTransaction
= PackageKit::Daemon::installPackage(packageId
);
71 connectTransactionToJobProgress(*installTransaction
);
72 connect(installTransaction
,
73 &PackageKit::Transaction::errorCode
,
75 [installTransaction
, this](PackageKit::Transaction::Error error
, const QString
&details
) {
76 disconnect(installTransaction
, nullptr, this, nullptr); // We only want to emit a result once.
77 slotInstallationFailed(error
, details
);
79 connect(installTransaction
,
80 &PackageKit::Transaction::finished
,
82 [installTransaction
, this](const PackageKit::Transaction::Exit status
, uint
/* runtime */) {
83 disconnect(installTransaction
, nullptr, this, nullptr); // We only want to emit a result once.
84 if (status
== PackageKit::Transaction::ExitSuccess
) {
87 slotInstallationFailed(PackageKit::Transaction::ErrorUnknown
,
88 i18nc("@info %1 is error code",
89 "Installation exited without reporting success. (%1)",
90 QMetaEnum::fromType
<PackageKit::Transaction::Exit
>().valueToKey(status
)));
95 void DolphinPackageInstaller::connectTransactionToJobProgress(const PackageKit::Transaction
&transaction
)
97 connect(&transaction
, &PackageKit::Transaction::speedChanged
, this, [this, &transaction
]() {
98 emitSpeed(transaction
.speed());
100 connect(&transaction
, &PackageKit::Transaction::percentageChanged
, this, [this, &transaction
]() {
101 setPercent(transaction
.percentage());
105 void DolphinPackageInstaller::slotInstallationFailed(PackageKit::Transaction::Error error
, const QString
&details
)
107 setErrorString(xi18nc("@info:shell %1 is package name, %2 is error message, %3 is error e.g. 'ErrorNoNetwork'",
108 "Installing <application>%1</application> failed: %2 (%3)<nl/>Please try installing <application>%1</application> manually instead.",
111 QMetaEnum::fromType
<PackageKit::Transaction::Error
>().valueToKey(error
)));