mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
379 lines
10 KiB
C++
379 lines
10 KiB
C++
/*
|
|
Copyright (c) 2014 Daniel Vrátil <dvratil@redhat.com>
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
*/
|
|
|
|
#include "searchquery.h"
|
|
|
|
#include <QtCore/QVariant>
|
|
|
|
#include <KDebug>
|
|
|
|
#include <qjson/parser.h>
|
|
#include <qjson/serializer.h>
|
|
|
|
using namespace Akonadi;
|
|
|
|
class SearchTerm::Private : public QSharedData
|
|
{
|
|
public:
|
|
Private()
|
|
: QSharedData()
|
|
, condition(SearchTerm::CondEqual)
|
|
, relation(SearchTerm::RelAnd)
|
|
, isNegated(false)
|
|
{
|
|
}
|
|
|
|
Private(const Private &other)
|
|
: QSharedData(other)
|
|
, key(other.key)
|
|
, value(other.value)
|
|
, condition(other.condition)
|
|
, relation(other.relation)
|
|
, terms(other.terms)
|
|
, isNegated(other.isNegated)
|
|
{
|
|
}
|
|
|
|
bool operator==(const Private &other) const
|
|
{
|
|
return relation == other.relation
|
|
&& isNegated == other.isNegated
|
|
&& terms == other.terms
|
|
&& key == other.key
|
|
&& value == other.value
|
|
&& condition == other.condition;
|
|
}
|
|
|
|
QString key;
|
|
QVariant value;
|
|
Condition condition;
|
|
Relation relation;
|
|
QList<SearchTerm> terms;
|
|
bool isNegated;
|
|
};
|
|
|
|
class SearchQuery::Private : public QSharedData
|
|
{
|
|
public:
|
|
Private()
|
|
: QSharedData()
|
|
, limit(-1)
|
|
{
|
|
}
|
|
|
|
Private(const Private &other)
|
|
: QSharedData(other)
|
|
, rootTerm(other.rootTerm)
|
|
, limit(other.limit)
|
|
{
|
|
}
|
|
|
|
bool operator==(const Private &other) const
|
|
{
|
|
return rootTerm == other.rootTerm && limit == other.limit;
|
|
}
|
|
|
|
static QVariantMap termToJSON(const SearchTerm &term)
|
|
{
|
|
const QList<SearchTerm> &subTerms = term.subTerms();
|
|
QVariantMap termJSON;
|
|
termJSON.insert(QLatin1String("negated"), term.isNegated());
|
|
if (subTerms.isEmpty()) {
|
|
termJSON.insert(QLatin1String("key"), term.key());
|
|
termJSON.insert(QLatin1String("value"), term.value());
|
|
termJSON.insert(QLatin1String("cond"), static_cast<int>(term.condition()));
|
|
} else {
|
|
termJSON.insert(QLatin1String("rel"), static_cast<int>(term.relation()));
|
|
QVariantList subTermsJSON;
|
|
Q_FOREACH (const SearchTerm &term, subTerms) {
|
|
subTermsJSON.append(termToJSON(term));
|
|
}
|
|
termJSON.insert(QLatin1String("subTerms"), subTermsJSON);
|
|
}
|
|
|
|
return termJSON;
|
|
}
|
|
|
|
static SearchTerm JSONToTerm(const QVariantMap &json)
|
|
{
|
|
if (json.contains(QLatin1String("key"))) {
|
|
SearchTerm term(json[QLatin1String("key")].toString(),
|
|
json[QLatin1String("value")],
|
|
static_cast<SearchTerm::Condition>(json[QLatin1String("cond")].toInt()));
|
|
term.setIsNegated(json[QLatin1String("negated")].toBool());
|
|
return term;
|
|
} else if (json.contains(QLatin1String("rel"))) {
|
|
SearchTerm term(static_cast<SearchTerm::Relation>(json[QLatin1String("rel")].toInt()));
|
|
term.setIsNegated(json[QLatin1String("negated")].toBool());
|
|
const QVariantList subTermsJSON = json[QLatin1String("subTerms")].toList();
|
|
Q_FOREACH (const QVariant &subTermJSON, subTermsJSON) {
|
|
term.addSubTerm(JSONToTerm(subTermJSON.toMap()));
|
|
}
|
|
return term;
|
|
} else {
|
|
kWarning() << "Invalid JSON for term: " << json;
|
|
return SearchTerm();
|
|
}
|
|
}
|
|
|
|
SearchTerm rootTerm;
|
|
int limit;
|
|
};
|
|
|
|
SearchTerm::SearchTerm(SearchTerm::Relation relation)
|
|
: d(new Private)
|
|
{
|
|
d->relation = relation;
|
|
}
|
|
|
|
SearchTerm::SearchTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition)
|
|
: d(new Private)
|
|
{
|
|
d->relation = RelAnd;
|
|
d->key = key;
|
|
d->value = value;
|
|
d->condition = condition;
|
|
}
|
|
|
|
SearchTerm::SearchTerm(const SearchTerm &other)
|
|
: d(other.d)
|
|
{
|
|
}
|
|
|
|
SearchTerm::~SearchTerm()
|
|
{
|
|
}
|
|
|
|
SearchTerm &SearchTerm::operator=(const SearchTerm &other)
|
|
{
|
|
d = other.d;
|
|
return *this;
|
|
}
|
|
|
|
bool SearchTerm::operator==(const SearchTerm &other) const
|
|
{
|
|
return *d == *other.d;
|
|
}
|
|
|
|
bool SearchTerm::isNull() const
|
|
{
|
|
return d->key.isEmpty() && d->value.isNull() && d->terms.isEmpty();
|
|
}
|
|
|
|
QString SearchTerm::key() const
|
|
{
|
|
return d->key;
|
|
}
|
|
|
|
QVariant SearchTerm::value() const
|
|
{
|
|
return d->value;
|
|
}
|
|
|
|
SearchTerm::Condition SearchTerm::condition() const
|
|
{
|
|
return d->condition;
|
|
}
|
|
|
|
void SearchTerm::setIsNegated(bool negated)
|
|
{
|
|
d->isNegated = negated;
|
|
}
|
|
|
|
bool SearchTerm::isNegated() const
|
|
{
|
|
return d->isNegated;
|
|
}
|
|
|
|
void SearchTerm::addSubTerm(const SearchTerm &term)
|
|
{
|
|
d->terms << term;
|
|
}
|
|
|
|
QList< SearchTerm > SearchTerm::subTerms() const
|
|
{
|
|
return d->terms;
|
|
}
|
|
|
|
SearchTerm::Relation SearchTerm::relation() const
|
|
{
|
|
return d->relation;
|
|
}
|
|
|
|
SearchQuery::SearchQuery(SearchTerm::Relation rel)
|
|
: d(new Private)
|
|
{
|
|
d->rootTerm = SearchTerm(rel);
|
|
}
|
|
|
|
SearchQuery::SearchQuery(const SearchQuery &other)
|
|
: d(other.d)
|
|
{
|
|
}
|
|
|
|
SearchQuery::~SearchQuery()
|
|
{
|
|
}
|
|
|
|
SearchQuery &SearchQuery::operator=(const SearchQuery &other)
|
|
{
|
|
d = other.d;
|
|
return *this;
|
|
}
|
|
|
|
bool SearchQuery::operator==(const SearchQuery &other) const
|
|
{
|
|
return *d == *other.d;
|
|
}
|
|
|
|
bool SearchQuery::isNull() const
|
|
{
|
|
return d->rootTerm.isNull();
|
|
}
|
|
|
|
SearchTerm SearchQuery::term() const
|
|
{
|
|
return d->rootTerm;
|
|
}
|
|
|
|
void SearchQuery::addTerm(const QString &key, const QVariant &value, SearchTerm::Condition condition)
|
|
{
|
|
addTerm(SearchTerm(key, value, condition));
|
|
}
|
|
|
|
void SearchQuery::addTerm(const SearchTerm &term)
|
|
{
|
|
d->rootTerm.addSubTerm(term);
|
|
}
|
|
|
|
void SearchQuery::setTerm(const SearchTerm &term)
|
|
{
|
|
d->rootTerm = term;
|
|
}
|
|
|
|
void SearchQuery::setLimit(int limit)
|
|
{
|
|
d->limit = limit;
|
|
}
|
|
|
|
int SearchQuery::limit() const
|
|
{
|
|
return d->limit;
|
|
}
|
|
|
|
QByteArray SearchQuery::toJSON() const
|
|
{
|
|
QVariantMap root = Private::termToJSON(d->rootTerm);
|
|
root.insert(QLatin1String("limit"), d->limit);
|
|
|
|
QJson::Serializer serializer;
|
|
return serializer.serialize(root);
|
|
}
|
|
|
|
SearchQuery SearchQuery::fromJSON(const QByteArray &jsonData)
|
|
{
|
|
QJson::Parser parser;
|
|
bool ok = false;
|
|
const QVariant json = parser.parse(jsonData, &ok);
|
|
if (!ok || json.isNull()) {
|
|
return SearchQuery();
|
|
}
|
|
|
|
const QVariantMap map = json.toMap();
|
|
SearchQuery query;
|
|
query.d->rootTerm = Private::JSONToTerm(map);
|
|
if (map.contains(QLatin1String("limit"))) {
|
|
query.d->limit = map.value(QLatin1String("limit")).toInt();
|
|
}
|
|
return query;
|
|
}
|
|
|
|
QMap<EmailSearchTerm::EmailSearchField, QString> initializeMapping()
|
|
{
|
|
QMap<EmailSearchTerm::EmailSearchField, QString> mapping;
|
|
mapping.insert(EmailSearchTerm::Body, QLatin1String("body"));
|
|
mapping.insert(EmailSearchTerm::Headers, QLatin1String("headers"));
|
|
mapping.insert(EmailSearchTerm::Subject, QLatin1String("subject"));
|
|
mapping.insert(EmailSearchTerm::Message, QLatin1String("message"));
|
|
mapping.insert(EmailSearchTerm::HeaderFrom, QLatin1String("from"));
|
|
mapping.insert(EmailSearchTerm::HeaderTo, QLatin1String("to"));
|
|
mapping.insert(EmailSearchTerm::HeaderCC, QLatin1String("cc"));
|
|
mapping.insert(EmailSearchTerm::HeaderBCC, QLatin1String("bcc"));
|
|
mapping.insert(EmailSearchTerm::HeaderReplyTo, QLatin1String("replyto"));
|
|
mapping.insert(EmailSearchTerm::HeaderOrganization, QLatin1String("organization"));
|
|
mapping.insert(EmailSearchTerm::HeaderListId, QLatin1String("listid"));
|
|
mapping.insert(EmailSearchTerm::HeaderResentFrom, QLatin1String("resentfrom"));
|
|
mapping.insert(EmailSearchTerm::HeaderXLoop, QLatin1String("xloop"));
|
|
mapping.insert(EmailSearchTerm::HeaderXMailingList, QLatin1String("xmailinglist"));
|
|
mapping.insert(EmailSearchTerm::HeaderXSpamFlag, QLatin1String("xspamflag"));
|
|
mapping.insert(EmailSearchTerm::HeaderDate, QLatin1String("date"));
|
|
mapping.insert(EmailSearchTerm::HeaderOnlyDate, QLatin1String("onlydate"));
|
|
mapping.insert(EmailSearchTerm::MessageStatus, QLatin1String("messagestatus"));
|
|
mapping.insert(EmailSearchTerm::MessageTag, QLatin1String("messagetag"));
|
|
mapping.insert(EmailSearchTerm::ByteSize, QLatin1String("size"));
|
|
mapping.insert(EmailSearchTerm::Attachment, QLatin1String("attachment"));
|
|
return mapping;
|
|
}
|
|
|
|
static QMap<EmailSearchTerm::EmailSearchField, QString> emailSearchFieldMapping = initializeMapping();
|
|
|
|
EmailSearchTerm::EmailSearchTerm(EmailSearchTerm::EmailSearchField field, const QVariant &value, SearchTerm::Condition condition)
|
|
: SearchTerm(toKey(field), value, condition)
|
|
{
|
|
|
|
}
|
|
|
|
QString EmailSearchTerm::toKey(EmailSearchTerm::EmailSearchField field)
|
|
{
|
|
return emailSearchFieldMapping.value(field);
|
|
}
|
|
|
|
EmailSearchTerm::EmailSearchField EmailSearchTerm::fromKey(const QString &key)
|
|
{
|
|
return emailSearchFieldMapping.key(key);
|
|
}
|
|
|
|
QMap<ContactSearchTerm::ContactSearchField, QString> initializeContactMapping()
|
|
{
|
|
QMap<ContactSearchTerm::ContactSearchField, QString> mapping;
|
|
mapping.insert(ContactSearchTerm::Name, QLatin1String("name"));
|
|
mapping.insert(ContactSearchTerm::Nickname, QLatin1String("nickname"));
|
|
mapping.insert(ContactSearchTerm::Email, QLatin1String("email"));
|
|
mapping.insert(ContactSearchTerm::Uid, QLatin1String("uid"));
|
|
mapping.insert(ContactSearchTerm::All, QLatin1String("all"));
|
|
return mapping;
|
|
}
|
|
|
|
static QMap<ContactSearchTerm::ContactSearchField, QString> contactSearchFieldMapping = initializeContactMapping();
|
|
|
|
ContactSearchTerm::ContactSearchTerm(ContactSearchTerm::ContactSearchField field, const QVariant &value, SearchTerm::Condition condition)
|
|
: SearchTerm(toKey(field), value, condition)
|
|
{
|
|
|
|
}
|
|
|
|
QString ContactSearchTerm::toKey(ContactSearchTerm::ContactSearchField field)
|
|
{
|
|
return contactSearchFieldMapping.value(field);
|
|
}
|
|
|
|
ContactSearchTerm::ContactSearchField ContactSearchTerm::fromKey(const QString &key)
|
|
{
|
|
return contactSearchFieldMapping.key(key);
|
|
}
|