1 | /* |
2 | This file is part of the KDE libraries. |
3 | |
4 | SPDX-FileCopyrightText: 2003 Cornelius Schumacher <schumacher@kde.org> |
5 | SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org> |
6 | SPDX-FileCopyrightText: 2003 Zack Rusin <zack@kde.org> |
7 | SPDX-FileCopyrightText: 2006 Michaƫl Larouche <michael.larouche@kdemail.net> |
8 | SPDX-FileCopyrightText: 2008 Allen Winter <winter@kde.org> |
9 | SPDX-FileCopyrightText: 2020 Tomaz Cananbrava <tcanabrava@kde.org> |
10 | |
11 | SPDX-License-Identifier: LGPL-2.0-or-later |
12 | */ |
13 | |
14 | #include "KConfigHeaderGenerator.h" |
15 | |
16 | #include <QDebug> |
17 | #include <QTextStream> |
18 | #include <iostream> |
19 | |
20 | KConfigHeaderGenerator::(const QString &inputFile, const QString &baseDir, const KConfigParameters &cfg, ParseResult &result) |
21 | : KConfigCodeGeneratorBase(inputFile, baseDir, baseDir + cfg.baseName + QLatin1Char('.') + cfg.headerExtension, cfg, result) |
22 | { |
23 | } |
24 | |
25 | void KConfigHeaderGenerator::() |
26 | { |
27 | KConfigCodeGeneratorBase::start(); |
28 | startHeaderGuards(); |
29 | createHeaders(); |
30 | |
31 | beginNamespaces(); |
32 | |
33 | createForwardDeclarations(); |
34 | |
35 | doClassDefinition(); |
36 | |
37 | endNamespaces(); |
38 | endHeaderGuards(); |
39 | } |
40 | |
41 | void KConfigHeaderGenerator::() |
42 | { |
43 | stream() << "class " << cfg().visibility << cfg().className << " : public " << cfg().inherits << '\n'; |
44 | startScope(); |
45 | |
46 | // Add Q_OBJECT macro if the config need signals. |
47 | if (!parseResult.signalList.isEmpty() || cfg().generateProperties) { |
48 | stream() << " Q_OBJECT\n" ; |
49 | } |
50 | stream() << " public:\n" ; |
51 | implementEnums(); |
52 | createConstructor(); |
53 | createDestructor(); |
54 | |
55 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
56 | const QString returnType = (cfg().useEnumTypes && entry->type == QLatin1String("Enum" )) ? enumType(e: entry, globalEnums: cfg().globalEnums) : cppType(t: entry->type); |
57 | |
58 | createSetters(entry); |
59 | createProperties(entry, returnType); |
60 | createImmutableProperty(entry); |
61 | createGetters(entry, returnType); |
62 | createImmutableGetters(entry); |
63 | createDefaultValueMember(entry); |
64 | createItemAcessors(entry, returnType); |
65 | } |
66 | |
67 | createSignals(); |
68 | stream() << " protected:\n" ; |
69 | createSingleton(); |
70 | |
71 | // TODO: Move those to functions too. |
72 | if (parseResult.hasNonModifySignals) { |
73 | stream() << whitespace() << "bool usrSave() override;\n" ; |
74 | } |
75 | |
76 | // Member variables |
77 | if (!cfg().memberVariables.isEmpty() // |
78 | && cfg().memberVariables != QLatin1String("private" ) // |
79 | && cfg().memberVariables != QLatin1String("dpointer" )) { |
80 | stream() << " " << cfg().memberVariables << ":\n" ; |
81 | } |
82 | |
83 | // Class Parameters |
84 | for (const auto ¶meter : std::as_const(t&: parseResult.parameters)) { |
85 | stream() << whitespace() << "" << cppType(t: parameter.type) << " mParam" << parameter.name << ";\n" ; |
86 | } |
87 | |
88 | createNonDPointerHelpers(); |
89 | createDPointer(); |
90 | |
91 | if (cfg().customAddons) { |
92 | stream() << whitespace() << "// Include custom additions\n" ; |
93 | stream() << whitespace() << "#include \"" << cfg().baseName << "_addons." << cfg().headerExtension << "\"\n" ; |
94 | } |
95 | |
96 | endScope(finalizer: ScopeFinalizer::Semicolon); |
97 | } |
98 | |
99 | void KConfigHeaderGenerator::() |
100 | { |
101 | addHeaders(header: cfg().headerIncludes); |
102 | if (cfg().headerIncludes.size()) { |
103 | stream() << '\n'; |
104 | } |
105 | |
106 | if (!cfg().singleton && parseResult.parameters.isEmpty()) { |
107 | addHeaders(header: {QStringLiteral("qglobal.h" )}); |
108 | } |
109 | |
110 | if (cfg().inherits == QLatin1String("KCoreConfigSkeleton" )) { |
111 | addHeaders(header: {QStringLiteral("kcoreconfigskeleton.h" )}); |
112 | } else { |
113 | addHeaders(header: {QStringLiteral("kconfigskeleton.h" )}); |
114 | } |
115 | |
116 | addHeaders(header: {QStringLiteral("QCoreApplication" ), QStringLiteral("QDebug" )}); |
117 | if (!cfg().dpointer && parseResult.hasNonModifySignals) { |
118 | addHeaders(header: {QStringLiteral("QSet" )}); |
119 | } |
120 | stream() << '\n'; |
121 | |
122 | addHeaders(header: parseResult.includes); |
123 | if (parseResult.includes.size()) { |
124 | stream() << '\n'; |
125 | } |
126 | } |
127 | |
128 | void KConfigHeaderGenerator::() |
129 | { |
130 | const bool hasNamespace = !cfg().nameSpace.isEmpty(); |
131 | const QString namespaceName = QString(QString(cfg().nameSpace).replace(before: QLatin1String("::" ), after: QLatin1String("_" ))).toUpper(); |
132 | const QString namespaceStr = hasNamespace ? namespaceName + QLatin1Char('_') : QString{}; |
133 | const QString defineName = namespaceStr + cfg().className.toUpper() + QStringLiteral("_H" ); |
134 | |
135 | stream() << "#ifndef " << defineName << '\n'; |
136 | stream() << "#define " << defineName << '\n'; |
137 | stream() << '\n'; |
138 | } |
139 | |
140 | void KConfigHeaderGenerator::() |
141 | { |
142 | stream() << '\n'; |
143 | stream() << "#endif" ; |
144 | stream() << '\n'; |
145 | // HACK: Original files ended with two last newlines, add them. |
146 | stream() << '\n'; |
147 | } |
148 | |
149 | void KConfigHeaderGenerator::(const CfgEntry *entry, const CfgEntry::Choices &choices) |
150 | { |
151 | const QList<CfgEntry::Choice> chlist = choices.choices; |
152 | |
153 | if (chlist.isEmpty()) { |
154 | return; |
155 | } |
156 | |
157 | QStringList values; |
158 | for (const auto &choice : std::as_const(t: chlist)) { |
159 | values.append(t: choices.prefix + choice.name); |
160 | } |
161 | |
162 | if (choices.name().isEmpty()) { |
163 | if (cfg().globalEnums) { |
164 | stream() << whitespace() << "enum " << enumName(n: entry->name, c: entry->choices) << " { " << values.join(QStringLiteral(", " )) << " };\n" ; |
165 | if (cfg().generateProperties) { |
166 | stream() << whitespace() << "Q_ENUM(" << enumName(n: entry->name, c: entry->choices) << ")\n" ; |
167 | } |
168 | } else { |
169 | // Create an automatically named enum |
170 | stream() << whitespace() << "class " << enumName(n: entry->name, c: entry->choices) << '\n'; |
171 | stream() << whitespace() << "{\n" ; |
172 | stream() << whitespace() << " public:\n" ; |
173 | stream() << whitespace() << " enum type { " << values.join(QStringLiteral(", " )) << ", COUNT };\n" ; |
174 | stream() << whitespace() << "};\n" ; |
175 | } |
176 | } else if (!choices.external()) { |
177 | // Create a named enum |
178 | stream() << whitespace() << "enum " << enumName(n: entry->name, c: entry->choices) << " { " << values.join(QStringLiteral(", " )) << " };\n" ; |
179 | } |
180 | } |
181 | |
182 | void KConfigHeaderGenerator::(const CfgEntry *entry, const QStringList &values) |
183 | { |
184 | if (values.isEmpty()) { |
185 | return; |
186 | } |
187 | |
188 | if (cfg().globalEnums) { |
189 | // ### FIXME!! |
190 | // make the following string table an index-based string search! |
191 | // ### |
192 | stream() << whitespace() << "enum " << enumName(n: entry->param) << " { " << values.join(QStringLiteral(", " )) << " };\n" ; |
193 | stream() << whitespace() << "static const char* const " << enumName(n: entry->param) << "ToString[];\n" ; |
194 | } else { |
195 | stream() << whitespace() << "class " << enumName(n: entry->param) << '\n'; |
196 | stream() << whitespace() << "{\n" ; |
197 | stream() << whitespace() << " public:\n" ; |
198 | stream() << whitespace() << " enum type { " << values.join(QStringLiteral(", " )) << ", COUNT };\n" ; |
199 | stream() << whitespace() << " static const char* const enumToString[];\n" ; |
200 | stream() << whitespace() << "};\n" ; |
201 | } |
202 | } |
203 | |
204 | void KConfigHeaderGenerator::() |
205 | { |
206 | if (!parseResult.entries.size()) { |
207 | return; |
208 | } |
209 | |
210 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
211 | const CfgEntry::Choices &choices = entry->choices; |
212 | const QStringList values = entry->paramValues; |
213 | |
214 | implementChoiceEnums(entry, choices); |
215 | implementValueEnums(entry, values); |
216 | } |
217 | stream() << '\n'; |
218 | } |
219 | |
220 | void KConfigHeaderGenerator::() |
221 | { |
222 | // Signal definition. |
223 | if (parseResult.signalList.isEmpty()) { |
224 | return; |
225 | } |
226 | |
227 | stream() << "\n enum {\n" ; |
228 | |
229 | // HACK: Use C-Style for add a comma in all but the last element, |
230 | // just to make the source generated code equal to the old one. |
231 | // When we are sure, revert this to a range-based-for and just add |
232 | // a last comma, as it's valid c++. |
233 | for (int i = 0, end = parseResult.signalList.size(); i < end; i++) { |
234 | auto signal = parseResult.signalList.at(i); |
235 | stream() << whitespace() << " " << signalEnumName(signalName: signal.name) << " = " << (i + 1); |
236 | if (i != end - 1) { |
237 | stream() << ",\n" ; |
238 | } |
239 | } |
240 | stream() << '\n'; |
241 | stream() << whitespace() << "};\n\n" ; |
242 | |
243 | stream() << " Q_SIGNALS:" ; |
244 | for (const Signal &signal : std::as_const(t&: parseResult.signalList)) { |
245 | stream() << '\n'; |
246 | if (!signal.label.isEmpty()) { |
247 | stream() << whitespace() << "/**\n" ; |
248 | stream() << whitespace() << " " << signal.label << '\n'; |
249 | stream() << whitespace() << "*/\n" ; |
250 | } |
251 | stream() << whitespace() << "void " << signal.name << "(" ; |
252 | |
253 | auto it = signal.arguments.cbegin(); |
254 | const auto itEnd = signal.arguments.cend(); |
255 | while (it != itEnd) { |
256 | Param argument = *it; |
257 | QString type = param(t: argument.type); |
258 | if (cfg().useEnumTypes && argument.type == QLatin1String("Enum" )) { |
259 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
260 | if (entry->name == argument.name) { |
261 | type = enumType(e: entry, globalEnums: cfg().globalEnums); |
262 | break; |
263 | } |
264 | } |
265 | } |
266 | stream() << type << " " << argument.name; |
267 | if (++it != itEnd) { |
268 | stream() << ", " ; |
269 | } |
270 | } |
271 | stream() << ");\n" ; |
272 | } |
273 | stream() << '\n'; |
274 | |
275 | stream() << " private:\n" ; |
276 | stream() << whitespace() << "void itemChanged(quint64 signalFlag);\n" ; |
277 | stream() << '\n'; |
278 | } |
279 | |
280 | void KConfigHeaderGenerator::() |
281 | { |
282 | if (!cfg().dpointer) { |
283 | return; |
284 | } |
285 | |
286 | // use a private class for both member variables and items |
287 | stream() << " private:\n" ; |
288 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
289 | if (cfg().allDefaultGetters || cfg().defaultGetters.contains(str: entry->name)) { |
290 | stream() << whitespace() << "" ; |
291 | if (cfg().staticAccessors) { |
292 | stream() << "static " ; |
293 | } |
294 | stream() << cppType(t: entry->type) << " " << getDefaultFunction(n: entry->name) << "_helper(" ; |
295 | if (!entry->param.isEmpty()) { |
296 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
297 | } |
298 | stream() << ")" << Const() << ";\n" ; |
299 | } |
300 | } |
301 | stream() << whitespace() << "" << cfg().className << "Private *d;\n" ; |
302 | } |
303 | |
304 | void KConfigHeaderGenerator::() |
305 | { |
306 | if (cfg().singleton) { |
307 | stream() << whitespace() << "static " << cfg().className << " *self();\n" ; |
308 | if (parseResult.cfgFileNameArg) { |
309 | stream() << whitespace() << "static void instance(const QString& cfgfilename);\n" ; |
310 | stream() << whitespace() << "static void instance(KSharedConfig::Ptr config);\n" ; |
311 | } |
312 | return; |
313 | } |
314 | |
315 | stream() << whitespace() << "" << cfg().className << "(" ; |
316 | if (parseResult.cfgFileNameArg) { |
317 | if (cfg().forceStringFilename) { |
318 | stream() << " const QString &cfgfilename" << (parseResult.parameters.isEmpty() ? " = QString()" : ", " ); |
319 | } else if (parseResult.cfgStateConfig) { |
320 | stream() << " KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ? " = KSharedConfig::openStateConfig()" : ", " ); |
321 | } else { |
322 | stream() << " KSharedConfig::Ptr config" << (parseResult.parameters.isEmpty() ? " = KSharedConfig::openConfig()" : ", " ); |
323 | } |
324 | } |
325 | if (cfg().forceStringFilename && parseResult.cfgStateConfig) { |
326 | std::cerr << "One can not use ForceStringFilename and use the stateConfig attribute, consider " |
327 | "removing the ForceStringFilename kcfgc option if you want to use state data" |
328 | << std::endl; |
329 | } |
330 | |
331 | bool first = true; |
332 | for (const auto ¶meter : std::as_const(t&: parseResult.parameters)) { |
333 | if (first) { |
334 | first = false; |
335 | } else { |
336 | stream() << "," ; |
337 | } |
338 | |
339 | stream() << " " << param(t: parameter.type) << " " << parameter.name; |
340 | } |
341 | |
342 | if (cfg().parentInConstructor) { |
343 | if (parseResult.cfgFileNameArg || !parseResult.parameters.isEmpty()) { |
344 | stream() << "," ; |
345 | } |
346 | stream() << " QObject *parent = nullptr" ; |
347 | } |
348 | stream() << " );\n" ; |
349 | } |
350 | |
351 | void KConfigHeaderGenerator::() |
352 | { |
353 | stream() << whitespace() << "~" << cfg().className << "() override;\n\n" ; |
354 | } |
355 | |
356 | void KConfigHeaderGenerator::() |
357 | { |
358 | // Private class declaration |
359 | if (cfg().dpointer) { |
360 | stream() << "class " << cfg().className << "Private;\n\n" ; |
361 | } |
362 | } |
363 | |
364 | void KConfigHeaderGenerator::(const CfgEntry *entry, const QString &returnType) |
365 | { |
366 | if (!cfg().generateProperties) { |
367 | return; |
368 | } |
369 | stream() << whitespace() << "Q_PROPERTY(" << returnType << ' ' << getFunction(n: entry->name); |
370 | stream() << " READ " << getFunction(n: entry->name); |
371 | |
372 | if (cfg().allMutators || cfg().mutators.contains(str: entry->name)) { |
373 | const QString signal = changeSignalName(n: entry->name); |
374 | stream() << " WRITE " << setFunction(n: entry->name); |
375 | stream() << " NOTIFY " << signal; |
376 | |
377 | // If we have the modified signal, we'll also need |
378 | // the changed signal as well |
379 | Signal s; |
380 | s.name = signal; |
381 | s.modify = true; |
382 | parseResult.signalList.append(t: s); |
383 | } else { |
384 | stream() << " CONSTANT" ; |
385 | } |
386 | stream() << ")\n" ; |
387 | } |
388 | |
389 | void KConfigHeaderGenerator::(const CfgEntry *entry) |
390 | { |
391 | if (!cfg().generateProperties) { |
392 | return; |
393 | } |
394 | stream() << whitespace(); |
395 | stream() << "Q_PROPERTY(bool " << immutableFunction(n: entry->name); |
396 | stream() << " READ " << immutableFunction(n: entry->name); |
397 | stream() << " CONSTANT)\n" ; |
398 | } |
399 | |
400 | void KConfigHeaderGenerator::(const CfgEntry *entry) |
401 | { |
402 | // Manipulator |
403 | if (!cfg().allMutators && !cfg().mutators.contains(str: entry->name)) { |
404 | return; |
405 | } |
406 | |
407 | stream() << whitespace() << "/**\n" ; |
408 | stream() << whitespace() << " Set " << entry->label << '\n'; |
409 | stream() << whitespace() << "*/\n" ; |
410 | |
411 | if (cfg().staticAccessors) { |
412 | stream() << whitespace() << "static\n" ; |
413 | } |
414 | |
415 | stream() << whitespace() << "void " << setFunction(n: entry->name) << "( " ; |
416 | if (!entry->param.isEmpty()) { |
417 | stream() << cppType(t: entry->paramType) << " i, " ; |
418 | } |
419 | |
420 | stream() << (cfg().useEnumTypes && entry->type == QLatin1String("Enum" ) ? enumType(e: entry, globalEnums: cfg().globalEnums) : param(t: entry->type)); |
421 | |
422 | stream() << " v )" ; |
423 | |
424 | // function body inline only if not using dpointer |
425 | // for BC mode |
426 | if (!cfg().dpointer) { |
427 | stream() << '\n'; |
428 | startScope(); |
429 | memberMutatorBody(e: entry); |
430 | endScope(); |
431 | stream() << '\n'; |
432 | } else { |
433 | stream() << ";\n\n" ; |
434 | } |
435 | } |
436 | |
437 | void KConfigHeaderGenerator::(const CfgEntry *entry, const QString &returnType) |
438 | { |
439 | // Accessor |
440 | stream() << whitespace() << "/**\n" ; |
441 | stream() << whitespace() << " Get " << entry->label << '\n'; |
442 | stream() << whitespace() << "*/\n" ; |
443 | if (cfg().staticAccessors) { |
444 | stream() << whitespace() << "static\n" ; |
445 | } |
446 | stream() << whitespace() << "" ; |
447 | stream() << returnType; |
448 | stream() << " " << getFunction(n: entry->name) << "(" ; |
449 | if (!entry->param.isEmpty()) { |
450 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
451 | } |
452 | stream() << ")" << Const(); |
453 | |
454 | // function body inline only if not using dpointer |
455 | // for BC mode |
456 | if (!cfg().dpointer) { |
457 | stream() << '\n'; |
458 | startScope(); |
459 | stream() << whitespace() << memberAccessorBody(e: entry, globalEnums: cfg().globalEnums); |
460 | endScope(); |
461 | stream() << '\n'; |
462 | } else { |
463 | stream() << ";\n\n" ; |
464 | } |
465 | } |
466 | |
467 | void KConfigHeaderGenerator::(const CfgEntry *entry) |
468 | { |
469 | stream() << whitespace() << "/**\n" ; |
470 | stream() << whitespace() << " Is " << entry->label << " Immutable\n" ; |
471 | stream() << whitespace() << "*/\n" ; |
472 | // Immutable |
473 | if (cfg().staticAccessors) { |
474 | stream() << whitespace() << "static\n" ; |
475 | } |
476 | stream() << whitespace() << "" ; |
477 | stream() << "bool " << immutableFunction(n: entry->name) << "(" ; |
478 | if (!entry->param.isEmpty()) { |
479 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
480 | } |
481 | stream() << ")" << Const(); |
482 | // function body inline only if not using dpointer |
483 | // for BC mode |
484 | if (!cfg().dpointer) { |
485 | stream() << '\n'; |
486 | startScope(); |
487 | memberImmutableBody(e: entry, globalEnums: cfg().globalEnums); |
488 | endScope(); |
489 | stream() << '\n'; |
490 | } else { |
491 | stream() << ";\n\n" ; |
492 | } |
493 | } |
494 | |
495 | void KConfigHeaderGenerator::(const CfgEntry *entry, const QString &returnType) |
496 | { |
497 | Q_UNUSED(returnType) |
498 | |
499 | // Item accessor |
500 | if (!cfg().itemAccessors) { |
501 | return; |
502 | } |
503 | |
504 | const QString declType = entry->signalList.isEmpty() ? QStringLiteral("Item" ) + itemType(type: entry->type) : QStringLiteral("KConfigCompilerSignallingItem" ); |
505 | |
506 | stream() << whitespace() << "/**\n" ; |
507 | stream() << whitespace() << " Get Item object corresponding to " << entry->name << "()" << '\n'; |
508 | stream() << whitespace() << "*/\n" ; |
509 | stream() << whitespace() << declType << " *" << getFunction(n: entry->name) << "Item(" ; |
510 | if (!entry->param.isEmpty()) { |
511 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
512 | } |
513 | stream() << ")" ; |
514 | if (!cfg().dpointer) { |
515 | stream() << '\n'; |
516 | startScope(); |
517 | stream() << whitespace() << itemAccessorBody(e: entry, cfg: cfg()); |
518 | endScope(); |
519 | } else { |
520 | stream() << ";\n" ; |
521 | } |
522 | |
523 | stream() << '\n'; |
524 | } |
525 | |
526 | void KConfigHeaderGenerator::(const CfgEntry *entry) |
527 | { |
528 | // Default value Accessor |
529 | if (!((cfg().allDefaultGetters || cfg().defaultGetters.contains(str: entry->name)) && !entry->defaultValue.isEmpty())) { |
530 | return; |
531 | } |
532 | stream() << whitespace() << "/**\n" ; |
533 | stream() << whitespace() << " Get " << entry->label << " default value\n" ; |
534 | stream() << whitespace() << "*/\n" ; |
535 | if (cfg().staticAccessors) { |
536 | stream() << whitespace() << "static\n" ; |
537 | } |
538 | stream() << whitespace() << "" ; |
539 | if (cfg().useEnumTypes && entry->type == QLatin1String("Enum" )) { |
540 | stream() << enumType(e: entry, globalEnums: cfg().globalEnums); |
541 | } else { |
542 | stream() << cppType(t: entry->type); |
543 | } |
544 | stream() << " " << getDefaultFunction(n: entry->name) << "(" ; |
545 | if (!entry->param.isEmpty()) { |
546 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
547 | } |
548 | stream() << ")" << Const() << '\n'; |
549 | stream() << whitespace() << "{\n" ; |
550 | stream() << whitespace() << " return " ; |
551 | if (cfg().useEnumTypes && entry->type == QLatin1String("Enum" )) { |
552 | stream() << "static_cast<" << enumType(e: entry, globalEnums: cfg().globalEnums) << ">(" ; |
553 | } |
554 | stream() << getDefaultFunction(n: entry->name) << "_helper(" ; |
555 | if (!entry->param.isEmpty()) { |
556 | stream() << " i " ; |
557 | } |
558 | stream() << ")" ; |
559 | if (cfg().useEnumTypes && entry->type == QLatin1String("Enum" )) { |
560 | stream() << ")" ; |
561 | } |
562 | stream() << ";\n" ; |
563 | stream() << whitespace() << "}\n" ; |
564 | stream() << '\n'; |
565 | } |
566 | |
567 | void KConfigHeaderGenerator::() |
568 | { |
569 | // Private constructor for singleton |
570 | if (!cfg().singleton) { |
571 | return; |
572 | } |
573 | |
574 | stream() << whitespace() << "" << cfg().className << "(" ; |
575 | if (parseResult.cfgFileNameArg) { |
576 | stream() << "KSharedConfig::Ptr config" ; |
577 | } |
578 | if (cfg().parentInConstructor) { |
579 | if (parseResult.cfgFileNameArg) { |
580 | stream() << ", " ; |
581 | } |
582 | stream() << "QObject *parent = nullptr" ; |
583 | } |
584 | stream() << ");\n" ; |
585 | stream() << whitespace() << "friend class " << cfg().className << "Helper;\n\n" ; |
586 | } |
587 | |
588 | void KConfigHeaderGenerator::() |
589 | { |
590 | if (cfg().memberVariables == QLatin1String("dpointer" )) { |
591 | return; |
592 | } |
593 | |
594 | QString group; |
595 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
596 | if (entry->group != group) { |
597 | group = entry->group; |
598 | stream() << '\n'; |
599 | stream() << whitespace() << "// " << group << '\n'; |
600 | } |
601 | stream() << whitespace() << "" << cppType(t: entry->type) << " " << varName(n: entry->name, cfg: cfg()); |
602 | if (!entry->param.isEmpty()) { |
603 | stream() << QStringLiteral("[%1]" ).arg(a: entry->paramMax + 1); |
604 | } |
605 | stream() << ";\n" ; |
606 | |
607 | if (cfg().allDefaultGetters || cfg().defaultGetters.contains(str: entry->name)) { |
608 | stream() << whitespace() << "" ; |
609 | if (cfg().staticAccessors) { |
610 | stream() << "static " ; |
611 | } |
612 | stream() << cppType(t: entry->type) << " " << getDefaultFunction(n: entry->name) << "_helper(" ; |
613 | if (!entry->param.isEmpty()) { |
614 | stream() << " " << cppType(t: entry->paramType) << " i " ; |
615 | } |
616 | stream() << ")" << Const() << ";\n" ; |
617 | } |
618 | } |
619 | |
620 | stream() << "\n private:\n" ; |
621 | if (cfg().itemAccessors) { |
622 | for (const auto *entry : std::as_const(t&: parseResult.entries)) { |
623 | const QString declType = |
624 | entry->signalList.isEmpty() ? QStringLiteral("Item" ) + itemType(type: entry->type) : QStringLiteral("KConfigCompilerSignallingItem" ); |
625 | stream() << whitespace() << declType << " *" << itemVar(e: entry, cfg: cfg()); |
626 | if (!entry->param.isEmpty()) { |
627 | stream() << QStringLiteral("[%1]" ).arg(a: entry->paramMax + 1); |
628 | } |
629 | stream() << ";\n" ; |
630 | } |
631 | } |
632 | |
633 | if (parseResult.hasNonModifySignals) { |
634 | stream() << whitespace() << "QSet<quint64> " << varName(QStringLiteral("settingsChanged" ), cfg: cfg()) << ";\n" ; |
635 | } |
636 | } |
637 | |