]> cloud.milkyroute.net Git - dolphin.git/blob - src/dolphinpackageinstaller.cpp
Apply 2 suggestion(s) to 1 file(s)
[dolphin.git] / src / dolphinpackageinstaller.cpp
1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #include "dolphinpackageinstaller.h"
9
10 #include <KLocalizedString>
11
12 #if HAVE_PACKAGEKIT
13 #include <PackageKit/Daemon>
14 #else
15 #include <QDesktopServices>
16 #endif
17
18 #include <QTimer>
19 #include <QtAssert>
20
21 DolphinPackageInstaller::DolphinPackageInstaller(const QString &packageName,
22 const QUrl &fallBackInstallationPageUrl,
23 std::function<bool()> isPackageInstalledCheck,
24 QObject *parent)
25 : KJob(parent)
26 , m_packageName{packageName}
27 , m_fallBackInstallationPageUrl{fallBackInstallationPageUrl}
28 , m_isPackageInstalledCheck{isPackageInstalledCheck}
29 {
30 }
31
32 void DolphinPackageInstaller::start()
33 {
34 if (m_isPackageInstalledCheck()) {
35 emitResult();
36 return;
37 }
38
39 #if HAVE_PACKAGEKIT
40 PackageKit::Daemon::setHints(PackageKit::Daemon::hints() + QStringList{QStringLiteral("interactive=true")});
41 const PackageKit::Transaction *resolveTransaction = PackageKit::Daemon::resolve(m_packageName);
42
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));
47 });
48 connect(resolveTransaction,
49 &PackageKit::Transaction::package,
50 this,
51 [this, resolveTransaction](PackageKit::Transaction::Info /* info */, const QString &packageId) {
52 disconnect(resolveTransaction, nullptr, this, nullptr); // We only care about the first package.
53 install(packageId);
54 });
55 #else
56 QDesktopServices::openUrl(m_fallBackInstallationPageUrl);
57 auto waitForSuccess = new QTimer(this);
58 connect(waitForSuccess, &QTimer::timeout, this, [this]() {
59 if (m_isPackageInstalledCheck()) {
60 emitResult();
61 }
62 });
63 waitForSuccess->start(3000);
64 #endif
65 }
66
67 #if HAVE_PACKAGEKIT
68 void DolphinPackageInstaller::install(const QString &packageId)
69 {
70 const PackageKit::Transaction *installTransaction = PackageKit::Daemon::installPackage(packageId);
71 connectTransactionToJobProgress(*installTransaction);
72 connect(installTransaction,
73 &PackageKit::Transaction::errorCode,
74 this,
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);
78 });
79 connect(installTransaction,
80 &PackageKit::Transaction::finished,
81 this,
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) {
85 emitResult();
86 } else {
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)));
91 }
92 });
93 }
94
95 void DolphinPackageInstaller::connectTransactionToJobProgress(const PackageKit::Transaction &transaction)
96 {
97 connect(&transaction, &PackageKit::Transaction::speedChanged, this, [this, &transaction]() {
98 emitSpeed(transaction.speed());
99 });
100 connect(&transaction, &PackageKit::Transaction::percentageChanged, this, [this, &transaction]() {
101 setPercent(transaction.percentage());
102 });
103 }
104
105 void DolphinPackageInstaller::slotInstallationFailed(PackageKit::Transaction::Error error, const QString &details)
106 {
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.",
109 m_packageName,
110 details,
111 QMetaEnum::fromType<PackageKit::Transaction::Error>().valueToKey(error)));
112 setError(error);
113 emitResult();
114 }
115 #endif