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