Cutelee  6.1.0
templateloader.cpp
1 /*
2  This file is part of the Cutelee template system.
3 
4  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either version
9  2.1 of the Licence, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 #include "templateloader.h"
22 
23 #include "engine.h"
24 #include "exception.h"
25 #include "nulllocalizer_p.h"
26 
27 #include <QtCore/QDir>
28 #include <QtCore/QFile>
29 #include <QtCore/QFileInfo>
30 
31 using namespace Cutelee;
32 
34 
35 namespace Cutelee
36 {
38 {
40  std::shared_ptr<AbstractLocalizer> localizer)
41  : q_ptr(loader),
42  m_localizer(localizer
43  ? localizer
44  : std::shared_ptr<AbstractLocalizer>(new NullLocalizer))
45  {
46  }
47  Q_DECLARE_PUBLIC(FileSystemTemplateLoader)
48  FileSystemTemplateLoader *const q_ptr;
49 
50  QString m_themeName;
51  QStringList m_templateDirs;
52  const std::shared_ptr<AbstractLocalizer> m_localizer;
53 };
54 }
55 
57  const std::shared_ptr<AbstractLocalizer> localizer)
59  d_ptr(new FileSystemTemplateLoaderPrivate(this, localizer))
60 {
61 }
62 
64 {
65  Q_FOREACH (const QString &dir, templateDirs())
66  d_ptr->m_localizer->unloadCatalog(dir + QLatin1Char('/') + themeName());
67  delete d_ptr;
68 }
69 
70 InMemoryTemplateLoader::InMemoryTemplateLoader() : AbstractTemplateLoader() {}
71 
72 InMemoryTemplateLoader::~InMemoryTemplateLoader() {}
73 
75 {
77  Q_FOREACH (const QString &dir, templateDirs())
78  d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName);
79  d->m_themeName = themeName;
80  Q_FOREACH (const QString &dir, templateDirs())
81  d->m_localizer->loadCatalog(dir + QLatin1Char('/') + themeName, themeName);
82 }
83 
85 {
86  Q_D(const FileSystemTemplateLoader);
87  return d->m_themeName;
88 }
89 
90 void FileSystemTemplateLoader::setTemplateDirs(const QStringList &dirs)
91 {
93 
94  Q_FOREACH (const QString &dir, templateDirs())
95  d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName);
96  d->m_templateDirs = dirs;
97  Q_FOREACH (const QString &dir, templateDirs())
98  d->m_localizer->loadCatalog(dir + QLatin1Char('/') + d->m_themeName,
99  d->m_themeName);
100 }
101 
103 {
104  Q_D(const FileSystemTemplateLoader);
105  return d->m_templateDirs;
106 }
107 
109 {
110  Q_D(const FileSystemTemplateLoader);
111  auto i = 0;
112  QFile file;
113 
114  while (!file.exists()) {
115  if (i >= d->m_templateDirs.size())
116  break;
117 
118  file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
119  + QLatin1Char('/') + name);
120  ++i;
121  }
122 
123  if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) {
124  return false;
125  }
126  file.close();
127  return true;
128 }
129 
131  Engine const *engine) const
132 {
133  Q_D(const FileSystemTemplateLoader);
134  auto i = 0;
135  QFile file;
136 
137  while (!file.exists()) {
138  if (i >= d->m_templateDirs.size())
139  break;
140 
141  file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
142  + QLatin1Char('/') + fileName);
143  const QFileInfo fi(file);
144 
145  if (file.exists()
146  && !fi.canonicalFilePath().contains(
147  QDir(d->m_templateDirs.at(i)).canonicalPath()))
148  return Template();
149  ++i;
150  }
151 
152  if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) {
153  return Template();
154  }
155 
156  QTextStream fstream(&file);
157 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
158  fstream.setCodec("UTF-8");
159 #else
160  fstream.setEncoding(QStringConverter::Utf8);
161 #endif
162  const auto fileContent = fstream.readAll();
163 
164  return engine->newTemplate(fileContent, fileName);
165 }
166 
167 std::pair<QString, QString>
169 {
170  Q_D(const FileSystemTemplateLoader);
171  auto i = 0;
172  QFile file;
173  while (!file.exists()) {
174  if (i >= d->m_templateDirs.size())
175  break;
176 
177  file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName
178  + QLatin1Char('/') + fileName);
179 
180  const QFileInfo fi(file);
181  if (!fi.canonicalFilePath().contains(
182  QDir(d->m_templateDirs.at(i)).canonicalPath())) {
183  ++i;
184  continue;
185  }
186 
187  if (file.exists()) {
188  auto path = fi.absoluteFilePath();
189  path.chop(fileName.size());
190  return {path, fileName};
191  }
192  ++i;
193  }
194  return {};
195 }
196 
198  const QString &content)
199 {
200  m_namedTemplates.insert(name, content);
201 }
202 
204 {
205  return m_namedTemplates.contains(name);
206 }
207 
209  Engine const *engine) const
210 {
211  const auto it = m_namedTemplates.constFind(name);
212  if (it != m_namedTemplates.constEnd()) {
213  return engine->newTemplate(it.value(), name);
214  }
215  throw Cutelee::Exception(
216  TagSyntaxError,
217  QStringLiteral("Couldn't load template %1. Template does not exist.")
218  .arg(name));
219 }
220 
221 std::pair<QString, QString>
223 {
224  Q_UNUSED(fileName)
225  // This loader doesn't make any media available yet.
226  return std::pair<QString, QString>();
227 }
An retrieval interface to a storage location for Template objects.
Cutelee::Engine is the main entry point for creating Cutelee Templates.
Definition: engine.h:121
Template newTemplate(const QString &content, const QString &name) const
Definition: engine.cpp:391
An exception for use when implementing template tags.
Definition: exception.h:85
The FileSystemTemplateLoader loads Templates from the file system.
FileSystemTemplateLoader(const std::shared_ptr< AbstractLocalizer > localizer={})
Template loadByName(const QString &name, Engine const *engine) const override
void setTheme(const QString &themeName)
bool canLoadTemplate(const QString &name) const override
void setTemplateDirs(const QStringList &dirs)
std::pair< QString, QString > getMediaUri(const QString &fileName) const override
bool canLoadTemplate(const QString &name) const override
void setTemplate(const QString &name, const QString &content)
std::pair< QString, QString > getMediaUri(const QString &fileName) const override
Template loadByName(const QString &name, Engine const *engine) const override
The Template class is a tree of nodes which may be rendered.
Definition: template.h:95
The Cutelee namespace holds all public Cutelee API.
Definition: Mainpage.dox:8