/* -*- c++ -*- * * searchquery.cpp * * Copyright (C) 2003-2004 Petter E. Stokke * Copyright (C) 2003-2004 Sebastian Sauer * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include "searchquery.h" #include "donkeymessage.h" #include #include /*** SearchQuery ***/ SearchQuery::SearchQuery(Operation op) { setOperation(op); } SearchQuery::~SearchQuery() { } SearchQuery::Operation SearchQuery::operation() { return Op; } void SearchQuery::setOperation(Operation op) { Op = op; } const QString SearchQuery::getQuerystring() { kdDebug() << "SearchQuery::getQuerystring() NOT IMPLEMENTATED !!!" << endl; return QString::null; } void SearchQuery::writeQuery(DonkeyMessage& msg) { msg.writeInt8((int8)Op); } SearchQuery* SearchQuery::getQuery(DonkeyMessage* msg) { int op = msg->readInt8(); switch (op) { case And: { QueryAnd* q = new QueryAnd(); int i, j = msg->readInt16(); for (i=0; iappend( getQuery(msg) ); return q; } break; case Or: { QueryOr* q = new QueryOr(); int i, j = msg->readInt16(); for (i=0; iappend( getQuery(msg) ); return q; } break; case Hidden: { QueryHidden* q = new QueryHidden(); int i, j = msg->readInt16(); for (i=0; iappend( getQuery(msg) ); return q; } break; case AndNot: { return new QueryAndNot(getQuery(msg), getQuery(msg)); } break; case Module: { QString s = msg->readString(); SearchQuery* q = getQuery(msg); return new QueryModule(s, q); } break; case Keywords: { return new QueryKeywords(msg->readString(), msg->readString()); } break; case MinSize: { return new QueryMinSize(msg->readString(), msg->readString()); } break; case MaxSize: { return new QueryMaxSize(msg->readString(), msg->readString()); } break; case Format: { return new QueryFormat(msg->readString(), msg->readString()); } break; case Media: { return new QueryMedia(msg->readString(), msg->readString()); } break; case Mp3Artist: { return new QueryMp3Artist(msg->readString(), msg->readString()); } break; case Mp3Title: { return new QueryMp3Title(msg->readString(), msg->readString()); } break; case Mp3Album: { return new QueryMp3Album(msg->readString(), msg->readString()); } break; case Mp3Bitrate: { return new QueryMp3Bitrate(msg->readString(), msg->readString()); } break; default: { return 0; } break; } } SearchQuery* SearchQuery::getQuery(const QString& querystring) { // First seek for SearchQueryList's QRegExp rxlist("(\\(.*\\))[\\s]*(AND|AND[\\s]*NOT|OR)[\\s]*(\\(.*\\))"); int pos = rxlist.search(querystring); if(pos >= 0) { QString op = rxlist.cap(2).stripWhiteSpace().simplifyWhiteSpace(); if(op == "AND") { QueryAnd* q = new QueryAnd(); q->append( getQuery(rxlist.cap(1)) ); q->append( getQuery(rxlist.cap(3)) ); return q; } if(op == "OR") { QueryOr* q = new QueryOr(); q->append( getQuery(rxlist.cap(1)) ); q->append( getQuery(rxlist.cap(3)) ); return q; } if(op == "AND NOT") return new QueryAndNot(getQuery(rxlist.cap(1)), getQuery(rxlist.cap(3))); kdDebug() << "SearchQuery::getQuery() Unknown list-operator " << op << " in " << querystring << endl; return 0; } // Clean the querystring QRegExp rxq("^[\\s]*[\\(]+(.*)[\\)]+[\\s]*$"); QString qs = (rxq.search(querystring) >= 0) ? rxq.cap(1) : querystring; // Look for [...]>0 or [...]<0 QRegExp rx1("\\[(.*)\\][\\s]*(>|<)[\\s]*\\[([0-9]+)\\]"); if(rx1.search(qs) >= 0) { QString op = rx1.cap(1).stripWhiteSpace(); if(op == "size") { QString sizeop = rx1.cap(2).stripWhiteSpace(); if(sizeop == ">") return new QueryMinSize(QString::null, rx1.cap(3)); else if(sizeop == "<") return new QueryMaxSize(QString::null, rx1.cap(3)); else kdDebug() << "SearchQuery::getQuery() Unknown size-operator " << sizeop << " in " << qs << endl; } if(op == "bitrate") return new QueryMp3Bitrate(QString::null, rx1.cap(3)); kdDebug() << "SearchQuery::getQuery() Unknown integer-operator " << op << " in " << qs << endl; return 0; } // look for [...]CONTAINS[...] QRegExp rx2("\\[(.*)\\][\\s]*CONTAINS[\\s]*\\[(.*)\\]"); if(rx2.search(qs) >= 0) { QString op = rx2.cap(1).stripWhiteSpace(); if(op == "format") return new QueryFormat(QString::null, rx2.cap(2)); if(op == "type") return new QueryMedia(QString::null, rx2.cap(2)); if(op == "artist") return new QueryMp3Artist(QString::null, rx2.cap(2)); if(op == "album") return new QueryMp3Album(QString::null, rx2.cap(2)); if(op == "title") return new QueryMp3Title(QString::null, rx2.cap(2)); kdDebug() << "SearchQuery::getQuery() Unknown contains-operator " << op << " in " << qs << endl; return 0; } // and finally look for CONTAINS[...] QRegExp rx3("CONTAINS[\\s]*\\[(.*)\\]"); if(rx3.search(qs) >= 0) return new QueryKeywords(QString::null, rx3.cap(1)); kdDebug() << "SearchQuery::getQuery() Unknown querystring " << qs << endl; return 0; } /*** SearchQueryList ***/ SearchQueryList::SearchQueryList(Operation op) : SearchQuery(op) { queryList.setAutoDelete(true); } SearchQueryList* SearchQueryList::append(SearchQuery* q) { queryList.append(q); return this; } uint SearchQueryList::count() { return queryList.count(); } SearchQuery* SearchQueryList::at(uint index) { return queryList.at(index); } SearchQuery* SearchQueryList::take(uint index) { return queryList.take(index); } const QString SearchQueryList::getQuerystring() { kdDebug() << "SearchQueryList::getQuerystring() NOT IMPLEMENTATED !!!" << endl; return QString::null; } const QString SearchQueryList::toQueryString(const QString& joinstr) { QString qs = QString::null; QPtrListIterator it(queryList); SearchQuery* q; while ((q = it.current()) != 0) { ++it; if(! qs.isEmpty()) qs += " " + joinstr + " "; qs += "(" + q->getQuerystring() + ")"; } return qs; } void SearchQueryList::writeQuery(DonkeyMessage& msg) { SearchQuery::writeQuery(msg); msg.writeInt16((int16)queryList.count()); QPtrListIterator it(queryList); SearchQuery* q; while ((q = it.current()) != 0) { ++it; q->writeQuery(msg); } } /*** QueryAnd ***/ QueryAnd::QueryAnd() : SearchQueryList(SearchQuery::And) { } const QString QueryAnd::getQuerystring() { return toQueryString("AND"); } /*** QueryOr ***/ QueryOr::QueryOr() : SearchQueryList(SearchQuery::Or) { } const QString QueryOr::getQuerystring() { return toQueryString("OR"); } /*** QueryHidden ***/ QueryHidden::QueryHidden() : SearchQueryList(SearchQuery::Hidden) { } const QString QueryHidden::getQuerystring() { return toQueryString("HIDDEN"); } /*** QueryAndNot ***/ QueryAndNot::QueryAndNot(SearchQuery* q1, SearchQuery* q2) : SearchQuery(SearchQuery::AndNot) { query1 = q1; query2 = q2; } QueryAndNot::~QueryAndNot() { delete query1; delete query2; } const QString QueryAndNot::getQuerystring() { return "(" + query1->getQuerystring() + ") AND NOT (" + query2->getQuerystring() + ")"; } void QueryAndNot::writeQuery(DonkeyMessage& msg) { SearchQuery::writeQuery(msg); query1->writeQuery(msg); query2->writeQuery(msg); } /*** QueryModule ***/ QueryModule::QueryModule(QString str, SearchQuery* q) : SearchQuery(SearchQuery::Module) , string(str) { query = q; } QueryModule::~QueryModule() { delete query; } const QString QueryModule::getQuerystring() { return query->getQuerystring(); } void QueryModule::writeQuery(DonkeyMessage& msg) { SearchQuery::writeQuery(msg); msg.writeString(string); query->writeQuery(msg); } /*** SearchQueryTwoStrings ***/ SearchQueryTwoStrings::SearchQueryTwoStrings(Operation op, QString str1, QString str2) : SearchQuery(op) , s1(str1) , s2(str2) { } const QString SearchQueryTwoStrings::getQuerystring() { kdDebug() << "SearchQueryTwoStrings::getQuerystring() NOT IMPLEMENTATED !!!" << endl; return QString::null; } void SearchQueryTwoStrings::writeQuery(DonkeyMessage& msg) { SearchQuery::writeQuery(msg); msg.writeString(s1); msg.writeString(s2); } /*** QueryKeywords ***/ QueryKeywords::QueryKeywords(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Keywords, s1, s2) { } const QString QueryKeywords::getQuerystring() { return "CONTAINS[" + s2 + "]"; } /*** QueryMinSize ***/ QueryMinSize::QueryMinSize(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::MinSize, s1, s2) { } const QString QueryMinSize::getQuerystring() { return "[size]>[" + s2 + "]"; } /*** QueryMaxSize ***/ QueryMaxSize::QueryMaxSize(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::MaxSize, s1, s2) { } const QString QueryMaxSize::getQuerystring() { return "[size]<[" + s2 + "]"; } /*** QueryFormat ***/ QueryFormat::QueryFormat(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Format, s1, s2) { } const QString QueryFormat::getQuerystring() { return "[format]CONTAINS[" + s2 + "]"; } /*** QueryMedia ***/ QueryMedia::QueryMedia(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Media, s1, s2) { } const QString QueryMedia::getQuerystring() { return "[type]CONTAINS[" + s2 + "]"; } /*** QueryMp3Artist ***/ QueryMp3Artist::QueryMp3Artist(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Mp3Artist, s1, s2) { } const QString QueryMp3Artist::getQuerystring() { return "[artist]CONTAINS[" + s2 + "]"; } /*** QueryMp3Title ***/ QueryMp3Title::QueryMp3Title(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Mp3Title, s1, s2) { } const QString QueryMp3Title::getQuerystring() { return "[title]CONTAINS[" + s2 + "]"; } /*** QueryMp3Album ***/ QueryMp3Album::QueryMp3Album(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Mp3Album, s1, s2) { } const QString QueryMp3Album::getQuerystring() { return "[album]CONTAINS[" + s2 + "]"; } /*** QueryMp3Bitrate ***/ QueryMp3Bitrate::QueryMp3Bitrate(QString s1, QString s2) : SearchQueryTwoStrings(SearchQuery::Mp3Bitrate, s1, s2) { } const QString QueryMp3Bitrate::getQuerystring() { return "[bitrate]>[" + s2 + "]"; }