Make the Grantlee::Node::render method const.
[grantlee:grantlee.git] / templates / lib / node.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 "node.h"
22
23 #include "metaenumvariable_p.h"
24 #include "nodebuiltins_p.h"
25 #include "template.h"
26 #include "util.h"
27
28 using namespace Grantlee;
29
30 namespace Grantlee
31 {
32
33 class NodePrivate
34 {
35   NodePrivate( Node *node )
36       : q_ptr( node ) {
37
38   }
39   Q_DECLARE_PUBLIC( Node )
40   Node * const q_ptr;
41 };
42
43 class AbstractNodeFactoryPrivate
44 {
45   AbstractNodeFactoryPrivate( AbstractNodeFactory *factory )
46       : q_ptr( factory ) {
47
48   }
49
50   Q_DECLARE_PUBLIC( AbstractNodeFactory )
51   AbstractNodeFactory * const q_ptr;
52 };
53
54 }
55
56 Node::Node( QObject *parent ) : QObject( parent ),
57     d_ptr( new NodePrivate( this ) )
58 {
59
60 }
61
62 Node::~Node()
63 {
64   delete d_ptr;
65 }
66
67 void Node::streamValueInContext( OutputStream *stream, const QVariant& input, Context* c ) const
68 {
69   Grantlee::SafeString inputString;
70   if ( input.type() == QVariant::List ) {
71     inputString = toString( input.toList() );
72   } else if ( input.userType() == qMetaTypeId<MetaEnumVariable>() ) {
73     const MetaEnumVariable mev = input.value<MetaEnumVariable>();
74     if ( mev.value >= 0 )
75       ( *stream ) << QString::number( mev.value );
76   } else {
77     inputString = getSafeString( input );
78   }
79   if ( c->autoEscape() && !inputString.isSafe() )
80     inputString.setNeedsEscape( true );
81
82   ( *stream ) << inputString;
83 }
84
85 TemplateImpl* Node::containerTemplate() const
86 {
87   QObject *_parent = parent();
88   TemplateImpl *ti = qobject_cast<TemplateImpl *>( _parent );
89   while ( _parent && !ti ) {
90     _parent = _parent->parent();
91     ti = qobject_cast<TemplateImpl *>( _parent );
92   }
93   Q_ASSERT( ti );
94   return ti;
95 }
96
97
98 NodeList::NodeList()
99     : QList<Grantlee::Node*>(), m_containsNonText( false )
100 {
101
102 }
103
104 NodeList::NodeList( const NodeList &list )
105     : QList<Grantlee::Node*>( list )
106 {
107   m_containsNonText = list.m_containsNonText;
108 }
109
110 NodeList::NodeList( const QList<Grantlee::Node *> &list )
111     : QList<Grantlee::Node*>( list )
112 {
113   Q_FOREACH( Grantlee::Node *node, list ) {
114     TextNode *textNode = qobject_cast<TextNode *>( node );
115     if ( !textNode ) {
116       m_containsNonText = true;
117       return;
118     }
119   }
120   m_containsNonText = false;
121 }
122
123 NodeList::~NodeList()
124 {
125 }
126
127 void NodeList::append( Grantlee::Node *node )
128 {
129   if ( !m_containsNonText ) {
130     TextNode *textNode = qobject_cast<TextNode *>( node );
131     if ( !textNode )
132       m_containsNonText = true;
133   }
134
135   QList<Grantlee::Node *>::append( node );
136 }
137
138 void NodeList::append( QList<Grantlee::Node*> nodeList )
139 {
140   if ( !m_containsNonText ) {
141     Q_FOREACH( Grantlee::Node *node, nodeList ) {
142       TextNode *textNode = qobject_cast<TextNode *>( node );
143       if ( !textNode ) {
144         m_containsNonText = true;
145         break;
146       }
147     }
148   }
149
150   QList<Grantlee::Node *>::append( nodeList );
151 }
152
153 bool NodeList::containsNonText() const
154 {
155   return m_containsNonText;
156 }
157
158 void NodeList::render( OutputStream *stream, Context *c ) const
159 {
160   for ( int i = 0; i < this->size(); ++i ) {
161     this->at( i )->render( stream, c );
162   }
163
164   return;
165 }
166
167 AbstractNodeFactory::AbstractNodeFactory( QObject *parent )
168     : QObject( parent ), d_ptr( new AbstractNodeFactoryPrivate( this ) )
169 {
170
171 }
172
173 AbstractNodeFactory::~AbstractNodeFactory()
174 {
175   delete d_ptr;
176 }
177
178 QList< FilterExpression > AbstractNodeFactory::getFilterExpressionList( const QStringList &list, Parser *p ) const
179 {
180   QList<FilterExpression> fes;
181   QListIterator<QString> it( list );
182   while ( it.hasNext() ) {
183     const QString varString = it.next();
184     fes << FilterExpression( varString, p );
185   }
186   return fes;
187 }
188
189 QStringList AbstractNodeFactory::smartSplit( const QString &str ) const
190 {
191   const QRegExp r( QLatin1String( "("                   // match
192                     "(?:[^\\s\\\'\\\"]*"                // things that are not whitespace or escaped quote chars
193                       "(?:"                             // followed by
194                         "(?:\""                         // Either a quote starting with "
195                           "(?:[^\"\\\\]|\\\\.)*\""      // followed by anything that is not the end of the quote
196                         "|\'"                           // Or a quote starting with '
197                           "(?:[^\'\\\\]|\\\\.)*\'"      // followed by anything that is not the end of the quote
198                         ")"                             // (End either)
199                         "[^\\s\'\"]*"                   // To the start of the next such fragment
200                       ")+"                              // Perform multiple matches of the above.
201                     ")"                                 // End of quoted string handling.
202                     "|\\S+"                             // Apart from quoted strings, match non-whitespace fragments also
203                   ")"                                   // End match
204                 ) );
205
206   QStringList l;
207   int count = 0;
208   int pos = 0;
209   while (( pos = r.indexIn( str, pos ) ) != -1 ) {
210     ++count;
211     pos += r.matchedLength();
212     l << r.capturedTexts().first();
213   }
214
215   return l;
216 }
217
218 #include "node.moc"
219