GrantleeTheme

grantleetheme.cpp
1/*
2 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#include "grantleetheme.h"
8#include "grantleetheme_debug.h"
9#include "grantleetheme_p.h"
10#include "grantleethemeengine.h"
11#include "qtresourcetemplateloader.h"
12#include <config-grantleetheme.h>
13
14#include <KConfig>
15#include <KConfigGroup>
16#include <KLocalizedString>
17
18#include <QDir>
19#include <QSharedPointer>
20
21using namespace GrantleeTheme;
22
23QSharedPointer<GrantleeKi18nLocalizer> GrantleeTheme::ThemePrivate::sLocalizer;
24KTextTemplate::Engine *GrantleeTheme::ThemePrivate::sEngine = nullptr;
25
26ThemePrivate::ThemePrivate()
27 : QSharedData()
28{
29}
30
31ThemePrivate::ThemePrivate(const ThemePrivate &other) = default;
32
33ThemePrivate::~ThemePrivate() = default;
34
35void ThemePrivate::setupEngine()
36{
37 sEngine = new GrantleeTheme::Engine();
38}
39
40void ThemePrivate::setupLoader()
41{
42 // Get the parent dir with themes, we set the theme directory separately
43
44 QStringList templatePaths;
45 for (const QString &absolutePath : std::as_const(absolutePaths)) {
46 QDir dir(absolutePath);
47 dir.cdUp();
48 templatePaths << dir.absolutePath();
49 }
51 loader->setTemplateDirs(templatePaths);
52 loader->setTheme(dirName);
53
54 if (!sEngine) {
55 ThemePrivate::setupEngine();
56 }
57 sEngine->addTemplateLoader(loader);
58}
59KTextTemplate::Context ThemePrivate::createContext(const QVariantHash &data, const QByteArray &applicationDomain)
60{
61 if (!sLocalizer) {
62 sLocalizer.reset(new GrantleeKi18nLocalizer());
63 }
64 sLocalizer->setApplicationDomain(applicationDomain);
65 KTextTemplate::Context ctx(data);
66 ctx.setLocalizer(sLocalizer);
67 return ctx;
68}
69QString ThemePrivate::errorTemplate(const QString &reason, const QString &origTemplateName, const KTextTemplate::Template &failedTemplate)
70{
71 KTextTemplate::Template tpl = sEngine->newTemplate(QStringLiteral("<h1>{{ error }}</h1>\n"
72 "<b>%1:</b> {{ templateName }}<br>\n"
73 "<b>%2:</b> {{ errorMessage }}")
74 .arg(i18n("Template"), i18n("Error message")),
75 QStringLiteral("TemplateError"));
76
77 KTextTemplate::Context ctx = createContext();
78 ctx.insert(QStringLiteral("error"), reason);
79 ctx.insert(QStringLiteral("templateName"), origTemplateName);
80 const QString errorString = failedTemplate ? failedTemplate->errorString() : i18n("(null template)");
81 ctx.insert(QStringLiteral("errorMessage"), errorString);
82 return tpl->render(&ctx);
83}
84
85Theme::Theme()
86 : d(new ThemePrivate)
87{
88}
89
90Theme::Theme(const QString &themePath, const QString &dirName, const QString &defaultDesktopFileName)
91 : d(new ThemePrivate)
92{
93 const QString themeInfoFile = themePath + QLatin1Char('/') + defaultDesktopFileName;
94 KConfig config(themeInfoFile);
95 KConfigGroup group(&config, QStringLiteral("Desktop Entry"));
96 if (group.isValid()) {
97 d->dirName = dirName;
98 d->absolutePaths.append(themePath);
99 d->name = group.readEntry("Name", QString());
100 d->description = group.readEntry("Description", QString());
101 d->themeFileName = group.readEntry("FileName", QString());
102 d->displayExtraVariables = group.readEntry("DisplayExtraVariables", QStringList());
103 }
104}
105
106Theme::Theme(const Theme &other)
107
108 = default;
109
110Theme::~Theme() = default;
111
112bool Theme::operator==(const Theme &other) const
113{
114 return isValid() && other.isValid() && d->absolutePaths == other.d->absolutePaths;
115}
116
117Theme &Theme::operator=(const Theme &other)
118{
119 if (this != &other) {
120 d = other.d;
121 }
122
123 return *this;
124}
125
126bool Theme::isValid() const
127{
128 return !d->themeFileName.isEmpty() && !d->name.isEmpty();
129}
130
131QString Theme::description() const
132{
133 return d->description;
134}
135
136QString Theme::themeFilename() const
137{
138 return d->themeFileName;
139}
140
141QString Theme::name() const
142{
143 return d->name;
144}
145
146QStringList Theme::displayExtraVariables() const
147{
148 return d->displayExtraVariables;
149}
150
151QString Theme::dirName() const
152{
153 return d->dirName;
154}
155
156QString Theme::absolutePath() const
157{
158 if (!d->absolutePaths.isEmpty()) {
159 return d->absolutePaths.at(0); // ####
160 }
161 return {};
162}
163
164QString Theme::author() const
165{
166 return d->author;
167}
168
169QString Theme::authorEmail() const
170{
171 return d->email;
172}
173
174void Theme::addThemePath(const QString &path)
175{
176 d->absolutePaths.append(path);
177}
178
179QString Theme::render(const QString &templateName, const QVariantHash &data, const QByteArray &applicationDomain)
180{
181 if (!d->loader) {
182 d->setupLoader();
183 }
184 Q_ASSERT(d->loader);
185
186 if (!d->loader->canLoadTemplate(templateName)) {
187 qCWarning(GRANTLEETHEME_LOG) << "Cannot load template" << templateName
188 << ", please check your installation. Tried in these dirs:" << d->loader->templateDirs();
189 return {};
190 }
191 KTextTemplate::Template tpl = d->loader->loadByName(templateName, ThemePrivate::sEngine);
192 if (!tpl || tpl->error()) {
193 return d->errorTemplate(i18n("Template parsing error"), templateName, tpl);
194 }
195 KTextTemplate::Context ctx = d->createContext(data, applicationDomain);
196 const QString result = tpl->render(&ctx);
197 if (tpl->error()) {
198 return d->errorTemplate(i18n("Template rendering error"), templateName, tpl);
199 }
200
201 return result;
202}
203
204void Theme::addPluginPath(const QString &path)
205{
206 if (!ThemePrivate::sEngine) {
207 ThemePrivate::setupEngine();
208 }
209
210 QStringList paths = ThemePrivate::sEngine->pluginPaths();
211 if (!paths.contains(path)) {
212 paths.prepend(path);
213 ThemePrivate::sEngine->setPluginPaths(paths);
214 }
215}
The GrantleeKi18nLocalizer class.
The Theme class.
void insert(const QString &name, const QVariant &variant)
QString errorString() const
QString render(Context *c) const
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT QString dir(const QString &fileClass)
void prepend(parameter_type value)
QSharedPointer< T > create(Args &&... args)
QString & append(QChar ch)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:07:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.