diff --git a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp index 8af5a446..bee92691 100644 --- a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp +++ b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp @@ -1,211 +1,222 @@ /*************************************************************************** * Copyright © 2013 Aleix Pol Gonzalez * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ #include "AppPackageKitResource.h" #include #include #include #include #include #include #include #include #include #include #include #include "config-paths.h" #include #include AppPackageKitResource::AppPackageKitResource(const AppStream::Component& data, const QString &packageName, PackageKitBackend* parent) : PackageKitResource(packageName, QString(), parent) , m_appdata(data) { Q_ASSERT(data.isValid()); } QString AppPackageKitResource::name() const { QString ret; if (!m_appdata.extends().isEmpty()) { auto components = backend()->componentsById(m_appdata.extends().constFirst()); if (components.isEmpty()) qWarning() << "couldn't find" << m_appdata.extends() << "which is supposedly extended by" << m_appdata.id(); else ret = components.constFirst().name() + QStringLiteral(" - ") + m_appdata.name(); } if (ret.isEmpty()) ret = m_appdata.name(); return ret; } QString AppPackageKitResource::longDescription() { const auto desc = m_appdata.description(); if (!desc.isEmpty()) return desc; return PackageKitResource::longDescription(); } static QIcon componentIcon(const AppStream::Component &comp) { QIcon ret; const auto icons = comp.icons(); if (icons.isEmpty()) { ret = QIcon::fromTheme(QStringLiteral("package-x-generic")); } else foreach(const AppStream::Icon &icon, icons) { QStringList stock; switch(icon.kind()) { case AppStream::Icon::KindLocal: ret.addFile(icon.url().toLocalFile(), icon.size()); break; case AppStream::Icon::KindCached: ret.addFile(icon.url().toLocalFile(), icon.size()); break; case AppStream::Icon::KindStock: stock += icon.name(); break; default: break; } if (ret.isNull() && !stock.isEmpty()) { ret = QIcon::fromTheme(stock.first()); } } return ret; } QVariant AppPackageKitResource::icon() const { return componentIcon(m_appdata); } QString AppPackageKitResource::license() { const auto license = m_appdata.projectLicense(); return license.isEmpty() ? PackageKitResource::license() : license; } QStringList AppPackageKitResource::mimetypes() const { return m_appdata.provided(AppStream::Provided::KindMimetype).items(); } QStringList AppPackageKitResource::categories() { auto cats = m_appdata.categories(); if (m_appdata.kind() != AppStream::Component::KindAddon) cats.append(QStringLiteral("Application")); return cats; } QString AppPackageKitResource::comment() { const auto summary = m_appdata.summary(); if (!summary.isEmpty()) return summary; return PackageKitResource::comment(); } QString AppPackageKitResource::appstreamId() const { return m_appdata.id(); } QUrl AppPackageKitResource::homepage() { return m_appdata.url(AppStream::Component::UrlKindHomepage); } bool AppPackageKitResource::isTechnical() const { static QString desktop = QString::fromUtf8(qgetenv("XDG_CURRENT_DESKTOP")); const auto desktops = m_appdata.compulsoryForDesktops(); return (!desktops.isEmpty() && !desktops.contains(desktop)) || m_appdata.kind() == AppStream::Component::KindAddon; } void AppPackageKitResource::fetchScreenshots() { QList thumbnails, screenshots; Q_FOREACH (const AppStream::Screenshot &s, m_appdata.screenshots()) { const QUrl thumbnail = AppStreamUtils::imageOfKind(s.images(), AppStream::Image::KindThumbnail); const QUrl plain = AppStreamUtils::imageOfKind(s.images(), AppStream::Image::KindSource); if (plain.isEmpty()) qWarning() << "invalid screenshot for" << name(); screenshots << plain; thumbnails << (thumbnail.isEmpty() ? plain : thumbnail); } Q_EMIT screenshotsFetched(thumbnails, screenshots); } QStringList AppPackageKitResource::allPackageNames() const { return m_appdata.packageNames(); } QList AppPackageKitResource::addonsInformation() { const PackageKitBackend* p = static_cast(parent()); const QVector res = p->extendedBy(m_appdata.id()); QList ret; Q_FOREACH (AppPackageKitResource* r, res) { ret += PackageState(r->appstreamId(), r->name(), r->comment(), r->isInstalled()); } return ret; } QStringList AppPackageKitResource::extends() const { return m_appdata.extends(); } void AppPackageKitResource::fetchChangelog() { emit changelogFetched(AppStreamUtils::changelogToHtml(m_appdata)); } void AppPackageKitResource::invokeApplication() const { auto trans = PackageKit::Daemon::getFiles({installedPackageId()}); connect(trans, &PackageKit::Transaction::files, this, [this](const QString &/*packageID*/, const QStringList &filenames) { const auto allServices = QStandardPaths::locateAll(QStandardPaths::ApplicationsLocation, m_appdata.id()); if (!allServices.isEmpty()) { const auto packageServices = kFilter(allServices, [filenames](const QString &file) { return filenames.contains(file); }); QProcess::startDetached(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/discover/runservice"), {packageServices}); } else { const QStringList exes = m_appdata.provided(AppStream::Provided::KindBinary).items(); const auto packageExecutables = kFilter(allServices, [filenames](const QString &exe) { return filenames.contains(QLatin1Char('/') + exe); }); - if (packageExecutables.isEmpty()) { - qWarning() << "Could not find any executables" << exes << filenames; - return; + if (!packageExecutables.isEmpty()) { + QProcess::startDetached(exes.constFirst()); + } else { + const auto locations = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation); + const auto desktopFiles = kFilter(filenames, [locations](const QString &exe) { + for (const auto &location: locations) { + if (exe.startsWith(location)) + return exe.contains(QLatin1String(".desktop")); + } + return false; + }); + if (!desktopFiles.isEmpty()) { + QProcess::startDetached(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/discover/runservice"), { desktopFiles }); + } } - QProcess::startDetached(exes.constFirst()); + qWarning() << "Could not find any executables" << exes << filenames; } }); }