KIMAP Library
listjob.cpp
00001 /* 00002 Copyright (c) 2009 Kevin Ottens <ervin@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "listjob.h" 00021 00022 #include <QtCore/QTimer> 00023 #include <KDE/KLocale> 00024 00025 #include "job_p.h" 00026 #include "message_p.h" 00027 #include "rfccodecs.h" 00028 #include "session_p.h" 00029 00030 namespace KIMAP 00031 { 00032 class ListJobPrivate : public JobPrivate 00033 { 00034 public: 00035 ListJobPrivate( ListJob *job, Session *session, const QString& name ) : JobPrivate(session, name), q(job), includeUnsubscribed(false) { } 00036 ~ListJobPrivate() { } 00037 00038 void emitPendings() 00039 { 00040 if ( pendingDescriptors.isEmpty() ) { 00041 return; 00042 } 00043 00044 emit q->mailBoxesReceived( pendingDescriptors, pendingFlags ); 00045 00046 pendingDescriptors.clear(); 00047 pendingFlags.clear(); 00048 } 00049 00050 ListJob * const q; 00051 00052 bool includeUnsubscribed; 00053 QList<MailBoxDescriptor> namespaces; 00054 QByteArray command; 00055 00056 QTimer emitPendingsTimer; 00057 QList<MailBoxDescriptor> pendingDescriptors; 00058 QList< QList<QByteArray> > pendingFlags; 00059 }; 00060 } 00061 00062 using namespace KIMAP; 00063 00064 ListJob::ListJob( Session *session ) 00065 : Job( *new ListJobPrivate(this, session, i18n("List")) ) 00066 { 00067 Q_D(ListJob); 00068 connect( &d->emitPendingsTimer, SIGNAL( timeout() ), 00069 this, SLOT( emitPendings() ) ); 00070 } 00071 00072 ListJob::~ListJob() 00073 { 00074 } 00075 00076 void ListJob::setIncludeUnsubscribed( bool include ) 00077 { 00078 Q_D(ListJob); 00079 d->includeUnsubscribed = include; 00080 } 00081 00082 bool ListJob::isIncludeUnsubscribed() const 00083 { 00084 Q_D(const ListJob); 00085 return d->includeUnsubscribed; 00086 } 00087 00088 void ListJob::setQueriedNamespaces( const QList<MailBoxDescriptor> &namespaces ) 00089 { 00090 Q_D(ListJob); 00091 d->namespaces = namespaces; 00092 } 00093 00094 QList<MailBoxDescriptor> ListJob::queriedNamespaces() const 00095 { 00096 Q_D(const ListJob); 00097 return d->namespaces; 00098 } 00099 00100 QList<MailBoxDescriptor> ListJob::mailBoxes() const 00101 { 00102 return QList<MailBoxDescriptor>(); 00103 } 00104 00105 QMap< MailBoxDescriptor, QList<QByteArray> > ListJob::flags() const 00106 { 00107 return QMap< MailBoxDescriptor, QList<QByteArray> >(); 00108 } 00109 00110 void ListJob::doStart() 00111 { 00112 Q_D(ListJob); 00113 00114 d->command = "LSUB"; 00115 if (d->includeUnsubscribed) { 00116 d->command = "LIST"; 00117 } 00118 00119 d->emitPendingsTimer.start( 100 ); 00120 00121 if ( d->namespaces.isEmpty() ) { 00122 d->tags << d->sessionInternal()->sendCommand( d->command, "\"\" *" ); 00123 } else { 00124 foreach ( const MailBoxDescriptor &descriptor, d->namespaces ) { 00125 QString parameters = "\"\" \"%1\""; 00126 00127 if ( descriptor.name.endsWith( descriptor.separator ) ) { 00128 QString name = encodeImapFolderName( descriptor.name ); 00129 name.chop( 1 ); 00130 d->tags << d->sessionInternal()->sendCommand( d->command, 00131 parameters.arg( name ).toUtf8() ); 00132 } 00133 00134 d->tags << d->sessionInternal()->sendCommand( d->command, 00135 parameters.arg( descriptor.name+'*' ).toUtf8() ); 00136 } 00137 } 00138 } 00139 00140 void ListJob::handleResponse( const Message &response ) 00141 { 00142 Q_D(ListJob); 00143 00144 // We can predict it'll be handled by handleErrorReplies() so stop 00145 // the timer now so that result() will really be the last emitted signal. 00146 if ( !response.content.isEmpty() 00147 && d->tags.size() == 1 00148 && d->tags.contains( response.content.first().toString() ) ) { 00149 d->emitPendingsTimer.stop(); 00150 d->emitPendings(); 00151 } 00152 00153 if ( handleErrorReplies( response ) == NotHandled ) { 00154 if ( response.content.size() >= 5 && response.content[1].toString() == d->command ) { 00155 QList<QByteArray> flags = response.content[2].toList(); 00156 QByteArray separator = response.content[3].toString(); 00157 if ( separator.isEmpty() ) { 00158 // Defaults to / for servers reporting an empty list 00159 // it's supposedly not a problem as servers doing that 00160 // only do it for mailboxes with no child. 00161 separator = "/"; 00162 } 00163 Q_ASSERT(separator.size()==1); 00164 QByteArray fullName; 00165 for ( int i=4; i<response.content.size(); i++ ) { 00166 fullName += response.content[i].toString() + ' '; 00167 } 00168 fullName.chop( 1 ); 00169 00170 fullName = decodeImapFolderName( fullName ); 00171 00172 MailBoxDescriptor mailBoxDescriptor; 00173 mailBoxDescriptor.separator = QChar( separator[0] ); 00174 mailBoxDescriptor.name = QString::fromUtf8( fullName ); 00175 00176 d->pendingDescriptors << mailBoxDescriptor; 00177 d->pendingFlags << flags; 00178 } 00179 } 00180 } 00181 00182 #include "listjob.moc"