Always use QStringBuilder.
[grantlee:grantlee.git] / templates / lib / templateloader.cpp
1 /*
2   This file is part of the Grantlee 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 Grantlee;
32
33 AbstractTemplateLoader::~AbstractTemplateLoader()
34 {
35
36 }
37
38 FileSystemTemplateLoader::FileSystemTemplateLoader()
39   : AbstractTemplateLoader()
40 {
41
42 }
43
44 FileSystemTemplateLoader::~FileSystemTemplateLoader()
45 {
46
47 }
48
49 InMemoryTemplateLoader::InMemoryTemplateLoader()
50   : AbstractTemplateLoader()
51 {
52
53 }
54
55 InMemoryTemplateLoader::~InMemoryTemplateLoader()
56 {
57
58 }
59
60 void FileSystemTemplateLoader::setTheme( const QString &themeName )
61 {
62   m_themeName = themeName;
63 }
64
65 QString FileSystemTemplateLoader::themeName() const
66 {
67   return m_themeName;
68 }
69
70 void FileSystemTemplateLoader::setTemplateDirs( const QStringList &dirs )
71 {
72   m_templateDirs = dirs;
73 }
74
75 QStringList FileSystemTemplateLoader::templateDirs() const
76 {
77   return m_templateDirs;
78 }
79
80 bool FileSystemTemplateLoader::canLoadTemplate( const QString &name ) const
81 {
82   int i = 0;
83   QFile file;
84
85   while ( !file.exists() ) {
86     if ( i >= m_templateDirs.size() )
87       break;
88
89     file.setFileName( m_templateDirs.at( i ) + QLatin1Char( '/' ) + m_themeName + QLatin1Char( '/' ) + name );
90     ++i;
91   }
92
93   if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
94     return false;
95   }
96   file.close();
97   return true;
98 }
99
100 Template FileSystemTemplateLoader::loadByName( const QString &fileName, Engine const *engine ) const
101 {
102   int i = 0;
103   QFile file;
104
105   while ( !file.exists() ) {
106     if ( i >= m_templateDirs.size() )
107       break;
108
109     file.setFileName( m_templateDirs.at( i ) + QLatin1Char( '/' ) + m_themeName + QLatin1Char( '/' ) + fileName );
110     const QFileInfo fi( file );
111
112     if ( file.exists() &&
113           !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) )
114       return Template();
115     ++i;
116   }
117
118   if ( !file.exists() || !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
119     return Template();
120   }
121
122   QTextStream fstream( &file );
123   fstream.setCodec( "UTF-8" );
124   const QString fileContent = fstream.readAll();
125
126   return engine->newTemplate( fileContent, fileName );
127 }
128
129 QPair<QString, QString> FileSystemTemplateLoader::getMediaUri( const QString& fileName ) const
130 {
131   int i = 0;
132   QFile file;
133   while ( !file.exists() ) {
134     if ( i >= m_templateDirs.size() )
135       break;
136
137     file.setFileName( m_templateDirs.at( i ) + QLatin1Char( '/' ) + m_themeName + QLatin1Char( '/' ) + fileName );
138
139     const QFileInfo fi( file );
140     if ( !fi.canonicalFilePath().contains( QDir( m_templateDirs.at( i ) ).canonicalPath() ) ) {
141       ++i;
142       continue;
143     }
144
145     if ( file.exists() ) {
146       QString path = fi.absoluteFilePath();
147       path.chop( fileName.size() );
148       return qMakePair( path, fileName );
149     }
150     ++i;
151   }
152   return QPair<QString, QString>();
153 }
154
155
156 void InMemoryTemplateLoader::setTemplate( const QString &name, const QString &content )
157 {
158   m_namedTemplates.insert( name, content );
159 }
160
161 bool InMemoryTemplateLoader::canLoadTemplate( const QString &name ) const
162 {
163   return m_namedTemplates.contains( name );
164 }
165
166 Template InMemoryTemplateLoader::loadByName( const QString& name, Engine const *engine ) const
167 {
168   if ( m_namedTemplates.contains( name ) ) {
169     return engine->newTemplate( m_namedTemplates.value( name ), name );
170   }
171   throw Grantlee::Exception( TagSyntaxError, QString::fromLatin1( "Couldn't load template %1. Template does not exist." ).arg( name ) );
172 }
173
174 QPair<QString, QString> InMemoryTemplateLoader::getMediaUri( const QString& fileName ) const
175 {
176   Q_UNUSED( fileName )
177   // This loader doesn't make any media available yet.
178   return QPair<QString, QString>();
179 }
180
181 namespace Grantlee
182 {
183
184 class LocalizedFileSystemTemplateLoaderPrivate
185 {
186   LocalizedFileSystemTemplateLoaderPrivate( LocalizedFileSystemTemplateLoader *qq, AbstractLocalizer::Ptr localizer )
187     : q_ptr( qq ), m_localizer( localizer ? localizer : AbstractLocalizer::Ptr( new NullLocalizer ) )
188   {
189
190   }
191   Q_DECLARE_PUBLIC( LocalizedFileSystemTemplateLoader )
192   LocalizedFileSystemTemplateLoader * const q_ptr;
193   const AbstractLocalizer::Ptr m_localizer;
194 };
195
196 }
197
198 LocalizedFileSystemTemplateLoader::LocalizedFileSystemTemplateLoader( const AbstractLocalizer::Ptr localizer )
199   : FileSystemTemplateLoader(),
200     d_ptr( new LocalizedFileSystemTemplateLoaderPrivate( this, localizer ) )
201 {
202
203 }
204
205 LocalizedFileSystemTemplateLoader::~LocalizedFileSystemTemplateLoader()
206 {
207   Q_FOREACH( const QString &dir, templateDirs() )
208     d_ptr->m_localizer->unloadCatalog( dir + QLatin1Char( '/' ) + themeName() );
209   delete d_ptr;
210 }
211
212 void LocalizedFileSystemTemplateLoader::setTemplateDirs( const QStringList& dirs )
213 {
214   Q_D( LocalizedFileSystemTemplateLoader );
215   Q_FOREACH( const QString &dir, templateDirs() )
216     d->m_localizer->unloadCatalog( dir + QLatin1Char( '/' ) + themeName() );
217   FileSystemTemplateLoader::setTemplateDirs( dirs );
218   Q_FOREACH( const QString &dir, templateDirs() )
219     d->m_localizer->loadCatalog( dir + QLatin1Char( '/' ) + themeName(), themeName() );
220 }
221
222 void LocalizedFileSystemTemplateLoader::setTheme( const QString& _themeName )
223 {
224   Q_D( LocalizedFileSystemTemplateLoader );
225   Q_FOREACH( const QString &dir, templateDirs() )
226     d->m_localizer->unloadCatalog( dir + QLatin1Char( '/' ) + themeName() );
227   FileSystemTemplateLoader::setTheme( _themeName );
228   Q_FOREACH( const QString &dir, templateDirs() )
229     d->m_localizer->loadCatalog( dir + QLatin1Char( '/' ) + _themeName, _themeName );
230 }