GrantleeTheme

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

KDE's Doxygen guidelines are available online.