GrantleeTheme

grantleetheme.cpp
1 /*
2  Copyright (c) 2013-2020 Laurent Montel <[email protected]>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include "grantleetheme.h"
20 #include "grantleetheme_p.h"
21 #include "grantleetheme_debug.h"
22 #include "grantleethemeengine.h"
23 #include <config-grantleetheme.h>
24 #include "qtresourcetemplateloader.h"
25 
26 #include <KConfig>
27 #include <KConfigGroup>
28 #include <KLocalizedString>
29 
30 #include <QDir>
31 #include <QSharedPointer>
32 
33 using namespace GrantleeTheme;
34 
35 QSharedPointer<GrantleeKi18nLocalizer> GrantleeTheme::ThemePrivate::sLocalizer;
36 Grantlee::Engine *GrantleeTheme::ThemePrivate::sEngine = nullptr;
37 
38 ThemePrivate::ThemePrivate()
39  : QSharedData()
40 {
41 }
42 
43 ThemePrivate::ThemePrivate(const ThemePrivate &other)
44  : QSharedData(other)
45  , displayExtraVariables(other.displayExtraVariables)
46  , themeFileName(other.themeFileName)
47  , description(other.description)
48  , name(other.name)
49  , dirName(other.dirName)
50  , absolutePaths(other.absolutePaths)
51  , author(other.author)
52  , email(other.email)
53  , loader(other.loader)
54 {
55 }
56 
57 ThemePrivate::~ThemePrivate()
58 {
59 }
60 
61 void ThemePrivate::setupEngine()
62 {
63  sEngine = new GrantleeTheme::Engine();
64 }
65 
66 void ThemePrivate::setupLoader()
67 {
68  // Get the parent dir with themes, we set the theme directory separately
69 
70  QStringList templatePaths;
71  for (const QString &absolutePath : qAsConst(absolutePaths)) {
72  QDir dir(absolutePath);
73  dir.cdUp();
74  templatePaths << dir.absolutePath();
75  }
76 
78  loader->setTemplateDirs(templatePaths);
79  loader->setTheme(dirName);
80 
81  if (!sEngine) {
82  ThemePrivate::setupEngine();
83  }
84  sEngine->addTemplateLoader(loader);
85 }
86 
87 Grantlee::Context ThemePrivate::createContext(const QVariantHash &data, const QByteArray &applicationDomain)
88 {
89  if (!sLocalizer) {
90  sLocalizer.reset(new GrantleeKi18nLocalizer());
91  }
92  sLocalizer->setApplicationDomain(applicationDomain);
93  Grantlee::Context ctx(data);
94  ctx.setLocalizer(sLocalizer);
95  return ctx;
96 }
97 
98 QString ThemePrivate::errorTemplate(const QString &reason, const QString &origTemplateName, const Grantlee::Template &failedTemplate)
99 {
100  Grantlee::Template tpl = sEngine->newTemplate(
101  QStringLiteral("<h1>{{ error }}</h1>\n"
102  "<b>%1:</b> {{ templateName }}<br>\n"
103  "<b>%2:</b> {{ errorMessage }}")
104  .arg(i18n("Template"), i18n("Error message")),
105  QStringLiteral("TemplateError"));
106 
107  Grantlee::Context ctx = createContext();
108  ctx.insert(QStringLiteral("error"), reason);
109  ctx.insert(QStringLiteral("templateName"), origTemplateName);
110  const QString errorString = failedTemplate
111  ? failedTemplate->errorString()
112  : i18n("(null template)");
113  ctx.insert(QStringLiteral("errorMessage"), errorString);
114  return tpl->render(&ctx);
115 }
116 
117 Theme::Theme()
118  : d(new ThemePrivate)
119 {
120 }
121 
122 Theme::Theme(const QString &themePath, const QString &dirName, const QString &defaultDesktopFileName)
123  : d(new ThemePrivate)
124 {
125  const QString themeInfoFile = themePath + QLatin1Char('/') + defaultDesktopFileName;
126  KConfig config(themeInfoFile);
127  KConfigGroup group(&config, QStringLiteral("Desktop Entry"));
128  if (group.isValid()) {
129  d->dirName = dirName;
130  d->absolutePaths.append(themePath);
131  d->name = group.readEntry("Name", QString());
132  d->description = group.readEntry("Description", QString());
133  d->themeFileName = group.readEntry("FileName", QString());
134  d->displayExtraVariables = group.readEntry("DisplayExtraVariables", QStringList());
135  }
136 }
137 
138 Theme::Theme(const Theme &other)
139  : d(other.d)
140 {
141 }
142 
143 Theme::~Theme()
144 {
145 }
146 
147 bool Theme::operator==(const Theme &other) const
148 {
149  return isValid() && other.isValid() && d->absolutePaths == other.d->absolutePaths;
150 }
151 
152 Theme &Theme::operator=(const Theme &other)
153 {
154  if (this != &other) {
155  d = other.d;
156  }
157 
158  return *this;
159 }
160 
161 bool Theme::isValid() const
162 {
163  return !d->themeFileName.isEmpty() && !d->name.isEmpty();
164 }
165 
166 QString Theme::description() const
167 {
168  return d->description;
169 }
170 
171 QString Theme::themeFilename() const
172 {
173  return d->themeFileName;
174 }
175 
176 QString Theme::name() const
177 {
178  return d->name;
179 }
180 
181 QStringList Theme::displayExtraVariables() const
182 {
183  return d->displayExtraVariables;
184 }
185 
186 QString Theme::dirName() const
187 {
188  return d->dirName;
189 }
190 
191 QString Theme::absolutePath() const
192 {
193  return d->absolutePaths.at(0); // ####
194 }
195 
196 QString Theme::author() const
197 {
198  return d->author;
199 }
200 
201 QString Theme::authorEmail() const
202 {
203  return d->email;
204 }
205 
206 void Theme::addThemePath(const QString &path)
207 {
208  d->absolutePaths.append(path);
209 }
210 
211 QString Theme::render(const QString &templateName, const QVariantHash &data, const QByteArray &applicationDomain)
212 {
213  if (!d->loader) {
214  d->setupLoader();
215  }
216  Q_ASSERT(d->loader);
217 
218  if (!d->loader->canLoadTemplate(templateName)) {
219  qCWarning(GRANTLEETHEME_LOG) << "Cannot load template" << templateName << ", please check your installation. Tried in these dirs:" << d->loader->templateDirs();
220  return QString();
221  }
222 
223  Grantlee::Template tpl = d->loader->loadByName(templateName, ThemePrivate::sEngine);
224  if (!tpl || tpl->error()) {
225  return d->errorTemplate(i18n("Template parsing error"), templateName, tpl);
226  }
227 
228  Grantlee::Context ctx = d->createContext(data, applicationDomain);
229  const QString result = tpl->render(&ctx);
230  if (tpl->error()) {
231  return d->errorTemplate(i18n("Template rendering error"), templateName, tpl);
232  }
233 
234  return result;
235 }
236 
237 void Theme::addPluginPath(const QString &path)
238 {
239  if (!ThemePrivate::sEngine) {
240  ThemePrivate::setupEngine();
241  }
242 
243  QStringList paths = ThemePrivate::sEngine->pluginPaths();
244  if (!paths.contains(path)) {
245  paths.prepend(path);
246  ThemePrivate::sEngine->setPluginPaths(paths);
247  }
248 }
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:36
void prepend(const T &value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sat Jun 6 2020 23:12:00 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.