File indexing completed on 2025-02-09 04:28:40
0001 /* 0002 This file is part of the KTextTemplate library 0003 0004 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 0008 */ 0009 0010 #include "templateloader.h" 0011 0012 #include "engine.h" 0013 #include "exception.h" 0014 #include "nulllocalizer_p.h" 0015 0016 #include <QDir> 0017 #include <QFile> 0018 #include <QFileInfo> 0019 0020 using namespace KTextTemplate; 0021 0022 AbstractTemplateLoader::~AbstractTemplateLoader() = default; 0023 0024 namespace KTextTemplate 0025 { 0026 class FileSystemTemplateLoaderPrivate 0027 { 0028 FileSystemTemplateLoaderPrivate(FileSystemTemplateLoader *loader, QSharedPointer<AbstractLocalizer> localizer) 0029 : q_ptr(loader) 0030 , m_localizer(localizer ? localizer : QSharedPointer<AbstractLocalizer>(new NullLocalizer)) 0031 { 0032 } 0033 Q_DECLARE_PUBLIC(FileSystemTemplateLoader) 0034 FileSystemTemplateLoader *const q_ptr; 0035 0036 QString m_themeName; 0037 QStringList m_templateDirs; 0038 const QSharedPointer<AbstractLocalizer> m_localizer; 0039 }; 0040 } 0041 0042 FileSystemTemplateLoader::FileSystemTemplateLoader(const QSharedPointer<AbstractLocalizer> localizer) 0043 : AbstractTemplateLoader() 0044 , d_ptr(new FileSystemTemplateLoaderPrivate(this, localizer)) 0045 { 0046 } 0047 0048 FileSystemTemplateLoader::~FileSystemTemplateLoader() 0049 { 0050 for (const QString &dir : templateDirs()) 0051 d_ptr->m_localizer->unloadCatalog(dir + QLatin1Char('/') + themeName()); 0052 delete d_ptr; 0053 } 0054 0055 InMemoryTemplateLoader::InMemoryTemplateLoader() 0056 : AbstractTemplateLoader() 0057 { 0058 } 0059 0060 InMemoryTemplateLoader::~InMemoryTemplateLoader() = default; 0061 0062 void FileSystemTemplateLoader::setTheme(const QString &themeName) 0063 { 0064 Q_D(FileSystemTemplateLoader); 0065 for (const QString &dir : templateDirs()) 0066 d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName); 0067 d->m_themeName = themeName; 0068 for (const QString &dir : templateDirs()) 0069 d->m_localizer->loadCatalog(dir + QLatin1Char('/') + themeName, themeName); 0070 } 0071 0072 QString FileSystemTemplateLoader::themeName() const 0073 { 0074 Q_D(const FileSystemTemplateLoader); 0075 return d->m_themeName; 0076 } 0077 0078 void FileSystemTemplateLoader::setTemplateDirs(const QStringList &dirs) 0079 { 0080 Q_D(FileSystemTemplateLoader); 0081 0082 for (const QString &dir : templateDirs()) 0083 d->m_localizer->unloadCatalog(dir + QLatin1Char('/') + d->m_themeName); 0084 d->m_templateDirs = dirs; 0085 for (const QString &dir : templateDirs()) 0086 d->m_localizer->loadCatalog(dir + QLatin1Char('/') + d->m_themeName, d->m_themeName); 0087 } 0088 0089 QStringList FileSystemTemplateLoader::templateDirs() const 0090 { 0091 Q_D(const FileSystemTemplateLoader); 0092 return d->m_templateDirs; 0093 } 0094 0095 bool FileSystemTemplateLoader::canLoadTemplate(const QString &name) const 0096 { 0097 Q_D(const FileSystemTemplateLoader); 0098 auto i = 0; 0099 QFile file; 0100 0101 while (!file.exists()) { 0102 if (i >= d->m_templateDirs.size()) 0103 break; 0104 0105 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName + QLatin1Char('/') + name); 0106 ++i; 0107 } 0108 0109 if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) { 0110 return false; 0111 } 0112 file.close(); 0113 return true; 0114 } 0115 0116 Template FileSystemTemplateLoader::loadByName(const QString &fileName, Engine const *engine) const 0117 { 0118 Q_D(const FileSystemTemplateLoader); 0119 auto i = 0; 0120 QFile file; 0121 0122 while (!file.exists()) { 0123 if (i >= d->m_templateDirs.size()) 0124 break; 0125 0126 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName + QLatin1Char('/') + fileName); 0127 const QFileInfo fi(file); 0128 0129 if (file.exists() && !fi.canonicalFilePath().contains(QDir(d->m_templateDirs.at(i)).canonicalPath())) 0130 return {}; 0131 ++i; 0132 } 0133 0134 if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) { 0135 return {}; 0136 } 0137 0138 QTextStream fstream(&file); 0139 fstream.setEncoding(QStringConverter::Utf8); 0140 const auto fileContent = fstream.readAll(); 0141 0142 return engine->newTemplate(fileContent, fileName); 0143 } 0144 0145 std::pair<QString, QString> FileSystemTemplateLoader::getMediaUri(const QString &fileName) const 0146 { 0147 Q_D(const FileSystemTemplateLoader); 0148 auto i = 0; 0149 QFile file; 0150 while (!file.exists()) { 0151 if (i >= d->m_templateDirs.size()) 0152 break; 0153 0154 file.setFileName(d->m_templateDirs.at(i) + QLatin1Char('/') + d->m_themeName + QLatin1Char('/') + fileName); 0155 0156 const QFileInfo fi(file); 0157 if (!fi.canonicalFilePath().contains(QDir(d->m_templateDirs.at(i)).canonicalPath())) { 0158 ++i; 0159 continue; 0160 } 0161 0162 if (file.exists()) { 0163 auto path = fi.absoluteFilePath(); 0164 path.chop(fileName.size()); 0165 return std::make_pair(path, fileName); 0166 } 0167 ++i; 0168 } 0169 return {}; 0170 } 0171 0172 void InMemoryTemplateLoader::setTemplate(const QString &name, const QString &content) 0173 { 0174 m_namedTemplates.insert(name, content); 0175 } 0176 0177 bool InMemoryTemplateLoader::canLoadTemplate(const QString &name) const 0178 { 0179 return m_namedTemplates.contains(name); 0180 } 0181 0182 Template InMemoryTemplateLoader::loadByName(const QString &name, Engine const *engine) const 0183 { 0184 const auto it = m_namedTemplates.constFind(name); 0185 if (it != m_namedTemplates.constEnd()) { 0186 return engine->newTemplate(it.value(), name); 0187 } 0188 throw KTextTemplate::Exception(TagSyntaxError, QStringLiteral("Couldn't load template %1. Template does not exist.").arg(name)); 0189 } 0190 0191 std::pair<QString, QString> InMemoryTemplateLoader::getMediaUri(const QString &fileName) const 0192 { 0193 Q_UNUSED(fileName) 0194 // This loader doesn't make any media available yet. 0195 return {}; 0196 }