kmail

imapjob.cpp

00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002  *
00003  *  This file is part of KMail, the KDE mail client.
00004  *  Copyright (c) 2002-2003 Zack Rusin <zack@kde.org>
00005  *                2000-2002 Michael Haeckel <haeckel@kde.org>
00006  *
00007  *  KMail is free software; you can redistribute it and/or modify it
00008  *  under the terms of the GNU General Public License, version 2, as
00009  *  published by the Free Software Foundation.
00010  *
00011  *  KMail is distributed in the hope that it will be useful, but
00012  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *  General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  *
00020  *  In addition, as a special exception, the copyright holders give
00021  *  permission to link the code of this program with any edition of
00022  *  the Qt library by Trolltech AS, Norway (or with modified versions
00023  *  of Qt that use the same license as Qt), and distribute linked
00024  *  combinations including the two.  You must obey the GNU General
00025  *  Public License in all respects for all of the code used other than
00026  *  Qt.  If you modify this file, you may extend this exception to
00027  *  your version of the file, but you are not obligated to do so.  If
00028  *  you do not wish to do so, delete this exception statement from
00029  *  your version.
00030  */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include "imapjob.h"
00037 #include "kmfolderimap.h"
00038 #include "kmfolder.h"
00039 #include "kmmsgpart.h"
00040 #include "progressmanager.h"
00041 using KPIM::ProgressManager;
00042 #include "util.h"
00043 
00044 #include <qstylesheet.h>
00045 #include <kio/scheduler.h>
00046 #include <kdebug.h>
00047 #include <klocale.h>
00048 #include <mimelib/body.h>
00049 #include <mimelib/bodypart.h>
00050 #include <mimelib/string.h>
00051 
00052 
00053 namespace KMail {
00054 
00055 //-----------------------------------------------------------------------------
00056 ImapJob::ImapJob( KMMessage *msg, JobType jt, KMFolderImap* folder,
00057     QString partSpecifier, const AttachmentStrategy *as )
00058   : FolderJob( msg, jt, folder? folder->folder() : 0, partSpecifier ),
00059     mAttachmentStrategy( as ), mParentProgressItem(0)
00060 {
00061 }
00062 
00063 //-----------------------------------------------------------------------------
00064 ImapJob::ImapJob( QPtrList<KMMessage>& msgList, QString sets, JobType jt,
00065                   KMFolderImap* folder )
00066   : FolderJob( msgList, sets, jt, folder? folder->folder() : 0 ),
00067     mAttachmentStrategy ( 0 ), mParentProgressItem(0)
00068 {
00069 }
00070 
00071 void ImapJob::init( JobType jt, QString sets, KMFolderImap* folder,
00072                     QPtrList<KMMessage>& msgList )
00073 {
00074   mJob = 0;
00075 
00076   assert(jt == tGetMessage || folder);
00077   KMMessage* msg = msgList.first();
00078    // guard against empty list
00079   if ( !msg ) {
00080     deleteLater();
00081     return;
00082   }
00083   mType = jt;
00084   mDestFolder = folder? folder->folder() : 0;
00085   // refcount++
00086   if (folder) {
00087     folder->open();
00088   }
00089   KMFolder *msg_parent = msg->parent();
00090   if (msg_parent) {
00091     if (!folder || folder!= msg_parent->storage()) {
00092       msg_parent->open();
00093     }
00094   }
00095   mSrcFolder = msg_parent;
00096   // If there is a destination folder, this is a copy, move or put to an
00097   // imap folder, use its account for keeping track of the job. Otherwise,
00098   // this is a get job and the src folder is an imap one. Use its account
00099   // then.
00100   KMAcctImap *account;
00101   if (folder) {
00102     account = folder->account();
00103   } else {
00104     account = static_cast<KMFolderImap*>(msg_parent->storage())->account();
00105   }
00106   if ( !account ||
00107        account->makeConnection() == ImapAccountBase::Error ) {
00108     deleteLater();
00109     return;
00110   }
00111   account->mJobList.append( this );
00112   if ( jt == tPutMessage )
00113   {
00114     // transfers the complete message to the server
00115     QPtrListIterator<KMMessage> it( msgList );
00116     KMMessage* curMsg;
00117     while ( ( curMsg = it.current() ) != 0 )
00118     {
00119       ++it;
00120       if ( mSrcFolder && !curMsg->isMessage() )
00121       {
00122         int idx = mSrcFolder->find( curMsg );
00123         curMsg = mSrcFolder->getMsg( idx );
00124       }
00125       KURL url = account->getUrl();
00126       QString flags = KMFolderImap::statusToFlags( curMsg->status() );
00127       url.setPath( folder->imapPath() + ";SECTION=" + flags );
00128       ImapAccountBase::jobData jd;
00129       jd.parent = 0; jd.offset = 0; jd.done = 0;
00130       jd.total = ( curMsg->msgSizeServer() > 0 ) ? 
00131         curMsg->msgSizeServer() : curMsg->msgSize();
00132       jd.msgList.append( curMsg );
00133       QCString cstr( curMsg->asString() );
00134       int a = cstr.find("\nX-UID: ");
00135       int b = cstr.find('\n', a);
00136       if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a);
00137       jd.data.resize( cstr.length() + cstr.contains( "\n" ) - cstr.contains( "\r\n" ) );
00138       unsigned int i = 0;
00139       char prevChar = '\0';
00140       // according to RFC 2060 we need CRLF
00141       for ( char *ch = cstr.data(); *ch; ch++ )
00142       {
00143         if ( *ch == '\n' && (prevChar != '\r') ) {
00144           jd.data.at( i ) = '\r';
00145           i++;
00146         }
00147         jd.data.at( i ) = *ch;
00148         prevChar = *ch;
00149         i++;
00150       }
00151       jd.progressItem = ProgressManager::createProgressItem(
00152           mParentProgressItem,
00153           "ImapJobUploading"+ProgressManager::getUniqueID(),
00154           i18n("Uploading message data"),
00155           curMsg->subject(),
00156           true,
00157           account->useSSL() || account->useTLS() );
00158       jd.progressItem->setTotalItems( jd.total );
00159       connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00160           account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00161       KIO::SimpleJob *job = KIO::put( url, 0, FALSE, FALSE, FALSE );
00162       KIO::Scheduler::assignJobToSlave( account->slave(), job );
00163       account->insertJob( job, jd );
00164       connect( job, SIGNAL(result(KIO::Job *)),
00165           SLOT(slotPutMessageResult(KIO::Job *)) );
00166       connect( job, SIGNAL(dataReq(KIO::Job *, QByteArray &)),
00167           SLOT(slotPutMessageDataReq(KIO::Job *, QByteArray &)) );
00168       connect( job, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00169           SLOT(slotPutMessageInfoData(KIO::Job *, const QString &)) );
00170       connect( job, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00171           SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00172     }
00173   }
00174   else if ( jt == tCopyMessage || jt == tMoveMessage )
00175   {
00176     KURL url = account->getUrl();
00177     KURL destUrl = account->getUrl();
00178     destUrl.setPath(folder->imapPath());
00179     KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(msg_parent->storage());
00180     url.setPath( imapDestFolder->imapPath() + ";UID=" + sets );
00181     ImapAccountBase::jobData jd;
00182     jd.parent = 0; jd.offset = 0;
00183     jd.total = 1; jd.done = 0;
00184     jd.msgList = msgList;
00185 
00186     QByteArray packedArgs;
00187     QDataStream stream( packedArgs, IO_WriteOnly );
00188 
00189     stream << (int) 'C' << url << destUrl;
00190     jd.progressItem = ProgressManager::createProgressItem(
00191                           mParentProgressItem,
00192                           "ImapJobCopyMove"+ProgressManager::getUniqueID(),
00193                           i18n("Server operation"),
00194                           i18n("Source folder: %1 - Destination folder: %2")
00195                             .arg( msg_parent->prettyURL(), 
00196                                   mDestFolder->prettyURL() ),
00197                           true,
00198                           account->useSSL() || account->useTLS() );
00199     jd.progressItem->setTotalItems( jd.total );
00200     connect ( jd.progressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
00201               account, SLOT( slotAbortRequested(KPIM::ProgressItem* ) ) );
00202     KIO::SimpleJob *simpleJob = KIO::special( url, packedArgs, FALSE );
00203     KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00204     mJob = simpleJob;
00205     account->insertJob( mJob, jd );
00206     connect( mJob, SIGNAL(result(KIO::Job *)),
00207              SLOT(slotCopyMessageResult(KIO::Job *)) );
00208     if ( jt == tMoveMessage )
00209     {
00210       connect( mJob, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00211                SLOT(slotCopyMessageInfoData(KIO::Job *, const QString &)) );
00212     }
00213   }
00214   else {
00215     slotGetNextMessage();
00216   }
00217 }
00218 
00219 
00220 //-----------------------------------------------------------------------------
00221 ImapJob::~ImapJob()
00222 {
00223   if ( mDestFolder )
00224   {
00225     KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00226     if ( account &&  mJob ) {
00227       ImapAccountBase::JobIterator it = account->findJob( mJob );
00228       if ( it != account->jobsEnd() ) {
00229         if( (*it).progressItem ) {
00230           (*it).progressItem->setComplete();
00231           (*it).progressItem = 0;
00232         }
00233         if ( !(*it).msgList.isEmpty() ) {
00234           for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00235             mit.current()->setTransferInProgress( false );
00236         }
00237       }
00238       account->removeJob( mJob );
00239     }
00240     account->mJobList.remove( this );
00241     mDestFolder->close();
00242   }
00243 
00244   if ( mSrcFolder ) {
00245     if (!mDestFolder || mDestFolder != mSrcFolder) {
00246       if (! (mSrcFolder->folderType() == KMFolderTypeImap) ) return;
00247       KMAcctImap *account = static_cast<KMFolderImap*>(mSrcFolder->storage())->account();
00248       if ( account && mJob ) {
00249         ImapAccountBase::JobIterator it = account->findJob( mJob );
00250         if ( it != account->jobsEnd() ) {
00251           if( (*it).progressItem ) {
00252             (*it).progressItem->setComplete();
00253             (*it).progressItem = 0;
00254           }
00255           if ( !(*it).msgList.isEmpty() ) {
00256             for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00257               mit.current()->setTransferInProgress( false );
00258           }
00259         }
00260         account->removeJob( mJob ); // remove the associated kio job
00261       }
00262       account->mJobList.remove( this ); // remove the folderjob
00263     }
00264     mSrcFolder->close();
00265   }
00266 }
00267 
00268 
00269 //-----------------------------------------------------------------------------
00270 void ImapJob::slotGetNextMessage()
00271 {
00272   KMMessage *msg = mMsgList.first();
00273   KMFolderImap *msgParent = static_cast<KMFolderImap*>(msg->storage());
00274   KMAcctImap *account = msgParent->account();
00275   if ( msg->UID() == 0 )
00276   {
00277     // broken message
00278     emit messageRetrieved( 0 );
00279     deleteLater();
00280     return;
00281   }
00282   KURL url = account->getUrl();
00283   QString path = msgParent->imapPath() + ";UID=" + QString::number(msg->UID());
00284   ImapAccountBase::jobData jd;
00285   jd.parent = 0; jd.offset = 0;
00286   jd.total = 1; jd.done = 0;
00287   jd.msgList.append( msg );
00288   if ( !mPartSpecifier.isEmpty() )
00289   {
00290     if ( mPartSpecifier.find ("STRUCTURE", 0, false) != -1 ) {
00291       path += ";SECTION=STRUCTURE";
00292     } else if ( mPartSpecifier == "HEADER" ) {
00293       path += ";SECTION=HEADER";
00294     } else {
00295       path += ";SECTION=BODY.PEEK[" + mPartSpecifier + "]";
00296       DwBodyPart * part = msg->findDwBodyPart( msg->getFirstDwBodyPart(), mPartSpecifier );
00297       if (part)
00298         jd.total = part->BodySize();
00299     }
00300   } else {
00301       path += ";SECTION=BODY.PEEK[]";
00302       if (msg->msgSizeServer() > 0)
00303         jd.total = msg->msgSizeServer();
00304   }
00305   url.setPath( path );
00306 //  kdDebug(5006) << "ImapJob::slotGetNextMessage - retrieve " << url.path() << endl;
00307   // protect the message, otherwise we'll get crashes afterwards
00308   msg->setTransferInProgress( true );
00309   const QString escapedSubject = QStyleSheet::escape( msg->subject() );
00310   jd.progressItem = ProgressManager::createProgressItem(
00311                           mParentProgressItem,
00312                           "ImapJobDownloading"+ProgressManager::getUniqueID(),
00313                           i18n("Downloading message data"),
00314                           i18n("Message with subject: ") + escapedSubject,
00315                           true,
00316                           account->useSSL() || account->useTLS() );
00317   connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00318             account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00319   jd.progressItem->setTotalItems( jd.total );
00320 
00321   KIO::SimpleJob *simpleJob = KIO::get( url, FALSE, FALSE );
00322   KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00323   mJob = simpleJob;
00324   account->insertJob( mJob, jd );
00325   if ( mPartSpecifier.find( "STRUCTURE", 0, false ) != -1 )
00326   {
00327     connect( mJob, SIGNAL(result(KIO::Job *)),
00328              this, SLOT(slotGetBodyStructureResult(KIO::Job *)) );
00329   } else {
00330     connect( mJob, SIGNAL(result(KIO::Job *)),
00331              this, SLOT(slotGetMessageResult(KIO::Job *)) );
00332   }
00333   connect( mJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
00334            msgParent, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)) );
00335   if ( jd.total > 1 )
00336   {
00337     connect(mJob, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00338         this, SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00339   }
00340 }
00341 
00342 
00343 //-----------------------------------------------------------------------------
00344 void ImapJob::slotGetMessageResult( KIO::Job * job )
00345 {
00346   KMMessage *msg = mMsgList.first();
00347   if (!msg || !msg->parent() || !job) {
00348     emit messageRetrieved( 0 );
00349     deleteLater();
00350     return;
00351   }
00352   KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00353   if (msg->transferInProgress())
00354     msg->setTransferInProgress( false );
00355   KMAcctImap *account = parent->account();
00356   if ( !account ) {
00357     emit messageRetrieved( 0 );
00358     deleteLater();
00359     return;
00360   }
00361   ImapAccountBase::JobIterator it = account->findJob( job );
00362   if ( it == account->jobsEnd() ) return;
00363 
00364   bool gotData = true;
00365   if (job->error())
00366   {
00367     QString errorStr = i18n( "Error while retrieving messages from the server." );
00368     if ( (*it).progressItem )
00369       (*it).progressItem->setStatus( errorStr );
00370     account->handleJobError( job, errorStr );
00371     return;
00372   } else {
00373     if ((*it).data.size() > 0)
00374     {
00375       kdDebug(5006) << "ImapJob::slotGetMessageResult - retrieved part " << mPartSpecifier << endl;
00376       if ( mPartSpecifier.isEmpty() ||
00377            mPartSpecifier == "HEADER" )
00378       {
00379         uint size = msg->msgSizeServer();
00380         if ( size > 0 && mPartSpecifier.isEmpty() )
00381           (*it).done = size;
00382         ulong uid = msg->UID();
00383         // must set this first so that msg->fromByteArray sets the attachment status
00384         if ( mPartSpecifier.isEmpty() )
00385           msg->setComplete( true );
00386         else
00387           msg->setReadyToShow( false );
00388 
00389         // Convert CR/LF to LF.
00390         size_t dataSize = (*it).data.size();
00391         dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
00392         (*it).data.resize( dataSize );
00393 
00394         // During the construction of the message from the byteArray it does 
00395         // not have a uid. Therefore we have to make sure that no connected
00396         // slots are called, since they would operate on uid == 0.
00397         msg->parent()->storage()->blockSignals( true );
00398         msg->fromByteArray( (*it).data );
00399         // now let others react
00400         msg->parent()->storage()->blockSignals( false );
00401         if ( size > 0 && msg->msgSizeServer() == 0 ) {
00402           msg->setMsgSizeServer(size);
00403         }
00404         // reconstruct the UID as it gets overwritten above
00405         msg->setUID(uid);
00406 
00407       } else {
00408         // Convert CR/LF to LF.
00409         size_t dataSize = (*it).data.size();
00410         dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
00411         (*it).data.resize( dataSize );
00412 
00413         // Update the body of the retrieved part (the message notifies all observers)
00414         msg->updateBodyPart( mPartSpecifier, (*it).data );
00415         msg->setReadyToShow( true );
00416         // Update the attachment state, we have to do this for every part as we actually
00417         // do not know if the message has no attachment or we simply did not load the header
00418         if (msg->attachmentState() != KMMsgHasAttachment)
00419           msg->updateAttachmentState();
00420       }
00421     } else {
00422       kdDebug(5006) << "ImapJob::slotGetMessageResult - got no data for " << mPartSpecifier << endl;
00423       gotData = false;
00424       msg->setReadyToShow( true );
00425       // nevertheless give visual feedback
00426       msg->notify();
00427     }
00428   }
00429   if (account->slave()) {
00430       account->removeJob(it);
00431       account->mJobList.remove(this);
00432   }
00433   /* This needs to be emitted last, so the slots that are hooked to it
00434    * don't unGetMsg the msg before we have finished. */
00435   if ( mPartSpecifier.isEmpty() ||
00436        mPartSpecifier == "HEADER" )
00437   {
00438     if ( gotData )
00439       emit messageRetrieved(msg);
00440     else
00441     {
00442       /* we got an answer but not data
00443        * this means that the msg is not on the server anymore so delete it */
00444       emit messageRetrieved( 0 );
00445       parent->ignoreJobsForMessage( msg );
00446       int idx = parent->find( msg );
00447       if (idx != -1) parent->removeMsg( idx, true );
00448       // the removeMsg will unGet the message, which will delete all 
00449       // jobs, including this one
00450       return;
00451     }
00452   } else {
00453     emit messageUpdated(msg, mPartSpecifier);
00454   }
00455   deleteLater();
00456 }
00457 
00458 //-----------------------------------------------------------------------------
00459 void ImapJob::slotGetBodyStructureResult( KIO::Job * job )
00460 {
00461   KMMessage *msg = mMsgList.first();
00462   if (!msg || !msg->parent() || !job) {
00463     deleteLater();
00464     return;
00465   }
00466   KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00467   if (msg->transferInProgress())
00468     msg->setTransferInProgress( false );
00469   KMAcctImap *account = parent->account();
00470   if ( !account ) {
00471     deleteLater();
00472     return;
00473   }
00474   ImapAccountBase::JobIterator it = account->findJob( job );
00475   if ( it == account->jobsEnd() ) return;
00476 
00477 
00478   if (job->error())
00479   {
00480     account->handleJobError( job, i18n( "Error while retrieving information on the structure of a message." ) );
00481     return;
00482   } else {
00483     if ((*it).data.size() > 0)
00484     {
00485       QDataStream stream( (*it).data, IO_ReadOnly );
00486       account->handleBodyStructure(stream, msg, mAttachmentStrategy);
00487     }
00488   }
00489   if (account->slave()) {
00490       account->removeJob(it);
00491       account->mJobList.remove(this);
00492   }
00493   deleteLater();
00494 }
00495 
00496 //-----------------------------------------------------------------------------
00497 void ImapJob::slotPutMessageDataReq( KIO::Job *job, QByteArray &data )
00498 {
00499   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00500   ImapAccountBase::JobIterator it = account->findJob( job );
00501   if ( it == account->jobsEnd() ) return;
00502 
00503   if ((*it).data.size() - (*it).offset > 0x8000)
00504   {
00505     data.duplicate((*it).data.data() + (*it).offset, 0x8000);
00506     (*it).offset += 0x8000;
00507   }
00508   else if ((*it).data.size() - (*it).offset > 0)
00509   {
00510     data.duplicate((*it).data.data() + (*it).offset, (*it).data.size() - (*it).offset);
00511     (*it).offset = (*it).data.size();
00512   } else data.resize(0);
00513 }
00514 
00515 
00516 //-----------------------------------------------------------------------------
00517 void ImapJob::slotPutMessageResult( KIO::Job *job )
00518 {
00519   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00520   ImapAccountBase::JobIterator it = account->findJob( job );
00521   if ( it == account->jobsEnd() ) return;
00522   bool deleteMe = false;
00523   if (job->error())
00524   {
00525     if ( (*it).progressItem )
00526       (*it).progressItem->setStatus( i18n("Uploading message data failed.") );
00527     account->handlePutError( job, *it, mDestFolder );
00528     return;
00529   } else {
00530     if ( (*it).progressItem )
00531       (*it).progressItem->setStatus( i18n("Uploading message data completed.") );
00532     if ( mParentProgressItem )
00533     {
00534       mParentProgressItem->incCompletedItems();
00535       mParentProgressItem->updateProgress();
00536     }
00537     KMMessage *msg = (*it).msgList.first();
00538     emit messageStored( msg );
00539     if ( msg == mMsgList.getLast() )
00540     {
00541       emit messageCopied( mMsgList );
00542       if (account->slave()) {
00543         account->mJobList.remove( this );
00544       }
00545       deleteMe = true;
00546     }
00547   }
00548   if (account->slave()) {
00549     account->removeJob( it ); // also clears progressitem
00550   }
00551   if ( deleteMe )
00552     deleteLater();
00553 }
00554 
00555 //-----------------------------------------------------------------------------
00556 void ImapJob::slotCopyMessageInfoData(KIO::Job * job, const QString & data)
00557 {
00558   KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00559   KMAcctImap *account = imapFolder->account();
00560   ImapAccountBase::JobIterator it = account->findJob( job );
00561   if ( it == account->jobsEnd() ) return;
00562 
00563   if (data.find("UID") != -1)
00564   {
00565     // split
00566     QString oldUid = data.section(' ', 1, 1);
00567     QString newUid = data.section(' ', 2, 2);
00568 
00569     // get lists of uids
00570     QValueList<ulong> olduids = KMFolderImap::splitSets(oldUid);
00571     QValueList<ulong> newuids = KMFolderImap::splitSets(newUid);
00572 
00573     int index = -1;
00574     KMMessage * msg;
00575     for ( msg = (*it).msgList.first(); msg; msg = (*it).msgList.next() )
00576     {
00577       ulong uid = msg->UID();
00578       index = olduids.findIndex(uid);
00579       if (index > -1)
00580       {
00581         // found, get the new uid
00582         imapFolder->saveMsgMetaData( msg, newuids[index] );
00583       }
00584     }
00585   }
00586 }
00587 
00588 //----------------------------------------------------------------------------
00589 void ImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data)
00590 {
00591   KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00592   KMAcctImap *account = imapFolder->account();
00593   ImapAccountBase::JobIterator it = account->findJob( job );
00594   if ( it == account->jobsEnd() ) return;
00595 
00596   if ( data.find("UID") != -1 )
00597   {
00598     ulong uid = ( data.right(data.length()-4) ).toInt();
00599     if ( !(*it).msgList.isEmpty() )
00600     {
00601       imapFolder->saveMsgMetaData( (*it).msgList.first(), uid );
00602     }
00603   }
00604 }
00605 
00606 
00607 //-----------------------------------------------------------------------------
00608 void ImapJob::slotCopyMessageResult( KIO::Job *job )
00609 {
00610   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00611   ImapAccountBase::JobIterator it = account->findJob( job );
00612   if ( it == account->jobsEnd() ) return;
00613 
00614   if (job->error())
00615   {
00616     mErrorCode = job->error();
00617     QString errStr = i18n("Error while copying messages.");
00618     if ( (*it).progressItem )
00619       (*it).progressItem->setStatus( errStr );
00620     account->handleJobError( job, errStr  );
00621     deleteLater();
00622     return;
00623   } else {
00624     if ( !(*it).msgList.isEmpty() )
00625     {
00626       emit messageCopied((*it).msgList);
00627     } else if (mMsgList.first()) {
00628       emit messageCopied(mMsgList.first());
00629     }
00630   }
00631   if (account->slave()) {
00632     account->removeJob(it);
00633     account->mJobList.remove(this);
00634   }
00635   deleteLater();
00636 }
00637 
00638 //-----------------------------------------------------------------------------
00639 void ImapJob::execute()
00640 {
00641   init( mType, mSets, mDestFolder?
00642         dynamic_cast<KMFolderImap*>( mDestFolder->storage() ):0, mMsgList );
00643 }
00644 
00645 //-----------------------------------------------------------------------------
00646 void ImapJob::setParentFolder( const KMFolderImap* parent )
00647 {
00648   mParentFolder = const_cast<KMFolderImap*>( parent );
00649 }
00650 
00651 //-----------------------------------------------------------------------------
00652 void ImapJob::slotProcessedSize(KIO::Job * job, KIO::filesize_t processed)
00653 {
00654   KMMessage *msg = mMsgList.first();
00655   if (!msg || !job) {
00656     return;
00657   }
00658   KMFolderImap* parent = 0;
00659   if ( msg->parent() && msg->parent()->folderType() == KMFolderTypeImap )
00660     parent = static_cast<KMFolderImap*>(msg->parent()->storage());
00661   else if (mDestFolder) // put
00662     parent = static_cast<KMFolderImap*>(mDestFolder->storage());
00663   if (!parent) return;
00664   KMAcctImap *account = parent->account();
00665   if ( !account ) return;
00666   ImapAccountBase::JobIterator it = account->findJob( job );
00667   if ( it == account->jobsEnd() ) return;
00668   (*it).done = processed;
00669   if ( (*it).progressItem ) {
00670     (*it).progressItem->setCompletedItems( processed );
00671     (*it).progressItem->updateProgress();
00672   }
00673   emit progress( (*it).done, (*it).total );
00674 }
00675 
00676 }//namespace KMail
00677 
00678 #include "imapjob.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys