File indexing completed on 2023-09-24 04:11:10
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2000 Torben Weis <weis@kde.org> 0004 SPDX-FileCopyrightText: 2006 David Faure <faure@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "kservicetypetrader.h" 0010 0011 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90) 0012 0013 #include "kservicefactory_p.h" 0014 #include "kservicetype.h" 0015 #include "kservicetypefactory_p.h" 0016 #include "ksycoca.h" 0017 #include "ksycoca_p.h" 0018 #include "ktraderparsetree_p.h" 0019 #include <kservicetypeprofile.h> 0020 0021 #include "servicesdebug.h" 0022 0023 using namespace KTraderParse; 0024 0025 // -------------------------------------------------- 0026 0027 namespace KServiceTypeProfile 0028 { 0029 KServiceOfferList sortServiceTypeOffers(const KServiceOfferList &list, const QString &servicetype); 0030 } 0031 0032 class KServiceTypeTraderSingleton 0033 { 0034 public: 0035 KServiceTypeTrader instance; 0036 }; 0037 0038 Q_GLOBAL_STATIC(KServiceTypeTraderSingleton, s_globalServiceTypeTrader) 0039 0040 KServiceTypeTrader *KServiceTypeTrader::self() 0041 { 0042 return &s_globalServiceTypeTrader()->instance; 0043 } 0044 0045 KServiceTypeTrader::KServiceTypeTrader() 0046 : d(nullptr) 0047 { 0048 } 0049 0050 KServiceTypeTrader::~KServiceTypeTrader() 0051 { 0052 } 0053 0054 // shared with KMimeTypeTrader 0055 void KServiceTypeTrader::applyConstraints(KService::List &lst, const QString &constraint) 0056 { 0057 if (lst.isEmpty() || constraint.isEmpty()) { 0058 return; 0059 } 0060 0061 const ParseTreeBase::Ptr constr = parseConstraints(constraint); // for ownership 0062 const ParseTreeBase *pConstraintTree = constr.data(); // for speed 0063 0064 if (!constr) { // parse error 0065 lst.clear(); 0066 } else { 0067 // Find all services matching the constraint 0068 // and remove the other ones 0069 auto isMatch = [=](const KService::Ptr &service) { 0070 return matchConstraint(pConstraintTree, service, lst) != 1; 0071 }; 0072 0073 lst.erase(std::remove_if(lst.begin(), lst.end(), isMatch), lst.end()); 0074 } 0075 } 0076 0077 KServiceOfferList KServiceTypeTrader::weightedOffers(const QString &serviceType) // static, internal 0078 { 0079 // qDebug() << "KServiceTypeTrader::weightedOffers( " << serviceType << " )"; 0080 0081 KSycoca::self()->ensureCacheValid(); 0082 KServiceType::Ptr servTypePtr = KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(serviceType); 0083 if (!servTypePtr) { 0084 qCWarning(SERVICES) << "KServiceTypeTrader: serviceType" << serviceType << "not found"; 0085 return KServiceOfferList(); 0086 } 0087 if (servTypePtr->serviceOffersOffset() == -1) { // no offers in ksycoca 0088 return KServiceOfferList(); 0089 } 0090 0091 // First, get all offers known to ksycoca. 0092 const KServiceOfferList services = KSycocaPrivate::self()->serviceFactory()->offers(servTypePtr->offset(), servTypePtr->serviceOffersOffset()); 0093 0094 const KServiceOfferList offers = KServiceTypeProfile::sortServiceTypeOffers(services, serviceType); 0095 0096 return offers; 0097 } 0098 0099 KService::List KServiceTypeTrader::defaultOffers(const QString &serviceType, const QString &constraint) const 0100 { 0101 KSycoca::self()->ensureCacheValid(); 0102 KServiceType::Ptr servTypePtr = KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(serviceType); 0103 if (!servTypePtr) { 0104 qCWarning(SERVICES) << "KServiceTypeTrader: serviceType" << serviceType << "not found"; 0105 return KService::List(); 0106 } 0107 if (servTypePtr->serviceOffersOffset() == -1) { 0108 return KService::List(); 0109 } 0110 0111 KService::List lst = KSycocaPrivate::self()->serviceFactory()->serviceOffers(servTypePtr->offset(), servTypePtr->serviceOffersOffset()); 0112 0113 applyConstraints(lst, constraint); 0114 0115 // qDebug() << "query for serviceType " << serviceType << constraint 0116 // << " : returning " << lst.count() << " offers" << endl; 0117 return lst; 0118 } 0119 0120 KService::List KServiceTypeTrader::query(const QString &serviceType, const QString &constraint) const 0121 { 0122 if (!KServiceTypeProfile::hasProfile(serviceType)) { 0123 // Fast path: skip the profile stuff if there's none (to avoid kservice->serviceoffer->kservice) 0124 // The ordering according to initial preferences is done by kbuildsycoca 0125 return defaultOffers(serviceType, constraint); 0126 } 0127 0128 // Get all services of this service type. 0129 const KServiceOfferList offers = weightedOffers(serviceType); 0130 KService::List lst; 0131 lst.reserve(offers.size()); 0132 0133 // Now extract only the services; the weighting was only used for sorting. 0134 std::transform(offers.cbegin(), offers.cend(), std::back_inserter(lst), [](const KServiceOffer &offer) { 0135 return offer.service(); 0136 }); 0137 0138 applyConstraints(lst, constraint); 0139 0140 // qDebug() << "query for serviceType " << serviceType << constraint 0141 // << " : returning " << lst.count() << " offers" << endl; 0142 return lst; 0143 } 0144 0145 KService::Ptr KServiceTypeTrader::preferredService(const QString &serviceType) const 0146 { 0147 const KServiceOfferList offers = weightedOffers(serviceType); 0148 0149 KServiceOfferList::const_iterator itOff = offers.begin(); 0150 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 67) 0151 // Look for the first one that is allowed as default. 0152 // Since the allowed-as-default are first anyway, we only have 0153 // to look at the first one to know. 0154 if (itOff != offers.end() && (*itOff).allowAsDefault()) { 0155 #else 0156 if (itOff != offers.end()) { 0157 #endif 0158 return (*itOff).service(); 0159 } 0160 0161 // qDebug() << "No offers, or none allowed as default"; 0162 return KService::Ptr(); 0163 } 0164 0165 #endif