File indexing completed on 2024-12-01 03:42:12

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