Always use QStringBuilder.
[grantlee:grantlee.git] / templates / lib / util.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 "util.h"
22
23 #include "metaenumvariable_p.h"
24 #include "metatype.h"
25
26 #include <QtCore/QStringList>
27
28 QString Grantlee::unescapeStringLiteral( const QString &input )
29 {
30   return input.mid( 1, input.size() - 2 )
31          .replace( QLatin1String( "\\\'" ), QChar::fromLatin1( '\'' ) )
32          .replace( QLatin1String( "\\\"" ), QChar::fromLatin1( '"' ) )
33          .replace( QLatin1String( "\\\\" ), QChar::fromLatin1( '\\' ) );
34 }
35
36 bool Grantlee::variantIsTrue( const QVariant &variant )
37 {
38
39   if ( !variant.isValid() )
40     return false;
41   switch ( variant.userType() ) {
42   case QVariant::Bool: {
43     return variant.toBool();
44   }
45   case QVariant::Int: {
46     return ( variant.toInt() > 0 );
47   }
48   case QVariant::Double: {
49     return ( variant.toDouble() > 0 );
50   }
51   case QMetaType::QObjectStar: {
52     QObject *obj = variant.value<QObject *>();
53     if ( !obj )
54       return false;
55
56     if ( obj->property( "__true__" ).isValid() ) {
57       return obj->property( "__true__" ).toBool();
58     }
59     return true;
60   }
61   case QVariant::List: {
62     return ( variant.toList().size() > 0 );
63   }
64   case QVariant::Hash: {
65     return ( variant.toHash().size() > 0 );
66   }
67   }
68
69   return !getSafeString( variant ).get().isEmpty();
70 }
71
72 Grantlee::SafeString Grantlee::markSafe( const Grantlee::SafeString &input )
73 {
74   Grantlee::SafeString sret = input;
75   sret.setSafety( Grantlee::SafeString::IsSafe );
76   return sret;
77 }
78
79 Grantlee::SafeString Grantlee::markForEscaping( const Grantlee::SafeString &input )
80 {
81   Grantlee::SafeString temp = input;
82   if ( input.isSafe() || input.needsEscape() )
83     return input;
84
85   temp.setNeedsEscape( true );
86   return temp;
87 }
88
89 Grantlee::SafeString Grantlee::getSafeString( const QVariant &input )
90 {
91   if ( input.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
92     return input.value<Grantlee::SafeString>();
93   } else {
94     return input.toString();
95   }
96 }
97
98 bool Grantlee::isSafeString( const QVariant &input )
99 {
100   const int type = input.userType();
101   return (( type == qMetaTypeId<Grantlee::SafeString>() )
102           || type == QVariant::String );
103 }
104
105 static QList<int> getPrimitives()
106 {
107   QList<int> primitives;
108   primitives << qMetaTypeId<Grantlee::SafeString>()
109              << QVariant::String
110              << QVariant::Bool
111              << QVariant::Int
112              << QVariant::Double
113              << QVariant::Date
114              << QVariant::Time
115              << QVariant::DateTime;
116   return primitives;
117 }
118
119 bool Grantlee::supportedOutputType( const QVariant &input )
120 {
121   static const QList<int> primitives = getPrimitives();
122   return primitives.contains( input.userType() );
123 }
124
125
126 bool Grantlee::equals( const QVariant &lhs, const QVariant &rhs )
127 {
128
129   // TODO: Redesign...
130
131   // QVariant doesn't use operator== to compare its held data, so we do it manually instead for SafeString.
132   bool equal = false;
133   if ( lhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
134     if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() ) {
135       equal = ( lhs.value<Grantlee::SafeString>() == rhs.value<Grantlee::SafeString>() );
136     } else if ( rhs.userType() == QVariant::String ) {
137       equal = ( lhs.value<Grantlee::SafeString>() == rhs.toString() );
138     }
139   } else if ( rhs.userType() == qMetaTypeId<Grantlee::SafeString>() && lhs.userType() == QVariant::String ) {
140     equal = ( rhs.value<Grantlee::SafeString>() == lhs.toString() );
141   } else if ( rhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
142     if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
143       equal = ( rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>() );
144     } else if ( lhs.type() == QVariant::Int ) {
145       equal = ( rhs.value<MetaEnumVariable>() == lhs.toInt() );
146     }
147   } else if ( lhs.userType() == qMetaTypeId<MetaEnumVariable>() ) {
148     if ( rhs.type() == QVariant::Int ) {
149       equal = ( lhs.value<MetaEnumVariable>() == rhs.toInt() );
150     }
151   } else {
152     equal = (( lhs == rhs ) && ( lhs.userType() == rhs.userType() ) );
153   }
154   return equal;
155 }
156
157 Grantlee::SafeString Grantlee::toString( const QVariantList &list )
158 {
159   QString output( QLatin1Char( '[' ) );
160   QVariantList::const_iterator it = list.constBegin();
161   const QVariantList::const_iterator end = list.constEnd();
162   while ( it != end ) {
163     const QVariant item = *it;
164     if ( isSafeString( item ) ) {
165       output += QLatin1Literal( "u\'" )
166               + static_cast<QString>( getSafeString( item ).get() )
167               + QLatin1Char( '\'' );
168     }
169     if ( ( item.type() == QVariant::Int )
170       || ( item.type() == QVariant::UInt )
171       || ( item.type() == QVariant::Double )
172       || ( item.type() == QVariant::LongLong )
173       || ( item.type() == QVariant::ULongLong )
174     ) {
175       output += item.toString();
176     }
177     if ( item.type() == QVariant::List ) {
178       output += static_cast<QString>( toString( item.toList() ).get() );
179     }
180     if ( ( it + 1 ) != end )
181       output += QLatin1String( ", " );
182     ++it;
183   }
184
185   return output.append( QLatin1Char( ']' ) );
186 }
187