20 #include "searchquery.h"
22 #include <QtCore/QVariant>
26 #include <qjson/parser.h>
27 #include <qjson/serializer.h>
29 using namespace Akonadi;
31 class SearchTerm::Private:
public QSharedData
42 Private(
const Private &other ):
53 bool operator==(
const Private &other )
const
57 && terms == other.terms
59 &&
value == other.value
67 QList<SearchTerm> terms;
71 class SearchQuery::Private:
public QSharedData
80 Private(
const Private &other ):
82 rootTerm( other.rootTerm ),
87 bool operator==(
const Private &other )
const
89 return rootTerm == other.rootTerm &&
limit == other.limit;
94 const QList<SearchTerm> &subTerms = term.
subTerms();
96 termJSON.insert( QLatin1String(
"negated"), term.
isNegated() );
97 if ( subTerms.isEmpty() ) {
98 termJSON.insert( QLatin1String(
"key" ), term.
key() );
99 termJSON.insert( QLatin1String(
"value" ), term.
value() );
100 termJSON.insert( QLatin1String(
"cond" ), static_cast<int>( term.
condition() ) );
102 termJSON.insert( QLatin1String(
"rel" ), static_cast<int>( term.
relation() ) );
103 QVariantList subTermsJSON;
104 Q_FOREACH (
const SearchTerm &term, subTerms ) {
105 subTermsJSON.append( termToJSON( term ) );
107 termJSON.insert( QLatin1String(
"subTerms" ), subTermsJSON );
113 static SearchTerm JSONToTerm(
const QVariantMap &json )
115 if ( json.contains( QLatin1String(
"key" ) ) ) {
117 json[QLatin1String(
"value" )],
118 static_cast<SearchTerm::Condition>( json[QLatin1String(
"cond" )].toInt() ) );
119 term.
setIsNegated( json[QLatin1String(
"negated" )].toBool() );
121 }
else if ( json.contains( QLatin1String(
"rel" ) ) ) {
122 SearchTerm term( static_cast<SearchTerm::Relation>( json[QLatin1String(
"rel" )].toInt() ) );
123 term.
setIsNegated( json[QLatin1String(
"negated" )].toBool() );
124 const QVariantList subTermsJSON = json[QLatin1String(
"subTerms" )].toList();
125 Q_FOREACH (
const QVariant &subTermJSON, subTermsJSON ) {
126 term.
addSubTerm( JSONToTerm( subTermJSON.toMap() ) );
130 kWarning() <<
"Invalid JSON for term: "<< json;
148 d->relation = RelAnd;
159 SearchTerm::~SearchTerm()
169 bool SearchTerm::operator==(
const SearchTerm &other )
const
171 return *d == *other.d;
174 bool SearchTerm::isNull()
const
176 return d->key.isEmpty() && d->value.isNull() && d->terms.isEmpty();
196 d->isNegated = negated;
231 SearchQuery::~SearchQuery()
241 bool SearchQuery::operator==(
const SearchQuery &other )
const
243 return *d == *other.d;
246 bool SearchQuery::isNull()
const
248 return d->rootTerm.isNull();
263 d->rootTerm.addSubTerm( term );
281 QByteArray SearchQuery::toJSON()
const
283 QVariantMap root = Private::termToJSON( d->rootTerm );
284 root.insert( QLatin1String(
"limit" ), d->limit );
286 QJson::Serializer serializer;
287 return serializer.serialize( root );
290 SearchQuery SearchQuery::fromJSON(
const QByteArray &jsonData )
292 QJson::Parser parser;
294 const QVariant json = parser.parse( jsonData, &ok );
295 if ( !ok || json.isNull() ) {
299 const QVariantMap map = json.toMap();
301 query.d->rootTerm = Private::JSONToTerm( map );
302 if ( map.contains( QLatin1String(
"limit") ) ) {
303 query.d->limit = map.value( QLatin1String(
"limit") ).toInt();
308 QMap<EmailSearchTerm::EmailSearchField, QString> initializeMapping()
310 QMap<EmailSearchTerm::EmailSearchField, QString> mapping;
311 mapping.insert(EmailSearchTerm::Body, QLatin1String(
"body"));
312 mapping.insert(EmailSearchTerm::Headers, QLatin1String(
"headers"));
313 mapping.insert(EmailSearchTerm::Subject, QLatin1String(
"subject"));
314 mapping.insert(EmailSearchTerm::Message, QLatin1String(
"message"));
315 mapping.insert(EmailSearchTerm::HeaderFrom, QLatin1String(
"from"));
316 mapping.insert(EmailSearchTerm::HeaderTo, QLatin1String(
"to"));
317 mapping.insert(EmailSearchTerm::HeaderCC, QLatin1String(
"cc"));
318 mapping.insert(EmailSearchTerm::HeaderBCC, QLatin1String(
"bcc"));
319 mapping.insert(EmailSearchTerm::HeaderReplyTo, QLatin1String(
"replyto"));
320 mapping.insert(EmailSearchTerm::HeaderOrganization, QLatin1String(
"organization"));
321 mapping.insert(EmailSearchTerm::HeaderListId, QLatin1String(
"listid"));
322 mapping.insert(EmailSearchTerm::HeaderResentFrom, QLatin1String(
"resentfrom"));
323 mapping.insert(EmailSearchTerm::HeaderXLoop, QLatin1String(
"xloop"));
324 mapping.insert(EmailSearchTerm::HeaderXMailingList, QLatin1String(
"xmailinglist"));
325 mapping.insert(EmailSearchTerm::HeaderXSpamFlag, QLatin1String(
"xspamflag"));
326 mapping.insert(EmailSearchTerm::HeaderDate, QLatin1String(
"date"));
327 mapping.insert(EmailSearchTerm::HeaderOnlyDate, QLatin1String(
"onlydate"));
328 mapping.insert(EmailSearchTerm::MessageStatus, QLatin1String(
"messagestatus"));
329 mapping.insert(EmailSearchTerm::MessageTag, QLatin1String(
"messagetag"));
330 mapping.insert(EmailSearchTerm::ByteSize, QLatin1String(
"size"));
331 mapping.insert(EmailSearchTerm::Attachment, QLatin1String(
"attachment"));
335 static QMap<EmailSearchTerm::EmailSearchField, QString> emailSearchFieldMapping = initializeMapping();
338 :
SearchTerm( toKey( field ), value, condition )
345 return emailSearchFieldMapping.value( field );
350 return emailSearchFieldMapping.key(key);
353 QMap<ContactSearchTerm::ContactSearchField, QString> initializeContactMapping()
355 QMap<ContactSearchTerm::ContactSearchField, QString> mapping;
356 mapping.insert(ContactSearchTerm::Name, QLatin1String(
"name"));
357 mapping.insert(ContactSearchTerm::Nickname, QLatin1String(
"nickname"));
358 mapping.insert(ContactSearchTerm::Email, QLatin1String(
"email"));
359 mapping.insert(ContactSearchTerm::Uid, QLatin1String(
"uid"));
360 mapping.insert(ContactSearchTerm::All, QLatin1String(
"all"));
364 static QMap<ContactSearchTerm::ContactSearchField, QString> contactSearchFieldMapping = initializeContactMapping();
366 ContactSearchTerm::ContactSearchTerm( ContactSearchTerm::ContactSearchField field,
const QVariant& value, SearchTerm::Condition condition )
367 :
SearchTerm( toKey( field ), value, condition )
374 return contactSearchFieldMapping.value( field );
379 return contactSearchFieldMapping.key(key);
void setIsNegated(bool negated)
Sets whether the entire term is negated.
void setTerm(const SearchTerm &term)
Sets the root term.
bool isNegated() const
Returns whether the entire term is negated.
void addSubTerm(const SearchTerm &term)
Adds a new subterm to this term.
EmailSearchTerm(EmailSearchField field, const QVariant &value, SearchTerm::Condition condition=SearchTerm::CondEqual)
Constructs an email end term.
static QString toKey(EmailSearchField)
Translates field to key.
void addTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition=SearchTerm::CondEqual)
Adds a new term.
SearchTerm::Condition condition() const
Returns relation between key and value.
QString key() const
Returns key of this end term.
SearchTerm(SearchTerm::Relation relation=SearchTerm::RelAnd)
Constructs a term where all subterms will be in given relation.
static EmailSearchField fromKey(const QString &key)
Translates key to field.
A query that can be passed to ItemSearchJob or others.
SearchTerm term() const
Returns the root term.
void setLimit(int limit)
Sets the maximum number of results.
QList< SearchTerm > subTerms() const
Returns all subterms, or an empty list if this is an end term.
QVariant value() const
Returns value of this end term.
SearchQuery(SearchTerm::Relation rel=SearchTerm::RelAnd)
Constructs query where all added terms will be in given relation.
Search term represents the actual condition within query.
int limit() const
Returns the maximum number of results.
SearchTerm::Relation relation() const
Returns relation in which all subterms are.
EmailSearchField
All fields expect a search string unless noted otherwise.