24 #include "exception.h"
25 #include "cutelee_config_p.h"
26 #include "cutelee_version.h"
28 #include "scriptabletags.h"
30 #include "template_p.h"
31 #include "templateloader.h"
33 #include <QtCore/QCoreApplication>
34 #include <QtCore/QDir>
35 #include <QtCore/QPluginLoader>
36 #include <QtCore/QTextStream>
40 static const char __scriptableLibName[] =
"cutelee_scriptabletags";
43 : QObject(parent), d_ptr(new EnginePrivate(this))
45 d_ptr->m_defaultLibraries << QStringLiteral(
"cutelee_defaulttags")
46 << QStringLiteral(
"cutelee_loadertags")
47 << QStringLiteral(
"cutelee_defaultfilters");
49 d_ptr->m_pluginDirs = QCoreApplication::instance()->libraryPaths();
50 d_ptr->m_pluginDirs << QString::fromLocal8Bit(CUTELEE_PLUGIN_PATH);
56 qDeleteAll(d_ptr->m_scriptableLibraries);
58 d_ptr->m_libraries.clear();
71 d->m_loaders << loader;
78 std::pair<QString, QString> uri;
79 for (
const auto &loader : d->m_loaders) {
80 uri = loader->getMediaUri(fileName);
81 if (!uri.second.isEmpty())
90 d->m_pluginDirs = dirs;
98 temp << d->m_pluginDirs;
99 d->m_pluginDirs = temp;
105 d->m_pluginDirs.removeAll(dir);
111 return d->m_pluginDirs;
117 return d->m_defaultLibraries;
123 d->m_defaultLibraries << libName;
129 d->m_defaultLibraries.removeAll(libName);
132 template <u
int v>
bool acceptableVersion(uint minorVersion)
134 return minorVersion >= v;
137 template <>
bool acceptableVersion<0>(uint) {
return true; }
139 void Engine::loadDefaultLibraries()
145 if (d->m_defaultLibraries.contains(QLatin1String(__scriptableLibName))
146 && !d->m_scriptableTagLibrary) {
154 d->loadCppLibrary( __scriptableLibName, CUTELEE_VERSION_MINOR );
155 PluginPointer<TagLibraryInterface> library = d->loadCppLibrary( __scriptableLibName, CUTELEE_VERSION_MINOR );
157 throw Cutelee::Exception( TagSyntaxError, QStringLiteral(
"Could not load scriptable tags library") );
164 if (libName == QLatin1String(__scriptableLibName))
168 if (d->m_libraries.contains(libName))
171 uint minorVersion = CUTELEE_VERSION_MINOR;
172 while (acceptableVersion<CUTELEE_MIN_PLUGIN_VERSION>(minorVersion)) {
177 auto scriptableLibrary = d->loadScriptableLibrary(libName, minorVersion);
178 if (scriptableLibrary) {
179 scriptableLibrary->clear();
184 auto library = d->loadCppLibrary(libName, minorVersion);
185 if (minorVersion == 0)
199 if (name == QLatin1String(__scriptableLibName))
204 const auto it = d->m_libraries.constFind(name);
205 if (it != d->m_libraries.constEnd()) {
209 uint minorVersion = CUTELEE_VERSION_MINOR;
210 while (acceptableVersion<CUTELEE_MIN_PLUGIN_VERSION>(minorVersion)) {
211 auto library = d->loadLibrary(name, minorVersion);
214 if (minorVersion == 0)
220 QStringLiteral(
"Plugin library '%1' not found.").arg(name));
227 auto ptr = PluginPointer<TagLibraryInterface>(lib);
228 d->m_libraries.insert(name, ptr);
235 d->m_defaultLibraries << name;
242 auto scriptableLibrary = loadScriptableLibrary(name, minorVersion);
243 if (scriptableLibrary)
244 return scriptableLibrary;
249 return loadCppLibrary(name, minorVersion).data();
252 EnginePrivate::EnginePrivate(
Engine *engine)
256 m_scriptableTagLibrary(0)
259 m_smartTrimEnabled(false)
264 uint minorVersion)
const
266 auto pluginIndex = 0;
268 = QStringLiteral(
"/cutelee-qt") + QString::number(QT_VERSION_MAJOR) + QLatin1Char(
'/')
269 + QString::number(CUTELEE_VERSION_MAJOR) + QLatin1Char(
'.') + QString::number(minorVersion) + QLatin1Char(
'/');
270 while (m_pluginDirs.size() > pluginIndex) {
271 const auto nextDir = m_pluginDirs.at(pluginIndex++);
272 const QString libFileName = nextDir + prefix + name + QStringLiteral(
".qs");
274 const QFile file(libFileName);
280 for (
const auto &loader : m_loaders) {
281 const auto pair = loader->getMediaUri(prefix + name + QStringLiteral(
".qs"));
283 if (!pair.first.isEmpty() && !pair.second.isEmpty()) {
284 return pair.first + pair.second;
292 ScriptableLibraryContainer *
293 EnginePrivate::loadScriptableLibrary(
const QString &name, uint minorVersion)
295 if (!m_scriptableTagLibrary)
298 const auto libFileName = getScriptLibraryName(name, minorVersion);
300 if (libFileName.isEmpty())
303 const auto it = m_scriptableLibraries.constFind(libFileName);
304 if (it != m_scriptableLibraries.constEnd()) {
305 auto library = it.value();
306 library->setNodeFactories(m_scriptableTagLibrary->nodeFactories(libFileName));
307 library->setFilters(m_scriptableTagLibrary->filters(libFileName));
311 PluginPointer<TagLibraryInterface> scriptableTagLibrary = m_libraries.value( __scriptableLibName );
314 const auto factories = m_scriptableTagLibrary->nodeFactories(libFileName);
315 const auto filters = m_scriptableTagLibrary->filters(libFileName);
317 auto library =
new ScriptableLibraryContainer(factories, filters);
318 m_scriptableLibraries.insert(libFileName, library);
323 PluginPointer<TagLibraryInterface>
324 EnginePrivate::loadCppLibrary(
const QString &name, uint minorVersion)
326 auto pluginIndex = 0;
328 while (m_pluginDirs.size() > pluginIndex) {
329 const auto nextDir = m_pluginDirs.at(pluginIndex++);
331 = nextDir + QStringLiteral(
"/cutelee-qt") + QString::number(QT_VERSION_MAJOR) + QLatin1Char(
'/')
332 + QString::number(CUTELEE_VERSION_MAJOR) + QLatin1Char(
'.')
333 + QString::number(minorVersion) + QLatin1Char(
'/');
335 const QDir pluginDir(pluginDirString);
337 if (!pluginDir.exists())
340 auto list = pluginDir.entryList(QStringList(name
341 #
if PLUGINS_PREFER_DEBUG_POSTFIX
344 + QLatin1Char(
'*')));
346 if (list.isEmpty()) {
347 #if PLUGINS_PREFER_DEBUG_POSTFIX
348 list = pluginDir.entryList(QStringList(name + QLatin1Char(
'*')));
356 auto pluginPath = pluginDir.absoluteFilePath(list.first());
357 auto plugin = PluginPointer<TagLibraryInterface>(pluginPath);
360 #ifdef __COVERAGESCANNER__
361 __coveragescanner_register_library(pluginPath.toLatin1().data());
363 m_libraries.insert(name, plugin);
374 for (
auto &loader : d->m_loaders) {
375 if (!loader->canLoadTemplate(name))
378 const auto t = loader->loadByName(name,
this);
384 auto t =
Template(
new TemplateImpl(
this));
385 t->setObjectName(name);
386 t->d_ptr->m_error = TagSyntaxError;
387 t->d_ptr->m_errorString = QStringLiteral(
"Template not found, %1").arg(name);
394 auto t =
Template(
new TemplateImpl(
this, d->m_smartTrimEnabled));
395 t->setObjectName(name);
396 t->setContent(content);
403 d->m_smartTrimEnabled = enabled;
409 return d->m_smartTrimEnabled;
Cutelee::Engine is the main entry point for creating Cutelee Templates.
QList< std::shared_ptr< AbstractTemplateLoader > > templateLoaders()
QStringList pluginPaths() const
std::pair< QString, QString > mediaUri(const QString &fileName) const
void insertDefaultLibrary(const QString &name, TagLibraryInterface *lib)
Engine(QObject *parent=nullptr)
Template loadByName(const QString &name) const
void setPluginPaths(const QStringList &dirs)
void addPluginPath(const QString &dir)
void setSmartTrimEnabled(bool enabled)
void removeDefaultLibrary(const QString &libName)
QStringList defaultLibraries() const
Template newTemplate(const QString &content, const QString &name) const
bool smartTrimEnabled() const
void removePluginPath(const QString &dir)
void addTemplateLoader(std::shared_ptr< AbstractTemplateLoader > loader)
void insertLibrary(const QString &name, TagLibraryInterface *lib)
void addDefaultLibrary(const QString &libName)
An exception for use when implementing template tags.
The TagLibraryInterface returns available tags and filters from libraries.
The Template class is a tree of nodes which may be rendered.
The Cutelee namespace holds all public Cutelee API.