1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 2000 Waldo Bastian <bastian@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only
6*/
7
8#include "kbuildservicegroupfactory_p.h"
9#include "ksycoca.h"
10#include "ksycocadict_p.h"
11#include "sycocadebug.h"
12#include <kservicegroup_p.h>
13
14#include <QDebug>
15#include <QHash>
16#include <QIODevice>
17#include <assert.h>
18
19KBuildServiceGroupFactory::KBuildServiceGroupFactory(KSycoca *db)
20 : KServiceGroupFactory(db)
21{
22 m_baseGroupDict = new KSycocaDict();
23}
24
25KBuildServiceGroupFactory::~KBuildServiceGroupFactory()
26{
27}
28
29KServiceGroup *KBuildServiceGroupFactory::createEntry(const QString &) const
30{
31 // Unused
32 qCWarning(SYCOCA) << "called!";
33 return nullptr;
34}
35
36void KBuildServiceGroupFactory::addNewEntryTo(const QString &menuName, const KService::Ptr &newEntry)
37{
38 KSycocaEntry::Ptr ptr = m_entryDict->value(key: menuName);
39 KServiceGroup::Ptr entry;
40 if (ptr && ptr->isType(t: KST_KServiceGroup)) {
41 entry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
42 }
43
44 if (!entry) {
45 qCWarning(SYCOCA) << "( " << menuName << ", " << newEntry->name() << " ): menu does not exists!";
46 return;
47 }
48 entry->addEntry(entry: KSycocaEntry::Ptr(newEntry));
49}
50
51KServiceGroup::Ptr KBuildServiceGroupFactory::addNew(const QString &menuName, const QString &file, KServiceGroup::Ptr entry, bool isDeleted)
52{
53 KSycocaEntry::Ptr ptr = m_entryDict->value(key: menuName);
54 if (ptr) {
55 qCWarning(SYCOCA) << "( " << menuName << ", " << file << " ): menu already exists!";
56 return KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
57 }
58
59 // Create new group entry
60 if (!entry) {
61 entry = new KServiceGroup(file, menuName);
62 }
63
64 entry->d_func()->m_childCount = -1; // Recalculate
65
66 addEntry(newEntry: KSycocaEntry::Ptr(entry));
67
68 if (menuName != QLatin1String("/")) {
69 // Make sure parent dir exists.
70 QString parent = menuName.left(n: menuName.length() - 1);
71 int i = parent.lastIndexOf(c: QLatin1Char('/'));
72 if (i > 0) {
73 parent = parent.left(n: i + 1);
74 } else {
75 parent = QLatin1Char('/');
76 }
77
78 KServiceGroup::Ptr parentEntry;
79 ptr = m_entryDict->value(key: parent);
80 if (ptr && ptr->isType(t: KST_KServiceGroup)) {
81 parentEntry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
82 }
83 if (!parentEntry) {
84 qCWarning(SYCOCA) << "( " << menuName << ", " << file << " ): parent menu does not exist!";
85 } else {
86 if (!isDeleted && !entry->isDeleted()) {
87 parentEntry->addEntry(entry: KSycocaEntry::Ptr(entry));
88 }
89 }
90 }
91 return entry;
92}
93
94void KBuildServiceGroupFactory::addNewChild(const QString &parent, const KSycocaEntry::Ptr &newEntry)
95{
96 QString name = QLatin1String("#parent#") + parent;
97
98 KServiceGroup::Ptr entry;
99 KSycocaEntry::Ptr ptr = m_entryDict->value(key: name);
100 if (ptr && ptr->isType(t: KST_KServiceGroup)) {
101 entry = KServiceGroup::Ptr(static_cast<KServiceGroup *>(ptr.data()));
102 }
103
104 if (!entry) {
105 entry = new KServiceGroup(name);
106 addEntry(newEntry: KSycocaEntry::Ptr(entry));
107 }
108 if (newEntry) {
109 entry->addEntry(entry: newEntry);
110 }
111}
112
113void KBuildServiceGroupFactory::addEntry(const KSycocaEntry::Ptr &newEntry)
114{
115 KSycocaFactory::addEntry(newEntry);
116
117 KServiceGroup::Ptr serviceGroup(static_cast<KServiceGroup *>(newEntry.data()));
118 serviceGroup->d_func()->m_serviceList.clear();
119
120 if (!serviceGroup->baseGroupName().isEmpty()) {
121 m_baseGroupDict->add(key: serviceGroup->baseGroupName(), payload: newEntry);
122 }
123}
124
125void KBuildServiceGroupFactory::saveHeader(QDataStream &str)
126{
127 KSycocaFactory::saveHeader(str);
128
129 str << qint32(m_baseGroupDictOffset);
130}
131
132void KBuildServiceGroupFactory::save(QDataStream &str)
133{
134 KSycocaFactory::save(str);
135
136 m_baseGroupDictOffset = str.device()->pos();
137 m_baseGroupDict->save(str);
138
139 qint64 endOfFactoryData = str.device()->pos();
140
141 // Update header (pass #3)
142 saveHeader(str);
143
144 // Seek to end.
145 str.device()->seek(pos: endOfFactoryData);
146}
147
148KServiceGroup::Ptr KBuildServiceGroupFactory::findGroupByDesktopPath(const QString &_name, bool deep)
149{
150 assert(sycoca()->isBuilding());
151 Q_UNUSED(deep); // ?
152 // We're building a database - the service type must be in memory
153 KSycocaEntry::Ptr group = m_entryDict->value(key: _name);
154 return KServiceGroup::Ptr(static_cast<KServiceGroup *>(group.data()));
155}
156

source code of kservice/src/sycoca/kbuildservicegroupfactory.cpp