KIMAP Library
searchjob.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "searchjob.h"
00021
00022 #include <KDE/KLocale>
00023 #include <KDE/KDebug>
00024
00025 #include <QtCore/QDate>
00026
00027 #include "job_p.h"
00028 #include "message_p.h"
00029 #include "session_p.h"
00030
00031
00032
00033 namespace KIMAP
00034 {
00035 class SearchJobPrivate : public JobPrivate
00036 {
00037 public:
00038 SearchJobPrivate( Session *session, const QString& name ) : JobPrivate(session, name), logic(SearchJob::And) {
00039 criteriaMap[SearchJob::All] = "ALL";
00040 criteriaMap[SearchJob::Answered] = "ANSWERED";
00041 criteriaMap[SearchJob::BCC] = "BCC";
00042 criteriaMap[SearchJob::Before] = "BEFORE";
00043 criteriaMap[SearchJob::Body] = "BODY";
00044 criteriaMap[SearchJob::CC] = "CC";
00045 criteriaMap[SearchJob::Deleted] = "DELETED";
00046 criteriaMap[SearchJob::Draft] = "DRAFT";
00047 criteriaMap[SearchJob::Flagged] = "FLAGGED";
00048 criteriaMap[SearchJob::From] = "FROM";
00049 criteriaMap[SearchJob::Header] = "HEADER";
00050 criteriaMap[SearchJob::Keyword] = "KEYWORD";
00051 criteriaMap[SearchJob::Larger] = "LARGER";
00052 criteriaMap[SearchJob::New] = "NEW";
00053 criteriaMap[SearchJob::Old] = "OLD";
00054 criteriaMap[SearchJob::On] = "ON";
00055 criteriaMap[SearchJob::Recent] = "RECENT";
00056 criteriaMap[SearchJob::Seen] = "SEEN";
00057 criteriaMap[SearchJob::SentBefore] = "SENTBEFORE";
00058 criteriaMap[SearchJob::SentOn] = "SENTON";
00059 criteriaMap[SearchJob::SentSince] = "SENTSINCE";
00060 criteriaMap[SearchJob::Since] = "SINCE";
00061 criteriaMap[SearchJob::Smaller] = "SMALLER";
00062 criteriaMap[SearchJob::Subject] = "SUBJECT";
00063 criteriaMap[SearchJob::Text] = "TEXT";
00064 criteriaMap[SearchJob::To] = "TO";
00065 criteriaMap[SearchJob::Uid] = "UID";
00066 criteriaMap[SearchJob::Unanswered] = "UNANSWERED";
00067 criteriaMap[SearchJob::Undeleted] = "UNDELETED";
00068 criteriaMap[SearchJob::Undraft] = "UNDRAFT";
00069 criteriaMap[SearchJob::Unflagged] = "UNFLAGGED";
00070 criteriaMap[SearchJob::Unkeyword] = "UNKEYWORD";
00071 criteriaMap[SearchJob::Unseen] = "UNSEEN";
00072
00073
00074 months[1] = "Jan";
00075 months[2] = "Feb";
00076 months[3] = "Mar";
00077 months[4] = "Apr";
00078 months[5] = "May";
00079 months[6] = "Jun";
00080 months[7] = "Jul";
00081 months[8] = "Aug";
00082 months[9] = "Sep";
00083 months[10] = "Oct";
00084 months[11] = "Nov";
00085 months[12] = "Dec";
00086
00087 nextContent = 0;
00088 uidBased = false;
00089 }
00090 ~SearchJobPrivate() { }
00091
00092
00093 QByteArray charset;
00094 QList<QByteArray> criterias;
00095 QMap<SearchJob::SearchCriteria, QByteArray > criteriaMap;
00096 QMap<int, QByteArray> months;
00097 SearchJob::SearchLogic logic;
00098 QList<QByteArray> contents;
00099 QList<int> results;
00100 uint nextContent;
00101 bool uidBased;
00102 };
00103 }
00104
00105 using namespace KIMAP;
00106
00107 SearchJob::SearchJob( Session *session )
00108 : Job( *new SearchJobPrivate(session, i18n("Search")) )
00109 {
00110 }
00111
00112 SearchJob::~SearchJob()
00113 {
00114 }
00115
00116 void SearchJob::doStart()
00117 {
00118 Q_D(SearchJob);
00119
00120 QByteArray searchKey;
00121
00122 if (!d->charset.isEmpty()) {
00123 searchKey = "[CHARSET] " + d->charset;
00124 }
00125
00126 if (d->logic == SearchJob::Not) {
00127 searchKey += "NOT";
00128 } else if (d->logic == SearchJob::Or) {
00129 searchKey += "OR";
00130 }
00131 Q_FOREACH(QByteArray key, d->criterias) {
00132 searchKey += " (" + key + ")";
00133 }
00134
00135 QByteArray command = "SEARCH";
00136 if ( d->uidBased ) {
00137 command = "UID "+ command;
00138 }
00139
00140 d->tag = d->sessionInternal()->sendCommand( command, searchKey );
00141 }
00142
00143 void SearchJob::handleResponse( const Message &response )
00144 {
00145 Q_D(SearchJob);
00146
00147 if (handleErrorReplies(response) == NotHandled ) {
00148 if ( response.content[0].toString() == "+" ) {
00149 d->sessionInternal()->sendData( d->contents[d->nextContent] );
00150 d->nextContent++;
00151 } else if ( response.content[1].toString() == "SEARCH" ) {
00152 for(int i = 2; i < response.content.size(); i++) {
00153 d->results.append(response.content[i].toString().toInt());
00154 }
00155 }
00156 }
00157 }
00158
00159
00160 void SearchJob::setCharset( const QByteArray &charset )
00161 {
00162 Q_D(SearchJob);
00163 d->charset = charset;
00164 }
00165
00166 QByteArray SearchJob::charset() const
00167 {
00168 Q_D(const SearchJob);
00169 return d->charset;
00170 }
00171
00172 void SearchJob::setSearchLogic( SearchLogic logic )
00173 {
00174 Q_D(SearchJob);
00175 d->logic = logic;
00176 }
00177
00178 void SearchJob::addSearchCriteria( SearchCriteria criteria )
00179 {
00180 Q_D(SearchJob);
00181
00182 switch (criteria) {
00183 case All:
00184 case Answered:
00185 case Deleted:
00186 case Draft:
00187 case Flagged:
00188 case New:
00189 case Old:
00190 case Recent:
00191 case Seen:
00192 case Unanswered:
00193 case Undeleted:
00194 case Undraft:
00195 case Unflagged:
00196 case Unseen:
00197 d->criterias.append(d->criteriaMap[criteria]);
00198 break;
00199 default:
00200
00201 kDebug() << "Criteria " << d->criteriaMap[criteria] << " needs an argument, but none was specified.";
00202 break;
00203 }
00204 }
00205
00206
00207 void SearchJob::addSearchCriteria( SearchCriteria criteria, int argument )
00208 {
00209 Q_D(SearchJob);
00210 switch (criteria) {
00211 case Larger:
00212 case Smaller:
00213 d->criterias.append(d->criteriaMap[criteria] + " " + QByteArray::number(argument));
00214 break;
00215 default:
00216
00217 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept an integer as an argument.";
00218 break;
00219 }
00220 }
00221
00222
00223 void SearchJob::addSearchCriteria( SearchCriteria criteria, const QByteArray &argument )
00224 {
00225 Q_D(SearchJob);
00226 switch (criteria) {
00227 case BCC:
00228 case Body:
00229 case CC:
00230 case From:
00231 case Subject:
00232 case Text:
00233 case To:
00234 d->contents.append(argument);
00235 d->criterias.append(d->criteriaMap[criteria] + " {" + QByteArray::number(argument.size()) + '}');
00236 break;
00237 case Keyword:
00238 case Unkeyword:
00239 d->criterias.append(d->criteriaMap[criteria] + ' ' + argument);
00240 break;
00241 case Header: {
00242 int pos = argument.indexOf(' ');
00243 QByteArray fieldName = argument.left(pos);
00244 QByteArray content = argument.mid(pos + 1);
00245 d->contents.append(content);
00246 d->criterias.append(d->criteriaMap[criteria] + ' ' + fieldName + " {" + QByteArray::number(content.size()) + '}');
00247 break;
00248 }
00249 default:
00250
00251 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept any argument.";
00252 break;
00253 }
00254 }
00255
00256 void SearchJob::addSearchCriteria( SearchCriteria criteria, const QDate &argument )
00257 {
00258 Q_D(SearchJob);
00259 switch (criteria) {
00260 case Before:
00261 case On:
00262 case SentBefore:
00263 case SentSince:
00264 case Since: {
00265 QByteArray date = QByteArray::number(argument.day()) + '-';
00266 date += d->months[argument.month()] + '-';
00267 date += QByteArray::number(argument.year());
00268 d->criterias.append(d->criteriaMap[criteria] + " \"" + date + '\"');
00269 break;
00270 }
00271 default:
00272
00273 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept a date as argument.";
00274 break;
00275 }
00276 }
00277
00278 void SearchJob::addSearchCriteria( const QByteArray &searchCriteria )
00279 {
00280 Q_D(SearchJob);
00281 d->criterias.append(searchCriteria);
00282 }
00283
00284 void SearchJob::setUidBased(bool uidBased)
00285 {
00286 Q_D(SearchJob);
00287 d->uidBased = uidBased;
00288 }
00289
00290 bool SearchJob::isUidBased() const
00291 {
00292 Q_D(const SearchJob);
00293 return d->uidBased;
00294 }
00295
00296 QList<int> SearchJob::foundItems()
00297 {
00298 Q_D(const SearchJob);
00299 return d->results;
00300 }
00301 #include "searchjob.moc"