KService

kapplicationtrader.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2000 Torben Weis <weis@kde.org>
4 SPDX-FileCopyrightText: 2006-2020 David Faure <faure@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "kapplicationtrader.h"
10
11#include "kmimetypefactory_p.h"
12#include "kservicefactory_p.h"
13#include "ksycoca.h"
14#include "ksycoca_p.h"
15#include "servicesdebug.h"
16
17#include <QMimeDatabase>
18
19#include <KConfigGroup>
20#include <KSharedConfig>
21
22static KService::List mimeTypeSycocaServiceOffers(const QString &mimeType)
23{
26 QString mime = db.mimeTypeForName(mimeType).name();
27 if (mime.isEmpty()) {
28 if (!mimeType.startsWith(QLatin1String("x-scheme-handler/"))) { // don't warn for unknown scheme handler mimetypes
29 qCWarning(SERVICES) << "KApplicationTrader: mimeType" << mimeType << "not found";
30 return lst; // empty
31 }
32 mime = mimeType;
33 }
35 KMimeTypeFactory *factory = KSycocaPrivate::self()->mimeTypeFactory();
36 const int offset = factory->entryOffset(mime);
37 if (!offset) {
38 qCWarning(SERVICES) << "KApplicationTrader: mimeType" << mimeType << "not found";
39 return lst; // empty
40 }
41 const int serviceOffersOffset = factory->serviceOffersOffset(mime);
42 if (serviceOffersOffset > -1) {
43 lst = KSycocaPrivate::self()->serviceFactory()->serviceOffers(offset, serviceOffersOffset);
44 }
45 return lst;
46}
47
48static void applyFilter(KService::List &list, KApplicationTrader::FilterFunc filterFunc, bool mustShowInCurrentDesktop)
49{
50 if (list.isEmpty()) {
51 return;
52 }
53
54 // Find all services matching the constraint
55 // and remove the other ones
56 auto removeFunc = [&](const KService::Ptr &serv) {
57 return (filterFunc && !filterFunc(serv)) || (mustShowInCurrentDesktop && !serv->showInCurrentDesktop());
58 };
59 list.erase(std::remove_if(list.begin(), list.end(), removeFunc), list.end());
60}
61
63{
64 // Get all applications
66 KService::List lst = KSycocaPrivate::self()->serviceFactory()->allServices();
67
68 applyFilter(lst, filterFunc, true); // true = filter out service with NotShowIn=KDE or equivalent
69
70 qCDebug(SERVICES) << "query returning" << lst.count() << "offers";
71 return lst;
72}
73
75{
76 // Get all services of this MIME type.
77 KService::List lst = mimeTypeSycocaServiceOffers(mimeType);
78
79 applyFilter(lst, filterFunc, false); // false = allow NotShowIn=KDE services listed in mimeapps.list
80
81 qCDebug(SERVICES) << "query for mimeType" << mimeType << "returning" << lst.count() << "offers";
82 return lst;
83}
84
86{
87 const KService::List offers = queryByMimeType(mimeType);
88 if (!offers.isEmpty()) {
89 return offers.at(0);
90 }
91 return KService::Ptr();
92}
93
95{
96 if (mimeType.isEmpty() || !(service && service->isValid())) {
97 return;
98 }
99 KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation);
100
101 // Save the default application according to mime-apps-spec 1.0
102 KConfigGroup defaultApp(profile, QStringLiteral("Default Applications"));
103 defaultApp.writeXdgListEntry(mimeType, QStringList(service->storageId()));
104
105 KConfigGroup addedApps(profile, QStringLiteral("Added Associations"));
106 QStringList apps = addedApps.readXdgListEntry(mimeType);
107 apps.removeAll(service->storageId());
108 apps.prepend(service->storageId()); // make it the preferred app
109 addedApps.writeXdgListEntry(mimeType, apps);
110
111 profile->sync();
112
113 // Also make sure the "auto embed" setting for this MIME type is off
114 KSharedConfig::Ptr fileTypesConfig = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
115 fileTypesConfig->group(QStringLiteral("EmbedSettings")).writeEntry(QStringLiteral("embed-") + mimeType, false);
116 fileTypesConfig->sync();
117}
118
120{
121 if (pattern.isEmpty()) {
122 return false;
123 }
124 const bool chk_case = cs == Qt::CaseSensitive;
125
126 auto textIt = text.cbegin();
127 auto patternIt = pattern.cbegin();
128 for (; textIt != text.cend() && patternIt != pattern.cend(); ++textIt) {
129 if ((chk_case && *textIt == *patternIt) || (!chk_case && textIt->toLower() == patternIt->toLower())) {
130 ++patternIt;
131 }
132 }
133 return patternIt == pattern.cend();
134}
QStringList readXdgListEntry(const char *key, const QStringList &aDefault=QStringList()) const
void writeXdgListEntry(const char *key, const QStringList &value, WriteConfigFlags pFlags=Normal)
QExplicitlySharedDataPointer< KService > Ptr
A shared data pointer for KService.
Definition kservice.h:49
static KSharedConfig::Ptr openConfig(const QString &fileName=QString(), OpenFlags mode=FullConfig, QStandardPaths::StandardLocation type=QStandardPaths::GenericConfigLocation)
static KSycoca * self()
Get or create the only instance of KSycoca (read-only)
Definition ksycoca.cpp:357
void ensureCacheValid()
Ensures the ksycoca database is up to date.
Definition ksycoca.cpp:763
KSERVICE_EXPORT void setPreferredService(const QString &mimeType, const KService::Ptr service)
Changes the preferred service for mimeType to service.
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
This method returns a list of services (applications) that match a given filter.
std::function< bool(const KService::Ptr &)> FilterFunc
Filter function, used for filtering results of query and queryByMimeType.
KSERVICE_EXPORT KService::List queryByMimeType(const QString &mimeType, FilterFunc filterFunc={})
This method returns a list of services (applications) which are associated with a given MIME type.
KSERVICE_EXPORT KService::Ptr preferredService(const QString &mimeType)
Returns the preferred service for mimeType.
KSERVICE_EXPORT bool isSubsequence(const QString &pattern, const QString &text, Qt::CaseSensitivity cs=Qt::CaseSensitive)
Returns true if pattern matches a subsequence of the string text.
KCALUTILS_EXPORT QString mimeType()
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const T & at(int i) const const
QList::iterator begin()
int count(const T &value) const const
QList::iterator end()
QList::iterator erase(QList::iterator pos)
bool isEmpty() const const
void prepend(const T &value)
int removeAll(const T &value)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QString::const_iterator cbegin() const const
QString::const_iterator cend() const const
bool isEmpty() const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
CaseSensitivity
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:43:03 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.