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 if (!mimeType.startsWith(QLatin1String("x-scheme-handler/"))) { // don't warn for unknown scheme handler mimetypes
39 qCWarning(SERVICES) << "KApplicationTrader: mimeType" << mimeType << "not found";
40 }
41 return lst; // empty
42 }
43 const int serviceOffersOffset = factory->serviceOffersOffset(mime);
44 if (serviceOffersOffset > -1) {
45 lst = KSycocaPrivate::self()->serviceFactory()->serviceOffers(offset, serviceOffersOffset);
46 }
47 return lst;
48}
49
50static void applyFilter(KService::List &list, KApplicationTrader::FilterFunc filterFunc, bool mustShowInCurrentDesktop)
51{
52 if (list.isEmpty()) {
53 return;
54 }
55
56 // Find all services matching the constraint
57 // and remove the other ones
58 auto removeFunc = [&](const KService::Ptr &serv) {
59 return (filterFunc && !filterFunc(serv)) || (mustShowInCurrentDesktop && !serv->showInCurrentDesktop());
60 };
61 list.erase(std::remove_if(list.begin(), list.end(), removeFunc), list.end());
62}
63
65{
66 // Get all applications
68 KService::List lst = KSycocaPrivate::self()->serviceFactory()->allServices();
69
70 applyFilter(lst, filterFunc, true); // true = filter out service with NotShowIn=KDE or equivalent
71
72 qCDebug(SERVICES) << "query returning" << lst.count() << "offers";
73 return lst;
74}
75
77{
78 // Get all services of this MIME type.
79 KService::List lst = mimeTypeSycocaServiceOffers(mimeType);
80
81 applyFilter(lst, filterFunc, false); // false = allow NotShowIn=KDE services listed in mimeapps.list
82
83 qCDebug(SERVICES) << "query for mimeType" << mimeType << "returning" << lst.count() << "offers";
84 return lst;
85}
86
88{
89 const KService::List offers = queryByMimeType(mimeType);
90 if (!offers.isEmpty()) {
91 return offers.at(0);
92 }
93 return KService::Ptr();
94}
95
97{
98 if (mimeType.isEmpty() || !(service && service->isValid())) {
99 return;
100 }
101 KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation);
102
103 // Save the default application according to mime-apps-spec 1.0
104 KConfigGroup defaultApp(profile, QStringLiteral("Default Applications"));
105 defaultApp.writeXdgListEntry(mimeType, QStringList(service->storageId()));
106
107 KConfigGroup addedApps(profile, QStringLiteral("Added Associations"));
108 QStringList apps = addedApps.readXdgListEntry(mimeType);
109 apps.removeAll(service->storageId());
110 apps.prepend(service->storageId()); // make it the preferred app
111 addedApps.writeXdgListEntry(mimeType, apps);
112
113 profile->sync();
114
115 // Also make sure the "auto embed" setting for this MIME type is off
116 KSharedConfig::Ptr fileTypesConfig = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
117 fileTypesConfig->group(QStringLiteral("EmbedSettings")).writeEntry(QStringLiteral("embed-") + mimeType, false);
118 fileTypesConfig->sync();
119}
120
122{
123 if (pattern.isEmpty()) {
124 return false;
125 }
126 const bool chk_case = cs == Qt::CaseSensitive;
127
128 auto textIt = text.cbegin();
129 auto patternIt = pattern.cbegin();
130 for (; textIt != text.cend() && patternIt != pattern.cend(); ++textIt) {
131 if ((chk_case && *textIt == *patternIt) || (!chk_case && textIt->toLower() == patternIt->toLower())) {
132 ++patternIt;
133 }
134 }
135 return patternIt == pattern.cend();
136}
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_reference at(qsizetype i) const const
iterator begin()
qsizetype count() const const
iterator end()
iterator erase(const_iterator begin, const_iterator end)
bool isEmpty() const const
void prepend(parameter_type value)
qsizetype removeAll(const AT &t)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
const_iterator cbegin() const const
const_iterator cend() const const
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseSensitivity
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:40 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.