File indexing completed on 2024-12-01 09:55:30
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "kservicegroup.h" 0009 #include "kservice.h" 0010 #include "kservicefactory_p.h" 0011 #include "kservicegroup_p.h" 0012 #include "kservicegroupfactory_p.h" 0013 #include "ksycoca_p.h" 0014 #include "servicesdebug.h" 0015 #include <KConfigGroup> 0016 #include <KDesktopFile> 0017 #include <ksycoca.h> 0018 0019 KServiceGroup::KServiceGroup(const QString &name) 0020 : KSycocaEntry(*new KServiceGroupPrivate(name)) 0021 { 0022 } 0023 0024 KServiceGroup::KServiceGroup(const QString &configFile, const QString &_relpath) 0025 : KSycocaEntry(*new KServiceGroupPrivate(_relpath)) 0026 { 0027 Q_D(KServiceGroup); 0028 0029 QString cfg = configFile; 0030 if (cfg.isEmpty()) { 0031 cfg = _relpath + QLatin1String(".directory"); 0032 } 0033 0034 d->load(cfg); 0035 } 0036 0037 void KServiceGroupPrivate::load(const QString &cfg) 0038 { 0039 directoryEntryPath = cfg; 0040 0041 const KDesktopFile desktopFile(cfg); 0042 0043 const KConfigGroup config = desktopFile.desktopGroup(); 0044 0045 m_strCaption = config.readEntry("Name"); 0046 m_strIcon = config.readEntry("Icon"); 0047 m_strComment = config.readEntry("Comment"); 0048 deleted = config.readEntry("Hidden", false); 0049 m_bNoDisplay = desktopFile.noDisplay(); 0050 m_strBaseGroupName = config.readEntry("X-KDE-BaseGroup"); 0051 suppressGenericNames = config.readEntry("X-KDE-SuppressGenericNames", QStringList()); 0052 0053 // Fill in defaults. 0054 if (m_strCaption.isEmpty()) { 0055 m_strCaption = path; 0056 if (m_strCaption.endsWith(QLatin1Char('/'))) { 0057 m_strCaption.chop(1); 0058 } 0059 int i = m_strCaption.lastIndexOf(QLatin1Char('/')); 0060 if (i > 0) { 0061 m_strCaption.remove(0, i + 1); 0062 } 0063 } 0064 if (m_strIcon.isEmpty()) { 0065 m_strIcon = QStringLiteral("folder"); 0066 } 0067 } 0068 0069 KServiceGroup::KServiceGroup(QDataStream &_str, int offset, bool deep) 0070 : KSycocaEntry(*new KServiceGroupPrivate(_str, offset)) 0071 { 0072 Q_D(KServiceGroup); 0073 d->m_bDeep = deep; 0074 d->load(_str); 0075 } 0076 0077 KServiceGroup::~KServiceGroup() 0078 { 0079 } 0080 0081 QString KServiceGroup::relPath() const 0082 { 0083 return entryPath(); 0084 } 0085 0086 QString KServiceGroup::caption() const 0087 { 0088 Q_D(const KServiceGroup); 0089 return d->m_strCaption; 0090 } 0091 0092 QString KServiceGroup::icon() const 0093 { 0094 Q_D(const KServiceGroup); 0095 return d->m_strIcon; 0096 } 0097 0098 QString KServiceGroup::comment() const 0099 { 0100 Q_D(const KServiceGroup); 0101 return d->m_strComment; 0102 } 0103 0104 int KServiceGroup::childCount() const 0105 { 0106 Q_D(const KServiceGroup); 0107 return d->childCount(); 0108 } 0109 0110 int KServiceGroupPrivate::childCount() const 0111 { 0112 if (m_childCount == -1) { 0113 m_childCount = 0; 0114 0115 for (const KSycocaEntry::Ptr &entryPtr : m_serviceList) { 0116 if (entryPtr->isType(KST_KService)) { 0117 KService::Ptr service(static_cast<KService *>(entryPtr.data())); 0118 if (!service->noDisplay()) { 0119 m_childCount++; 0120 } 0121 } else if (entryPtr->isType(KST_KServiceGroup)) { 0122 KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(entryPtr.data())); 0123 m_childCount += serviceGroup->childCount(); 0124 } 0125 } 0126 } 0127 return m_childCount; 0128 } 0129 0130 bool KServiceGroup::showInlineHeader() const 0131 { 0132 Q_D(const KServiceGroup); 0133 return d->m_bShowInlineHeader; 0134 } 0135 0136 bool KServiceGroup::showEmptyMenu() const 0137 { 0138 Q_D(const KServiceGroup); 0139 return d->m_bShowEmptyMenu; 0140 } 0141 0142 bool KServiceGroup::inlineAlias() const 0143 { 0144 Q_D(const KServiceGroup); 0145 return d->m_bInlineAlias; 0146 } 0147 0148 void KServiceGroup::setInlineAlias(bool _b) 0149 { 0150 Q_D(KServiceGroup); 0151 d->m_bInlineAlias = _b; 0152 } 0153 0154 void KServiceGroup::setShowEmptyMenu(bool _b) 0155 { 0156 Q_D(KServiceGroup); 0157 d->m_bShowEmptyMenu = _b; 0158 } 0159 0160 void KServiceGroup::setShowInlineHeader(bool _b) 0161 { 0162 Q_D(KServiceGroup); 0163 d->m_bShowInlineHeader = _b; 0164 } 0165 0166 int KServiceGroup::inlineValue() const 0167 { 0168 Q_D(const KServiceGroup); 0169 return d->m_inlineValue; 0170 } 0171 0172 void KServiceGroup::setInlineValue(int _val) 0173 { 0174 Q_D(KServiceGroup); 0175 d->m_inlineValue = _val; 0176 } 0177 0178 bool KServiceGroup::allowInline() const 0179 { 0180 Q_D(const KServiceGroup); 0181 return d->m_bAllowInline; 0182 } 0183 0184 void KServiceGroup::setAllowInline(bool _b) 0185 { 0186 Q_D(KServiceGroup); 0187 d->m_bAllowInline = _b; 0188 } 0189 0190 bool KServiceGroup::noDisplay() const 0191 { 0192 Q_D(const KServiceGroup); 0193 return d->m_bNoDisplay || d->m_strCaption.startsWith(QLatin1Char('.')); 0194 } 0195 0196 QStringList KServiceGroup::suppressGenericNames() const 0197 { 0198 Q_D(const KServiceGroup); 0199 return d->suppressGenericNames; 0200 } 0201 0202 void KServiceGroupPrivate::load(QDataStream &s) 0203 { 0204 QStringList groupList; 0205 qint8 noDisplay; 0206 qint8 _showEmptyMenu; 0207 qint8 inlineHeader; 0208 qint8 _inlineAlias; 0209 qint8 _allowInline; 0210 s >> m_strCaption >> m_strIcon >> m_strComment >> groupList >> m_strBaseGroupName >> m_childCount >> noDisplay >> suppressGenericNames >> directoryEntryPath 0211 >> sortOrder >> _showEmptyMenu >> inlineHeader >> _inlineAlias >> _allowInline; 0212 0213 m_bNoDisplay = (noDisplay != 0); 0214 m_bShowEmptyMenu = (_showEmptyMenu != 0); 0215 m_bShowInlineHeader = (inlineHeader != 0); 0216 m_bInlineAlias = (_inlineAlias != 0); 0217 m_bAllowInline = (_allowInline != 0); 0218 0219 if (m_bDeep) { 0220 for (const QString &path : std::as_const(groupList)) { 0221 if (path.endsWith(QLatin1Char('/'))) { 0222 KServiceGroup::Ptr serviceGroup; 0223 serviceGroup = KSycocaPrivate::self()->serviceGroupFactory()->findGroupByDesktopPath(path, false); 0224 if (serviceGroup) { 0225 m_serviceList.append(KServiceGroup::SPtr(serviceGroup)); 0226 } 0227 } else { 0228 KService::Ptr service; 0229 service = KSycocaPrivate::self()->serviceFactory()->findServiceByDesktopPath(path); 0230 if (service) { 0231 m_serviceList.append(KServiceGroup::SPtr(service)); 0232 } 0233 } 0234 } 0235 } 0236 } 0237 0238 void KServiceGroup::addEntry(const KSycocaEntry::Ptr &entry) 0239 { 0240 Q_D(KServiceGroup); 0241 d->m_serviceList.append(entry); 0242 } 0243 0244 void KServiceGroupPrivate::save(QDataStream &s) 0245 { 0246 KSycocaEntryPrivate::save(s); 0247 0248 QStringList groupList; 0249 for (const KSycocaEntry::Ptr &p : std::as_const(m_serviceList)) { 0250 if (p->isType(KST_KService)) { 0251 KService::Ptr service(static_cast<KService *>(p.data())); 0252 groupList.append(service->entryPath()); 0253 } else if (p->isType(KST_KServiceGroup)) { 0254 KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(p.data())); 0255 groupList.append(serviceGroup->relPath()); 0256 } else { 0257 // fprintf(stderr, "KServiceGroup: Unexpected object in list!\n"); 0258 } 0259 } 0260 0261 (void)childCount(); 0262 0263 qint8 noDisplay = m_bNoDisplay ? 1 : 0; 0264 qint8 _showEmptyMenu = m_bShowEmptyMenu ? 1 : 0; 0265 qint8 inlineHeader = m_bShowInlineHeader ? 1 : 0; 0266 qint8 _inlineAlias = m_bInlineAlias ? 1 : 0; 0267 qint8 _allowInline = m_bAllowInline ? 1 : 0; 0268 s << m_strCaption << m_strIcon << m_strComment << groupList << m_strBaseGroupName << m_childCount << noDisplay << suppressGenericNames << directoryEntryPath 0269 << sortOrder << _showEmptyMenu << inlineHeader << _inlineAlias << _allowInline; 0270 } 0271 0272 QList<KServiceGroup::Ptr> KServiceGroup::groupEntries(EntriesOptions options) 0273 { 0274 Q_D(KServiceGroup); 0275 bool sort = options & SortEntries || options & AllowSeparators; 0276 QList<KServiceGroup::Ptr> list; 0277 const List tmp = d->entries(this, sort, options & ExcludeNoDisplay, options & AllowSeparators, options & SortByGenericName); 0278 for (const SPtr &ptr : tmp) { 0279 if (ptr->isType(KST_KServiceGroup)) { 0280 KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(ptr.data())); 0281 list.append(serviceGroup); 0282 } else if (ptr->isType(KST_KServiceSeparator)) { 0283 list.append(KServiceGroup::Ptr(static_cast<KServiceGroup *>(new KSycocaEntry()))); 0284 } else if (sort && ptr->isType(KST_KService)) { 0285 break; 0286 } 0287 } 0288 return list; 0289 } 0290 0291 KService::List KServiceGroup::serviceEntries(EntriesOptions options) 0292 { 0293 Q_D(KServiceGroup); 0294 bool sort = options & SortEntries || options & AllowSeparators; 0295 QList<KService::Ptr> list; 0296 const List tmp = d->entries(this, sort, options & ExcludeNoDisplay, options & AllowSeparators, options & SortByGenericName); 0297 bool foundService = false; 0298 for (const SPtr &ptr : tmp) { 0299 if (ptr->isType(KST_KService)) { 0300 list.append(KService::Ptr(static_cast<KService *>(ptr.data()))); 0301 foundService = true; 0302 } else if (ptr->isType(KST_KServiceSeparator) && foundService) { 0303 list.append(KService::Ptr(static_cast<KService *>(new KSycocaEntry()))); 0304 } 0305 } 0306 return list; 0307 } 0308 0309 KServiceGroup::List KServiceGroup::entries(bool sort) 0310 { 0311 Q_D(KServiceGroup); 0312 return d->entries(this, sort, true, false, false); 0313 } 0314 0315 KServiceGroup::List KServiceGroup::entries(bool sort, bool excludeNoDisplay) 0316 { 0317 Q_D(KServiceGroup); 0318 return d->entries(this, sort, excludeNoDisplay, false, false); 0319 } 0320 0321 KServiceGroup::List KServiceGroup::entries(bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName) 0322 { 0323 Q_D(KServiceGroup); 0324 return d->entries(this, sort, excludeNoDisplay, allowSeparators, sortByGenericName); 0325 } 0326 0327 static void addItem(KServiceGroup::List &sorted, const KSycocaEntry::Ptr &p, bool &addSeparator) 0328 { 0329 if (addSeparator && !sorted.isEmpty()) { 0330 sorted.append(KSycocaEntry::Ptr(new KServiceSeparator())); 0331 } 0332 sorted.append(p); 0333 addSeparator = false; 0334 } 0335 0336 KServiceGroup::List KServiceGroupPrivate::entries(KServiceGroup *group, bool sort, bool excludeNoDisplay, bool allowSeparators, bool sortByGenericName) 0337 { 0338 KSycoca::self()->ensureCacheValid(); 0339 0340 // If the entries haven't been loaded yet, we have to reload ourselves 0341 // together with the entries. We can't only load the entries afterwards 0342 // since the offsets could have been changed if the database has changed. 0343 0344 KServiceGroup::Ptr grp; 0345 if (!m_bDeep) { 0346 grp = KSycocaPrivate::self()->serviceGroupFactory()->findGroupByDesktopPath(path, true); 0347 0348 group = grp.data(); 0349 if (nullptr == group) { // No guarantee that we still exist! 0350 return KServiceGroup::List(); 0351 } 0352 } 0353 0354 if (!sort) { 0355 return group->d_func()->m_serviceList; 0356 } 0357 0358 // Sort the list alphabetically, according to locale. 0359 // Groups come first, then services. 0360 0361 // We use a QMap, for sorting using a stored temporary key. 0362 typedef QMap<QByteArray, KServiceGroup::SPtr> SortedContainer; 0363 SortedContainer slist; 0364 SortedContainer glist; 0365 const auto listService = group->d_func()->m_serviceList; 0366 for (const KSycocaEntry::Ptr &p : listService) { 0367 bool noDisplay = p->isType(KST_KServiceGroup) ? static_cast<KServiceGroup *>(p.data())->noDisplay() : static_cast<KService *>(p.data())->noDisplay(); 0368 if (excludeNoDisplay && noDisplay) { 0369 continue; 0370 } 0371 // Choose the right list 0372 SortedContainer &list = p->isType(KST_KServiceGroup) ? glist : slist; 0373 QString name; 0374 if (p->isType(KST_KServiceGroup)) { 0375 name = static_cast<KServiceGroup *>(p.data())->caption(); 0376 } else if (sortByGenericName) { 0377 name = static_cast<KService *>(p.data())->genericName() + QLatin1Char(' ') + p->name(); 0378 } else { 0379 name = p->name() + QLatin1Char(' ') + static_cast<KService *>(p.data())->genericName(); 0380 } 0381 0382 const QByteArray nameStr = name.toLocal8Bit(); 0383 0384 QByteArray key; 0385 // strxfrm() crashes on Solaris and strxfrm is not defined under wince 0386 #if !defined(USE_SOLARIS) && !defined(_WIN32_WCE) 0387 // maybe it'd be better to use wcsxfrm() where available 0388 key.resize(name.length() * 4 + 1); 0389 size_t ln = strxfrm(key.data(), nameStr.constData(), key.size()); 0390 if (ln != size_t(-1)) { 0391 key.resize(ln); 0392 if (int(ln) >= key.size()) { 0393 // didn't fit? 0394 ln = strxfrm(key.data(), nameStr.constData(), key.size()); 0395 if (ln == size_t(-1)) { 0396 key = nameStr; 0397 } 0398 } 0399 } else 0400 #endif 0401 { 0402 key = nameStr; 0403 } 0404 list.insert(key, KServiceGroup::SPtr(p)); 0405 } 0406 0407 if (sortOrder.isEmpty()) { 0408 sortOrder << QStringLiteral(":M"); 0409 sortOrder << QStringLiteral(":F"); 0410 sortOrder << QStringLiteral(":OIH IL[4]"); // just inline header 0411 } 0412 0413 QString rp = path; 0414 if (rp == QLatin1String("/")) { 0415 rp.clear(); 0416 } 0417 0418 // Iterate through the sort spec list. 0419 // If an entry gets mentioned explicitly, we remove it from the sorted list 0420 for (const QString &item : std::as_const(sortOrder)) { 0421 if (item.isEmpty()) { 0422 continue; 0423 } 0424 if (item[0] == QLatin1Char('/')) { 0425 QString groupPath = rp + QStringView(item).mid(1) + QLatin1Char('/'); 0426 // Remove entry from sorted list of services. 0427 for (SortedContainer::iterator it2 = glist.begin(); it2 != glist.end(); ++it2) { 0428 const KServiceGroup::Ptr group(static_cast<KServiceGroup *>(it2.value().data())); 0429 if (group->relPath() == groupPath) { 0430 glist.erase(it2); 0431 break; 0432 } 0433 } 0434 } else if (item[0] != QLatin1Char(':')) { 0435 // Remove entry from sorted list of services. 0436 // TODO: Remove item from sortOrder-list if not found 0437 // TODO: This prevents duplicates 0438 for (SortedContainer::iterator it2 = slist.begin(); it2 != slist.end(); ++it2) { 0439 const KService::Ptr service(static_cast<KService *>(it2.value().data())); 0440 if (service->menuId() == item) { 0441 slist.erase(it2); 0442 break; 0443 } 0444 } 0445 } 0446 } 0447 0448 KServiceGroup::List sorted; 0449 0450 bool needSeparator = false; 0451 // Iterate through the sort spec list. 0452 // Add the entries to the list according to the sort spec. 0453 for (QStringList::ConstIterator it(sortOrder.constBegin()); it != sortOrder.constEnd(); ++it) { 0454 const QString &item = *it; 0455 if (item.isEmpty()) { 0456 continue; 0457 } 0458 if (item[0] == QLatin1Char(':')) { 0459 // Special condition... 0460 if (item == QLatin1String(":S")) { 0461 if (allowSeparators) { 0462 needSeparator = true; 0463 } 0464 } else if (item.contains(QLatin1String(":O"))) { 0465 // todo parse attribute: 0466 QString tmp(item); 0467 tmp.remove(QStringLiteral(":O")); 0468 QStringList optionAttribute = tmp.split(QLatin1Char(' '), Qt::SkipEmptyParts); 0469 if (optionAttribute.isEmpty()) { 0470 optionAttribute.append(tmp); 0471 } 0472 bool showEmptyMenu = false; 0473 bool showInline = false; 0474 bool showInlineHeader = false; 0475 bool showInlineAlias = false; 0476 int inlineValue = -1; 0477 0478 for (QStringList::Iterator it3 = optionAttribute.begin(); it3 != optionAttribute.end(); ++it3) { 0479 parseAttribute(*it3, showEmptyMenu, showInline, showInlineHeader, showInlineAlias, inlineValue); 0480 } 0481 for (SortedContainer::Iterator it2 = glist.begin(); it2 != glist.end(); ++it2) { 0482 KServiceGroup::Ptr group(static_cast<KServiceGroup *>(it2.value().data())); 0483 group->setShowEmptyMenu(showEmptyMenu); 0484 group->setAllowInline(showInline); 0485 group->setShowInlineHeader(showInlineHeader); 0486 group->setInlineAlias(showInlineAlias); 0487 group->setInlineValue(inlineValue); 0488 } 0489 0490 } else if (item == QLatin1String(":M")) { 0491 // Add sorted list of sub-menus 0492 for (SortedContainer::const_iterator it2 = glist.constBegin(); it2 != glist.constEnd(); ++it2) { 0493 addItem(sorted, it2.value(), needSeparator); 0494 } 0495 } else if (item == QLatin1String(":F")) { 0496 // Add sorted list of services 0497 for (SortedContainer::const_iterator it2 = slist.constBegin(); it2 != slist.constEnd(); ++it2) { 0498 addItem(sorted, it2.value(), needSeparator); 0499 } 0500 } else if (item == QLatin1String(":A")) { 0501 // Add sorted lists of services and submenus 0502 SortedContainer::Iterator it_s = slist.begin(); 0503 SortedContainer::Iterator it_g = glist.begin(); 0504 0505 while (true) { 0506 if (it_s == slist.end()) { 0507 if (it_g == glist.end()) { 0508 break; // Done 0509 } 0510 0511 // Insert remaining sub-menu 0512 addItem(sorted, it_g.value(), needSeparator); 0513 it_g++; 0514 } else if (it_g == glist.end()) { 0515 // Insert remaining service 0516 addItem(sorted, it_s.value(), needSeparator); 0517 it_s++; 0518 } else if (it_g.key() < it_s.key()) { 0519 // Insert sub-menu first 0520 addItem(sorted, it_g.value(), needSeparator); 0521 it_g++; 0522 } else { 0523 // Insert service first 0524 addItem(sorted, it_s.value(), needSeparator); 0525 it_s++; 0526 } 0527 } 0528 } 0529 } else if (item[0] == QLatin1Char('/')) { 0530 QString groupPath = rp + QStringView(item).mid(1) + QLatin1Char('/'); 0531 0532 for (KServiceGroup::List::ConstIterator it2(group->d_func()->m_serviceList.constBegin()); it2 != group->d_func()->m_serviceList.constEnd(); ++it2) { 0533 if (!(*it2)->isType(KST_KServiceGroup)) { 0534 continue; 0535 } 0536 KServiceGroup::Ptr group(static_cast<KServiceGroup *>((*it2).data())); 0537 if (group->relPath() == groupPath) { 0538 if (!excludeNoDisplay || !group->noDisplay()) { 0539 ++it; 0540 const QString &nextItem = (it == sortOrder.constEnd()) ? QString() : *it; 0541 0542 if (nextItem.startsWith(QLatin1String(":O"))) { 0543 QString tmp(nextItem); 0544 tmp.remove(QStringLiteral(":O")); 0545 QStringList optionAttribute = tmp.split(QLatin1Char(' '), Qt::SkipEmptyParts); 0546 if (optionAttribute.isEmpty()) { 0547 optionAttribute.append(tmp); 0548 } 0549 bool bShowEmptyMenu = false; 0550 bool bShowInline = false; 0551 bool bShowInlineHeader = false; 0552 bool bShowInlineAlias = false; 0553 int inlineValue = -1; 0554 for (const QString &opt_attr : std::as_const(optionAttribute)) { 0555 parseAttribute(opt_attr, bShowEmptyMenu, bShowInline, bShowInlineHeader, bShowInlineAlias, inlineValue); 0556 group->setShowEmptyMenu(bShowEmptyMenu); 0557 group->setAllowInline(bShowInline); 0558 group->setShowInlineHeader(bShowInlineHeader); 0559 group->setInlineAlias(bShowInlineAlias); 0560 group->setInlineValue(inlineValue); 0561 } 0562 } else { 0563 it--; 0564 } 0565 0566 addItem(sorted, KServiceGroup::SPtr(group), needSeparator); 0567 } 0568 break; 0569 } 0570 } 0571 } else { 0572 for (KServiceGroup::List::ConstIterator it2(group->d_func()->m_serviceList.constBegin()); it2 != group->d_func()->m_serviceList.constEnd(); ++it2) { 0573 if (!(*it2)->isType(KST_KService)) { 0574 continue; 0575 } 0576 const KService::Ptr service(static_cast<KService *>((*it2).data())); 0577 if (service->menuId() == item) { 0578 if (!excludeNoDisplay || !service->noDisplay()) { 0579 addItem(sorted, (*it2), needSeparator); 0580 } 0581 break; 0582 } 0583 } 0584 } 0585 } 0586 0587 return sorted; 0588 } 0589 0590 void KServiceGroupPrivate::parseAttribute(const QString &item, 0591 bool &showEmptyMenu, 0592 bool &showInline, 0593 bool &showInlineHeader, 0594 bool &showInlineAlias, 0595 int &inlineValue) 0596 { 0597 if (item == QLatin1String("ME")) { // menu empty 0598 showEmptyMenu = true; 0599 } else if (item == QLatin1String("NME")) { // not menu empty 0600 showEmptyMenu = false; 0601 } else if (item == QLatin1String("I")) { // inline menu ! 0602 showInline = true; 0603 } else if (item == QLatin1String("NI")) { // not inline menu! 0604 showInline = false; 0605 } else if (item == QLatin1String("IH")) { // inline header! 0606 showInlineHeader = true; 0607 } else if (item == QLatin1String("NIH")) { // not inline header! 0608 showInlineHeader = false; 0609 } else if (item == QLatin1String("IA")) { // inline alias! 0610 showInlineAlias = true; 0611 } else if (item == QLatin1String("NIA")) { // not inline alias! 0612 showInlineAlias = false; 0613 } else if ((item).contains(QLatin1String("IL"))) { // inline limit! 0614 QString tmp(item); 0615 tmp.remove(QStringLiteral("IL[")); 0616 tmp.remove(QLatin1Char(']')); 0617 bool ok; 0618 int _inlineValue = tmp.toInt(&ok); 0619 if (!ok) { // error 0620 _inlineValue = -1; 0621 } 0622 inlineValue = _inlineValue; 0623 } else { 0624 qCDebug(SERVICES) << "This attribute is not supported:" << item; 0625 } 0626 } 0627 0628 void KServiceGroup::setLayoutInfo(const QStringList &layout) 0629 { 0630 Q_D(KServiceGroup); 0631 d->sortOrder = layout; 0632 } 0633 0634 QStringList KServiceGroup::layoutInfo() const 0635 { 0636 Q_D(const KServiceGroup); 0637 return d->sortOrder; 0638 } 0639 0640 KServiceGroup::Ptr KServiceGroup::root() 0641 { 0642 KSycoca::self()->ensureCacheValid(); 0643 return KSycocaPrivate::self()->serviceGroupFactory()->findGroupByDesktopPath(QStringLiteral("/"), true); 0644 } 0645 0646 KServiceGroup::Ptr KServiceGroup::group(const QString &relPath) 0647 { 0648 if (relPath.isEmpty()) { 0649 return root(); 0650 } 0651 KSycoca::self()->ensureCacheValid(); 0652 return KSycocaPrivate::self()->serviceGroupFactory()->findGroupByDesktopPath(relPath, true); 0653 } 0654 0655 KServiceGroup::Ptr KServiceGroup::childGroup(const QString &parent) 0656 { 0657 KSycoca::self()->ensureCacheValid(); 0658 return KSycocaPrivate::self()->serviceGroupFactory()->findGroupByDesktopPath(QLatin1String("#parent#") + parent, true); 0659 } 0660 0661 QString KServiceGroup::baseGroupName() const 0662 { 0663 return d_func()->m_strBaseGroupName; 0664 } 0665 0666 QString KServiceGroup::directoryEntryPath() const 0667 { 0668 Q_D(const KServiceGroup); 0669 return d->directoryEntryPath; 0670 } 0671 0672 class KServiceSeparatorPrivate : public KSycocaEntryPrivate 0673 { 0674 public: 0675 K_SYCOCATYPE(KST_KServiceSeparator, KSycocaEntryPrivate) 0676 0677 KServiceSeparatorPrivate(const QString &name) 0678 : KSycocaEntryPrivate(name) 0679 { 0680 } 0681 0682 QString name() const override; 0683 }; 0684 0685 QString KServiceSeparatorPrivate::name() const 0686 { 0687 return QStringLiteral("separator"); 0688 } 0689 0690 KServiceSeparator::KServiceSeparator() 0691 : KSycocaEntry(*new KServiceSeparatorPrivate(QStringLiteral("separator"))) 0692 { 0693 } 0694 0695 KServiceSeparator::~KServiceSeparator() 0696 { 0697 }