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<qint64> 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, i18nc("Name of the search job", "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
00132 if ( d->logic == SearchJob::And ) {
00133 for ( int i = 0; i<d->criterias.size(); i++ ) {
00134 const QByteArray key = d->criterias.at( i );
00135 if ( i>0 ) searchKey+= ' ';
00136 searchKey += key;
00137 }
00138 } else {
00139 for ( int i = 0; i<d->criterias.size(); i++ ) {
00140 const QByteArray key = d->criterias.at( i );
00141 if ( i>0 ) searchKey+= ' ';
00142 searchKey += '(' + key + ')';
00143 }
00144 }
00145
00146 QByteArray command = "SEARCH";
00147 if ( d->uidBased ) {
00148 command = "UID "+ command;
00149 }
00150
00151 d->tags << d->sessionInternal()->sendCommand( command, searchKey );
00152 }
00153
00154 void SearchJob::handleResponse( const Message &response )
00155 {
00156 Q_D(SearchJob);
00157
00158 if (handleErrorReplies(response) == NotHandled ) {
00159 if ( response.content[0].toString() == "+" ) {
00160 d->sessionInternal()->sendData( d->contents[d->nextContent] );
00161 d->nextContent++;
00162 } else if ( response.content[1].toString() == "SEARCH" ) {
00163 for(int i = 2; i < response.content.size(); i++) {
00164 d->results.append(response.content[i].toString().toInt());
00165 }
00166 }
00167 }
00168 }
00169
00170
00171 void SearchJob::setCharset( const QByteArray &charset )
00172 {
00173 Q_D(SearchJob);
00174 d->charset = charset;
00175 }
00176
00177 QByteArray SearchJob::charset() const
00178 {
00179 Q_D(const SearchJob);
00180 return d->charset;
00181 }
00182
00183 void SearchJob::setSearchLogic( SearchLogic logic )
00184 {
00185 Q_D(SearchJob);
00186 d->logic = logic;
00187 }
00188
00189 void SearchJob::addSearchCriteria( SearchCriteria criteria )
00190 {
00191 Q_D(SearchJob);
00192
00193 switch (criteria) {
00194 case All:
00195 case Answered:
00196 case Deleted:
00197 case Draft:
00198 case Flagged:
00199 case New:
00200 case Old:
00201 case Recent:
00202 case Seen:
00203 case Unanswered:
00204 case Undeleted:
00205 case Undraft:
00206 case Unflagged:
00207 case Unseen:
00208 d->criterias.append(d->criteriaMap[criteria]);
00209 break;
00210 default:
00211
00212 kDebug() << "Criteria " << d->criteriaMap[criteria] << " needs an argument, but none was specified.";
00213 break;
00214 }
00215 }
00216
00217
00218 void SearchJob::addSearchCriteria( SearchCriteria criteria, int argument )
00219 {
00220 Q_D(SearchJob);
00221 switch (criteria) {
00222 case Larger:
00223 case Smaller:
00224 d->criterias.append(d->criteriaMap[criteria] + ' ' + QByteArray::number(argument));
00225 break;
00226 default:
00227
00228 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept an integer as an argument.";
00229 break;
00230 }
00231 }
00232
00233
00234 void SearchJob::addSearchCriteria( SearchCriteria criteria, const QByteArray &argument )
00235 {
00236 Q_D(SearchJob);
00237 switch (criteria) {
00238 case BCC:
00239 case Body:
00240 case CC:
00241 case From:
00242 case Subject:
00243 case Text:
00244 case To:
00245 d->contents.append(argument);
00246 d->criterias.append(d->criteriaMap[criteria] + " {" + QByteArray::number(argument.size()) + '}');
00247 break;
00248 case Keyword:
00249 case Unkeyword:
00250 case Header:
00251 case Uid:
00252 d->criterias.append(d->criteriaMap[criteria] + ' ' + argument);
00253 break;
00254 default:
00255
00256 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept any argument.";
00257 break;
00258 }
00259 }
00260
00261 void SearchJob::addSearchCriteria( SearchCriteria criteria, const QDate &argument )
00262 {
00263 Q_D(SearchJob);
00264 switch (criteria) {
00265 case Before:
00266 case On:
00267 case SentBefore:
00268 case SentSince:
00269 case Since: {
00270 QByteArray date = QByteArray::number(argument.day()) + '-';
00271 date += d->months[argument.month()] + '-';
00272 date += QByteArray::number(argument.year());
00273 d->criterias.append(d->criteriaMap[criteria] + " \"" + date + '\"');
00274 break;
00275 }
00276 default:
00277
00278 kDebug() << "Criteria " << d->criteriaMap[criteria] << " doesn't accept a date as argument.";
00279 break;
00280 }
00281 }
00282
00283 void SearchJob::addSearchCriteria( const QByteArray &searchCriteria )
00284 {
00285 Q_D(SearchJob);
00286 d->criterias.append(searchCriteria);
00287 }
00288
00289 void SearchJob::setUidBased(bool uidBased)
00290 {
00291 Q_D(SearchJob);
00292 d->uidBased = uidBased;
00293 }
00294
00295 bool SearchJob::isUidBased() const
00296 {
00297 Q_D(const SearchJob);
00298 return d->uidBased;
00299 }
00300
00301 QList<qint64> SearchJob::results() const
00302 {
00303 Q_D(const SearchJob);
00304 return d->results;
00305 }
00306
00307 QList<int> SearchJob::foundItems()
00308 {
00309 Q_D(const SearchJob);
00310
00311 QList<int> results;
00312 qCopy( d->results.begin(), d->results.end(), results.begin() );
00313
00314 return results;
00315 }
00316
00317 #include "searchjob.moc"