File indexing completed on 2024-04-28 15:29:53

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 "kbuildservicegroupfactory_p.h"
0009 #include "ksycoca.h"
0010 #include "ksycocadict_p.h"
0011 #include "ksycocaresourcelist_p.h"
0012 #include "sycocadebug.h"
0013 #include <kservicegroup_p.h>
0014 
0015 #include <QDebug>
0016 #include <QHash>
0017 #include <QIODevice>
0018 #include <assert.h>
0019 
0020 KBuildServiceGroupFactory::KBuildServiceGroupFactory(KSycoca *db)
0021     : KServiceGroupFactory(db)
0022 {
0023     m_baseGroupDict = new KSycocaDict();
0024 }
0025 
0026 KBuildServiceGroupFactory::~KBuildServiceGroupFactory()
0027 {
0028 }
0029 
0030 KServiceGroup *KBuildServiceGroupFactory::createEntry(const QString &) const
0031 {
0032     // Unused
0033     qCWarning(SYCOCA) << "called!";
0034     return nullptr;
0035 }
0036 
0037 void KBuildServiceGroupFactory::addNewEntryTo(const QString &menuName, const KService::Ptr &newEntry)
0038 {
0039     KSycocaEntry::Ptr ptr = m_entryDict->value(menuName);
0040     KServiceGroup::Ptr entry;
0041     if (ptr && ptr->isType(KST_KServiceGroup)) {
0042         entry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
0043     }
0044 
0045     if (!entry) {
0046         qCWarning(SYCOCA) << "( " << menuName << ", " << newEntry->name() << " ): menu does not exists!";
0047         return;
0048     }
0049     entry->addEntry(KSycocaEntry::Ptr(newEntry));
0050 }
0051 
0052 KServiceGroup::Ptr KBuildServiceGroupFactory::addNew(const QString &menuName, const QString &file, KServiceGroup::Ptr entry, bool isDeleted)
0053 {
0054     KSycocaEntry::Ptr ptr = m_entryDict->value(menuName);
0055     if (ptr) {
0056         qCWarning(SYCOCA) << "( " << menuName << ", " << file << " ): menu already exists!";
0057         return KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
0058     }
0059 
0060     // Create new group entry
0061     if (!entry) {
0062         entry = new KServiceGroup(file, menuName);
0063     }
0064 
0065     entry->d_func()->m_childCount = -1; // Recalculate
0066 
0067     addEntry(KSycocaEntry::Ptr(entry));
0068 
0069     if (menuName != QLatin1String("/")) {
0070         // Make sure parent dir exists.
0071         QString parent = menuName.left(menuName.length() - 1);
0072         int i = parent.lastIndexOf(QLatin1Char('/'));
0073         if (i > 0) {
0074             parent = parent.left(i + 1);
0075         } else {
0076             parent = QLatin1Char('/');
0077         }
0078 
0079         KServiceGroup::Ptr parentEntry;
0080         ptr = m_entryDict->value(parent);
0081         if (ptr && ptr->isType(KST_KServiceGroup)) {
0082             parentEntry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
0083         }
0084         if (!parentEntry) {
0085             qCWarning(SYCOCA) << "( " << menuName << ", " << file << " ): parent menu does not exist!";
0086         } else {
0087             if (!isDeleted && !entry->isDeleted()) {
0088                 parentEntry->addEntry(KSycocaEntry::Ptr(entry));
0089             }
0090         }
0091     }
0092     return entry;
0093 }
0094 
0095 void KBuildServiceGroupFactory::addNewChild(const QString &parent, const KSycocaEntry::Ptr &newEntry)
0096 {
0097     QString name = QLatin1String("#parent#") + parent;
0098 
0099     KServiceGroup::Ptr entry;
0100     KSycocaEntry::Ptr ptr = m_entryDict->value(name);
0101     if (ptr && ptr->isType(KST_KServiceGroup)) {
0102         entry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
0103     }
0104 
0105     if (!entry) {
0106         entry = new KServiceGroup(name);
0107         addEntry(KSycocaEntry::Ptr(entry));
0108     }
0109     if (newEntry) {
0110         entry->addEntry(newEntry);
0111     }
0112 }
0113 
0114 void KBuildServiceGroupFactory::addEntry(const KSycocaEntry::Ptr &newEntry)
0115 {
0116     KSycocaFactory::addEntry(newEntry);
0117 
0118     KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(newEntry.data()));
0119     serviceGroup->d_func()->m_serviceList.clear();
0120 
0121     if (!serviceGroup->baseGroupName().isEmpty()) {
0122         m_baseGroupDict->add(serviceGroup->baseGroupName(), newEntry);
0123     }
0124 }
0125 
0126 void KBuildServiceGroupFactory::saveHeader(QDataStream &str)
0127 {
0128     KSycocaFactory::saveHeader(str);
0129 
0130     str << qint32(m_baseGroupDictOffset);
0131 }
0132 
0133 void KBuildServiceGroupFactory::save(QDataStream &str)
0134 {
0135     KSycocaFactory::save(str);
0136 
0137     m_baseGroupDictOffset = str.device()->pos();
0138     m_baseGroupDict->save(str);
0139 
0140     qint64 endOfFactoryData = str.device()->pos();
0141 
0142     // Update header (pass #3)
0143     saveHeader(str);
0144 
0145     // Seek to end.
0146     str.device()->seek(endOfFactoryData);
0147 }
0148 
0149 KServiceGroup::Ptr KBuildServiceGroupFactory::findGroupByDesktopPath(const QString &_name, bool deep)
0150 {
0151     assert(sycoca()->isBuilding());
0152     Q_UNUSED(deep); // ?
0153     // We're building a database - the service type must be in memory
0154     KSycocaEntry::Ptr group = m_entryDict->value(_name);
0155     return KServiceGroup::Ptr(static_cast<KServiceGroup *>(group.data()));
0156 }