File indexing completed on 2023-12-03 07:47:47
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1999 Waldo Bastian <bastian@kde.org> 0004 SPDX-FileCopyrightText: David Faure <faure@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-only 0007 */ 0008 0009 #include "kservicetype.h" 0010 #include "kservice.h" 0011 #include "kservicefactory_p.h" 0012 #include "kservicetype_p.h" 0013 #include "kservicetypefactory_p.h" 0014 #include "kservicetypeprofile.h" 0015 #include "ksycoca.h" 0016 #include "ksycoca_p.h" 0017 #include "servicesdebug.h" 0018 #include <KConfigGroup> 0019 #include <KDesktopFile> 0020 #include <assert.h> 0021 0022 extern int servicesDebugArea(); 0023 0024 template QDataStream &operator>><QString, QVariant>(QDataStream &, QMap<QString, QVariant> &); 0025 template QDataStream &operator<< <QString, QVariant>(QDataStream &, const QMap<QString, QVariant> &); 0026 0027 KServiceType::KServiceType(KDesktopFile *config) 0028 : KSycocaEntry(*new KServiceTypePrivate(config->fileName())) 0029 { 0030 Q_D(KServiceType); 0031 d->init(config); 0032 } 0033 0034 void KServiceTypePrivate::init(KDesktopFile *config) 0035 { 0036 // Q_Q(KServiceType); 0037 0038 KConfigGroup desktopGroup = config->desktopGroup(); 0039 m_strName = desktopGroup.readEntry("X-KDE-ServiceType"); 0040 m_strComment = desktopGroup.readEntry("Comment"); 0041 deleted = desktopGroup.readEntry("Hidden", false); 0042 0043 // We store this as property to preserve BC, we can't change that 0044 // because KSycoca needs to remain BC between KDE 2.x and KDE 3.x 0045 QString sDerived = desktopGroup.readEntry("X-KDE-Derived"); 0046 m_bDerived = !sDerived.isEmpty(); 0047 if (m_bDerived) { 0048 m_mapProps.insert(QStringLiteral("X-KDE-Derived"), sDerived); 0049 } 0050 0051 const QStringList lst = config->groupList(); 0052 0053 for (const auto &groupName : lst) { 0054 if (QLatin1String marker("Property::"); groupName.startsWith(marker)) { 0055 KConfigGroup cg(config, groupName); 0056 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0057 QVariant variant = QVariant::nameToType(cg.readEntry("Type").toLatin1().constData()); 0058 #else 0059 QVariant variant(QMetaType::fromName(cg.readEntry("Type").toLatin1().constData())); 0060 #endif 0061 variant = cg.readEntry("Value", variant); 0062 0063 if (variant.isValid()) { 0064 m_mapProps.insert(groupName.mid(marker.size()), variant); 0065 } 0066 } else if (QLatin1String marker("PropertyDef::"); groupName.startsWith(marker)) { 0067 KConfigGroup cg(config, groupName); 0068 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0069 m_mapPropDefs.insert(groupName.mid(marker.size()), QVariant::nameToType(cg.readEntry("Type").toLatin1().constData())); 0070 #else 0071 m_mapPropDefs.insert(groupName.mid(marker.size()), 0072 static_cast<QVariant::Type>(QMetaType::fromName(cg.readEntry("Type").toLatin1().constData()).id())); 0073 #endif 0074 } 0075 } 0076 } 0077 0078 KServiceType::KServiceType(QDataStream &_str, int offset) 0079 : KSycocaEntry(*new KServiceTypePrivate(_str, offset)) 0080 { 0081 Q_D(KServiceType); 0082 d->load(_str); 0083 } 0084 0085 void KServiceTypePrivate::load(QDataStream &_str) 0086 { 0087 qint8 b; 0088 QString dummy; 0089 _str >> m_strName >> dummy >> m_strComment >> m_mapProps >> m_mapPropDefs >> b >> m_serviceOffersOffset; 0090 m_bDerived = m_mapProps.contains(QLatin1String("X-KDE-Derived")); 0091 } 0092 0093 void KServiceTypePrivate::save(QDataStream &_str) 0094 { 0095 KSycocaEntryPrivate::save(_str); 0096 // !! This data structure should remain binary compatible at all times !! 0097 // You may add new fields at the end. Make sure to update the version 0098 // number in ksycoca.h 0099 _str << m_strName << QString() /*was icon*/ << m_strComment << m_mapProps << m_mapPropDefs << qint8(1) << m_serviceOffersOffset; 0100 } 0101 0102 KServiceType::~KServiceType() 0103 { 0104 } 0105 0106 QString KServiceType::parentServiceType() const 0107 { 0108 const QVariant v = property(QStringLiteral("X-KDE-Derived")); 0109 return v.toString(); 0110 } 0111 0112 bool KServiceType::inherits(const QString &servTypeName) const 0113 { 0114 if (name() == servTypeName) { 0115 return true; 0116 } 0117 QString st = parentServiceType(); 0118 while (!st.isEmpty()) { 0119 KServiceType::Ptr ptr = KServiceType::serviceType(st); 0120 if (!ptr) { 0121 return false; // error 0122 } 0123 if (ptr->name() == servTypeName) { 0124 return true; 0125 } 0126 st = ptr->parentServiceType(); 0127 } 0128 return false; 0129 } 0130 0131 QVariant KServiceTypePrivate::property(const QString &_name) const 0132 { 0133 QVariant v; 0134 0135 if (_name == QLatin1String("Name")) { 0136 v = QVariant(m_strName); 0137 } else if (_name == QLatin1String("Comment")) { 0138 v = QVariant(m_strComment); 0139 } else { 0140 v = m_mapProps.value(_name); 0141 } 0142 0143 return v; 0144 } 0145 0146 QStringList KServiceTypePrivate::propertyNames() const 0147 { 0148 QStringList res = m_mapProps.keys(); 0149 res.append(QStringLiteral("Name")); 0150 res.append(QStringLiteral("Comment")); 0151 return res; 0152 } 0153 0154 QVariant::Type KServiceType::propertyDef(const QString &_name) const 0155 { 0156 Q_D(const KServiceType); 0157 return d->m_mapPropDefs.value(_name, QVariant::Invalid); 0158 } 0159 0160 QStringList KServiceType::propertyDefNames() const 0161 { 0162 Q_D(const KServiceType); 0163 return d->m_mapPropDefs.keys(); 0164 } 0165 0166 KServiceType::Ptr KServiceType::serviceType(const QString &_name) 0167 { 0168 KSycoca::self()->ensureCacheValid(); 0169 return KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(_name); 0170 } 0171 0172 KServiceType::List KServiceType::allServiceTypes() 0173 { 0174 KSycoca::self()->ensureCacheValid(); 0175 return KSycocaPrivate::self()->serviceTypeFactory()->allServiceTypes(); 0176 } 0177 0178 KServiceType::Ptr KServiceType::parentType() 0179 { 0180 Q_D(KServiceType); 0181 if (d->m_parentTypeLoaded) { 0182 return d->parentType; 0183 } 0184 0185 d->m_parentTypeLoaded = true; 0186 0187 const QString parentSt = parentServiceType(); 0188 if (parentSt.isEmpty()) { 0189 return KServiceType::Ptr(); 0190 } 0191 0192 KSycoca::self()->ensureCacheValid(); 0193 d->parentType = KSycocaPrivate::self()->serviceTypeFactory()->findServiceTypeByName(parentSt); 0194 if (!d->parentType) { 0195 qCWarning(SERVICES) << entryPath() << "specifies undefined MIME type/servicetype" << parentSt; 0196 } 0197 return d->parentType; 0198 } 0199 0200 void KServiceType::setServiceOffersOffset(int offset) 0201 { 0202 Q_D(KServiceType); 0203 Q_ASSERT(offset != -1); 0204 d->m_serviceOffersOffset = offset; 0205 } 0206 0207 int KServiceType::serviceOffersOffset() const 0208 { 0209 Q_D(const KServiceType); 0210 return d->serviceOffersOffset(); 0211 } 0212 0213 QString KServiceType::comment() const 0214 { 0215 Q_D(const KServiceType); 0216 return d->comment(); 0217 } 0218 0219 bool KServiceType::isDerived() const 0220 { 0221 Q_D(const KServiceType); 0222 return d->m_bDerived; 0223 } 0224 0225 QMap<QString, QVariant::Type> KServiceType::propertyDefs() const 0226 { 0227 Q_D(const KServiceType); 0228 return d->m_mapPropDefs; 0229 }