KService

kmimetypetrader.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2000 Torben Weis <[email protected]>
4  SPDX-FileCopyrightText: 2006 David Faure <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "kmimetypetrader.h"
10 
11 #include "kmimetypefactory_p.h"
12 #include "kservicefactory_p.h"
13 #include "kservicetype.h"
14 #include "kservicetypeprofile.h"
15 #include "kservicetypetrader.h"
16 #include "ksycoca.h"
17 #include "ksycoca_p.h"
18 #include "servicesdebug.h"
19 #include <QMimeDatabase>
20 
21 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 82)
22 
23 class KMimeTypeTraderPrivate
24 {
25 public:
26  KMimeTypeTraderPrivate()
27  {
28  }
29 };
30 
31 class KMimeTypeTraderSingleton
32 {
33 public:
34  KMimeTypeTrader instance;
35 };
36 
37 Q_GLOBAL_STATIC(KMimeTypeTraderSingleton, s_self)
38 
40 {
41  return &s_self()->instance;
42 }
43 
44 KMimeTypeTrader::KMimeTypeTrader()
45  : d(new KMimeTypeTraderPrivate())
46 {
47 }
48 
50 {
51  delete d;
52 }
53 
54 static KServiceOfferList mimeTypeSycocaOffers(const QString &mimeType)
55 {
57 
58  QMimeDatabase db;
59  QString mime = db.mimeTypeForName(mimeType).name();
60  if (mime.isEmpty()) {
61  if (!mimeType.startsWith(QLatin1String("x-scheme-handler/"))) { // don't warn for unknown scheme handler MIME types
62  qCWarning(SERVICES) << "KMimeTypeTrader: MIME type" << mimeType << "not found";
63  return lst; // empty
64  }
65  mime = mimeType;
66  }
68  KMimeTypeFactory *factory = KSycocaPrivate::self()->mimeTypeFactory();
69  const int offset = factory->entryOffset(mime);
70  if (!offset) { // shouldn't happen, now that we know the MIME type exists
71  if (!mimeType.startsWith(QLatin1String("x-scheme-handler/"))) { // don't warn for unknown scheme handler MIME types
72  qCDebug(SERVICES) << "KMimeTypeTrader: no entry offset for" << mimeType;
73  }
74  return lst; // empty
75  }
76 
77  const int serviceOffersOffset = factory->serviceOffersOffset(mime);
78  if (serviceOffersOffset > -1) {
79  lst = KSycocaPrivate::self()->serviceFactory()->offers(offset, serviceOffersOffset);
80  }
81  return lst;
82 }
83 
84 static KService::List mimeTypeSycocaServiceOffers(const QString &mimeType)
85 {
86  KService::List lst;
87  QMimeDatabase db;
88  QString mime = db.mimeTypeForName(mimeType).name();
89  if (mime.isEmpty()) {
90  if (!mimeType.startsWith(QLatin1String("x-scheme-handler/"))) { // don't warn for unknown scheme handler MIME types
91  qCWarning(SERVICES) << "KMimeTypeTrader: MIME type" << mimeType << "not found";
92  return lst; // empty
93  }
94  mime = mimeType;
95  }
97  KMimeTypeFactory *factory = KSycocaPrivate::self()->mimeTypeFactory();
98  const int offset = factory->entryOffset(mime);
99  if (!offset) {
100  qCWarning(SERVICES) << "KMimeTypeTrader: MIME type" << mimeType << "not found";
101  return lst; // empty
102  }
103  const int serviceOffersOffset = factory->serviceOffersOffset(mime);
104  if (serviceOffersOffset > -1) {
105  lst = KSycocaPrivate::self()->serviceFactory()->serviceOffers(offset, serviceOffersOffset);
106  }
107  return lst;
108 }
109 
110 #define CHECK_SERVICETYPE(genericServiceTypePtr) \
111  if (!genericServiceTypePtr) { \
112  qCWarning(SERVICES) << "KMimeTypeTrader: couldn't find service type" << genericServiceType \
113  << "\nPlease ensure that the .desktop file for it is installed; then run kbuildsycoca5."; \
114  return; \
115  }
116 
117 /**
118  * Filter the offers for the requested MIME type for the @p genericServiceType.
119  *
120  * @param list list of offers (key=service, value=initialPreference)
121  * @param genericServiceType the generic service type (e.g. "Application" or "KParts/ReadOnlyPart")
122  */
123 void KMimeTypeTrader::filterMimeTypeOffers(KServiceOfferList &list, const QString &genericServiceType) // static, internal
124 {
125  KServiceType::Ptr genericServiceTypePtr = KServiceType::serviceType(genericServiceType);
126  CHECK_SERVICETYPE(genericServiceTypePtr);
127 
129 
131  while (it.hasNext()) {
132  const KService::Ptr servPtr = it.next().service();
133  // Expand servPtr->hasServiceType( genericServiceTypePtr ) to avoid lookup each time:
134  if (!KSycocaPrivate::self()->serviceFactory()->hasOffer(genericServiceTypePtr, servPtr) //
135  || !servPtr->showInCurrentDesktop()) {
136  it.remove();
137  }
138  }
139 }
140 
141 void KMimeTypeTrader::filterMimeTypeOffers(KService::List &list, const QString &genericServiceType) // static, internal
142 {
143  KServiceType::Ptr genericServiceTypePtr = KServiceType::serviceType(genericServiceType);
144  CHECK_SERVICETYPE(genericServiceTypePtr);
145 
147 
149  while (it.hasNext()) {
150  const KService::Ptr servPtr = it.next();
151  // Expand servPtr->hasServiceType( genericServiceTypePtr ) to avoid lookup each time:
152  if (!KSycocaPrivate::self()->serviceFactory()->hasOffer(genericServiceTypePtr->offset(),
153  genericServiceTypePtr->serviceOffersOffset(),
154  servPtr->offset())
155  || !servPtr->showInCurrentDesktop()) {
156  it.remove();
157  }
158  }
159 }
160 
161 #undef CHECK_SERVICETYPE
162 
163 KService::List KMimeTypeTrader::query(const QString &mimeType, const QString &genericServiceType, const QString &constraint) const
164 {
165  // Get all services of this mime type.
166  KService::List lst = mimeTypeSycocaServiceOffers(mimeType);
167  filterMimeTypeOffers(lst, genericServiceType);
168 
169  KServiceTypeTrader::applyConstraints(lst, constraint);
170 
171  // qCDebug(SERVICES) << "query for MIME type " << mimeType << ", " << genericServiceType
172  // << " : returning " << lst.count() << " offers";
173  return lst;
174 }
175 
176 KService::Ptr KMimeTypeTrader::preferredService(const QString &mimeType, const QString &genericServiceType)
177 {
178  // First, get all offers known to ksycoca.
179  KServiceOfferList offers = mimeTypeSycocaOffers(mimeType);
180 
181  // Assign preferences from the profile to those offers - and filter for genericServiceType
182  Q_ASSERT(!genericServiceType.isEmpty());
183  filterMimeTypeOffers(offers, genericServiceType);
184 
185  auto itOff = offers.constBegin();
186 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 67)
187  // Look for the first one that is allowed as default.
188  // Since the allowed-as-default are first anyway, we only have
189  // to look at the first one to know.
190  if (itOff != offers.constEnd() && (*itOff).allowAsDefault()) {
191 #else
192  if (itOff != offers.constEnd()) {
193 #endif
194  return (*itOff).service();
195  }
196 
197  // qCDebug(SERVICES) << "No offers, or none allowed as default";
198  return KService::Ptr();
199 }
200 
201 #endif
static KSycoca * self()
Get or create the only instance of KSycoca (read-only)
Definition: ksycoca.cpp:379
KService::Ptr preferredService(const QString &mimeType, const QString &genericServiceType=QStringLiteral("Application"))
Returns the preferred service for mimeType and genericServiceType.
void ensureCacheValid()
Ensures the ksycoca database is up to date.
Definition: ksycoca.cpp:826
KService::List query(const QString &mimeType, const QString &genericServiceType=QStringLiteral("Application"), const QString &constraint=QString()) const
This method returns a list of services which are associated with a given MIME type.
~KMimeTypeTrader()
Standard destructor.
KCALUTILS_EXPORT QString mimeType()
QList::const_iterator constBegin() const const
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
bool isEmpty() const const
QExplicitlySharedDataPointer< KService > Ptr
A shared data pointer for KService.
Definition: kservice.h:56
static Ptr serviceType(const QString &_name)
Returns a pointer to the servicetype '_name' or nullptr if the service type is unknown.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QList::const_iterator constEnd() const const
static void applyConstraints(KService::List &lst, const QString &constraint)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Nov 27 2022 03:56:45 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.