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 = 0;
00101   if (folder) {
00102     account = folder->account();
00103   } else {
00104     if ( msg_parent && msg_parent->storage() )
00105       account = static_cast<KMFolderImap*>(msg_parent->storage())->account();
00106   }
00107   if ( !account ||
00108        account->makeConnection() == ImapAccountBase::Error ) {
00109     deleteLater();
00110     return;
00111   }
00112   account->mJobList.append( this );
00113   if ( jt == tPutMessage )
00114   {
00115     // transfers the complete message to the server
00116     QPtrListIterator<KMMessage> it( msgList );
00117     KMMessage* curMsg;
00118     while ( ( curMsg = it.current() ) != 0 )
00119     {
00120       ++it;
00121       if ( mSrcFolder && !curMsg->isMessage() )
00122       {
00123         int idx = mSrcFolder->find( curMsg );
00124         curMsg = mSrcFolder->getMsg( idx );
00125       }
00126       KURL url = account->getUrl();
00127       QString flags = KMFolderImap::statusToFlags( curMsg->status() );
00128       url.setPath( folder->imapPath() + ";SECTION=" + flags );
00129       ImapAccountBase::jobData jd;
00130       jd.parent = 0; jd.offset = 0; jd.done = 0;
00131       jd.total = ( curMsg->msgSizeServer() > 0 ) ?
00132         curMsg->msgSizeServer() : curMsg->msgSize();
00133       jd.msgList.append( curMsg );
00134       QCString cstr( curMsg->asString() );
00135       int a = cstr.find("\nX-UID: ");
00136       int b = cstr.find('\n', a);
00137       if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a);
00138       jd.data.resize( cstr.length() + cstr.contains( "\n" ) - cstr.contains( "\r\n" ) );
00139       unsigned int i = 0;
00140       char prevChar = '\0';
00141       // according to RFC 2060 we need CRLF
00142       for ( char *ch = cstr.data(); *ch; ch++ )
00143       {
00144         if ( *ch == '\n' && (prevChar != '\r') ) {
00145           jd.data.at( i ) = '\r';
00146           i++;
00147         }
00148         jd.data.at( i ) = *ch;
00149         prevChar = *ch;
00150         i++;
00151       }
00152       jd.progressItem = ProgressManager::createProgressItem(
00153           mParentProgressItem,
00154           "ImapJobUploading"+ProgressManager::getUniqueID(),
00155           i18n("Uploading message data"),
00156           QStyleSheet::escape( curMsg->subject() ),
00157           true,
00158           account->useSSL() || account->useTLS() );
00159       jd.progressItem->setTotalItems( jd.total );
00160       connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00161           account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00162       KIO::SimpleJob *job = KIO::put( url, 0, FALSE, FALSE, FALSE );
00163       KIO::Scheduler::assignJobToSlave( account->slave(), job );
00164       account->insertJob( job, jd );
00165       connect( job, SIGNAL(result(KIO::Job *)),
00166           SLOT(slotPutMessageResult(KIO::Job *)) );
00167       connect( job, SIGNAL(dataReq(KIO::Job *, QByteArray &)),
00168           SLOT(slotPutMessageDataReq(KIO::Job *, QByteArray &)) );
00169       connect( job, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00170           SLOT(slotPutMessageInfoData(KIO::Job *, const QString &)) );
00171       connect( job, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00172           SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00173     }
00174   }
00175   else if ( jt == tCopyMessage || jt == tMoveMessage )
00176   {
00177     KURL url = account->getUrl();
00178     KURL destUrl = account->getUrl();
00179     destUrl.setPath(folder->imapPath());
00180     KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(msg_parent->storage());
00181     url.setPath( imapDestFolder->imapPath() + ";UID=" + sets );
00182     ImapAccountBase::jobData jd;
00183     jd.parent = 0; jd.offset = 0;
00184     jd.total = 1; jd.done = 0;
00185     jd.msgList = msgList;
00186 
00187     QByteArray packedArgs;
00188     QDataStream stream( packedArgs, IO_WriteOnly );
00189 
00190     stream << (int) 'C' << url << destUrl;
00191     jd.progressItem = ProgressManager::createProgressItem(
00192                           mParentProgressItem,
00193                           "ImapJobCopyMove"+ProgressManager::getUniqueID(),
00194                           i18n("Server operation"),
00195                           i18n("Source folder: %1 - Destination folder: %2")
00196                             .arg( QStyleSheet::escape( msg_parent->prettyURL() ),
00197                                   QStyleSheet::escape( mDestFolder->prettyURL() ) ),
00198                           true,
00199                           account->useSSL() || account->useTLS() );
00200     jd.progressItem->setTotalItems( jd.total );
00201     connect ( jd.progressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
00202               account, SLOT( slotAbortRequested(KPIM::ProgressItem* ) ) );
00203     KIO::SimpleJob *simpleJob = KIO::special( url, packedArgs, FALSE );
00204     KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00205     mJob = simpleJob;
00206     account->insertJob( mJob, jd );
00207     connect( mJob, SIGNAL(result(KIO::Job *)),
00208              SLOT(slotCopyMessageResult(KIO::Job *)) );
00209     if ( jt == tMoveMessage )
00210     {
00211       connect( mJob, SIGNAL(infoMessage(KIO::Job *, const QString &)),
00212                SLOT(slotCopyMessageInfoData(KIO::Job *, const QString &)) );
00213     }
00214   }
00215   else {
00216     slotGetNextMessage();
00217   }
00218 }
00219 
00220 
00221 //-----------------------------------------------------------------------------
00222 ImapJob::~ImapJob()
00223 {
00224   if ( mDestFolder )
00225   {
00226     KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00227     if ( account ) {
00228       if ( mJob ) {
00229         ImapAccountBase::JobIterator it = account->findJob( mJob );
00230         if ( it != account->jobsEnd() ) {
00231           if( (*it).progressItem ) {
00232             (*it).progressItem->setComplete();
00233             (*it).progressItem = 0;
00234           }
00235           if ( !(*it).msgList.isEmpty() ) {
00236             for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00237               mit.current()->setTransferInProgress( false );
00238           }
00239         }
00240         account->removeJob( mJob );
00241       }
00242       account->mJobList.remove( this );
00243     }
00244     mDestFolder->close();
00245   }
00246 
00247   if ( mSrcFolder ) {
00248     if (!mDestFolder || mDestFolder != mSrcFolder) {
00249       if (! (mSrcFolder->folderType() == KMFolderTypeImap) ) return;
00250       KMAcctImap *account = static_cast<KMFolderImap*>(mSrcFolder->storage())->account();
00251       if ( account ) {
00252         if ( mJob ) {
00253           ImapAccountBase::JobIterator it = account->findJob( mJob );
00254           if ( it != account->jobsEnd() ) {
00255             if( (*it).progressItem ) {
00256               (*it).progressItem->setComplete();
00257               (*it).progressItem = 0;
00258             }
00259             if ( !(*it).msgList.isEmpty() ) {
00260               for ( QPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
00261                 mit.current()->setTransferInProgress( false );
00262             }
00263           }
00264           account->removeJob( mJob ); // remove the associated kio job
00265         }
00266         account->mJobList.remove( this ); // remove the folderjob
00267       }
00268     }
00269     mSrcFolder->close();
00270   }
00271 }
00272 
00273 
00274 //-----------------------------------------------------------------------------
00275 void ImapJob::slotGetNextMessage()
00276 {
00277   KMMessage *msg = mMsgList.first();
00278   KMFolderImap *msgParent = msg ? static_cast<KMFolderImap*>(msg->storage()) : 0;
00279   if ( !msgParent || !msg || msg->UID() == 0 )
00280   {
00281     // broken message
00282     emit messageRetrieved( 0 );
00283     deleteLater();
00284     return;
00285   }
00286   KMAcctImap *account = msgParent->account();
00287   KURL url = account->getUrl();
00288   QString path = msgParent->imapPath() + ";UID=" + QString::number(msg->UID());
00289   ImapAccountBase::jobData jd;
00290   jd.parent = 0; jd.offset = 0;
00291   jd.total = 1; jd.done = 0;
00292   jd.msgList.append( msg );
00293   if ( !mPartSpecifier.isEmpty() )
00294   {
00295     if ( mPartSpecifier.find ("STRUCTURE", 0, false) != -1 ) {
00296       path += ";SECTION=STRUCTURE";
00297     } else if ( mPartSpecifier == "HEADER" ) {
00298       path += ";SECTION=HEADER";
00299     } else {
00300       path += ";SECTION=BODY.PEEK[" + mPartSpecifier + "]";
00301       DwBodyPart * part = msg->findDwBodyPart( msg->getFirstDwBodyPart(), mPartSpecifier );
00302       if (part)
00303         jd.total = part->BodySize();
00304     }
00305   } else {
00306       path += ";SECTION=BODY.PEEK[]";
00307       if (msg->msgSizeServer() > 0)
00308         jd.total = msg->msgSizeServer();
00309   }
00310   url.setPath( path );
00311 //  kdDebug(5006) << "ImapJob::slotGetNextMessage - retrieve " << url.path() << endl;
00312   // protect the message, otherwise we'll get crashes afterwards
00313   msg->setTransferInProgress( true );
00314   jd.progressItem = ProgressManager::createProgressItem(
00315                           mParentProgressItem,
00316                           "ImapJobDownloading"+ProgressManager::getUniqueID(),
00317                           i18n("Downloading message data"),
00318                           i18n("Message with subject: ") +
00319                           QStyleSheet::escape( msg->subject() ),
00320                           true,
00321                           account->useSSL() || account->useTLS() );
00322   connect ( jd.progressItem, SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
00323             account, SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
00324   jd.progressItem->setTotalItems( jd.total );
00325 
00326   KIO::SimpleJob *simpleJob = KIO::get( url, FALSE, FALSE );
00327   KIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
00328   mJob = simpleJob;
00329   account->insertJob( mJob, jd );
00330   if ( mPartSpecifier.find( "STRUCTURE", 0, false ) != -1 )
00331   {
00332     connect( mJob, SIGNAL(result(KIO::Job *)),
00333              this, SLOT(slotGetBodyStructureResult(KIO::Job *)) );
00334   } else {
00335     connect( mJob, SIGNAL(result(KIO::Job *)),
00336              this, SLOT(slotGetMessageResult(KIO::Job *)) );
00337   }
00338   connect( mJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
00339            msgParent, SLOT(slotSimpleData(KIO::Job *, const QByteArray &)) );
00340   if ( jd.total > 1 )
00341   {
00342     connect(mJob, SIGNAL(processedSize(KIO::Job *, KIO::filesize_t)),
00343         this, SLOT(slotProcessedSize(KIO::Job *, KIO::filesize_t)));
00344   }
00345 }
00346 
00347 
00348 //-----------------------------------------------------------------------------
00349 void ImapJob::slotGetMessageResult( KIO::Job * job )
00350 {
00351   KMMessage *msg = mMsgList.first();
00352   if (!msg || !msg->parent() || !job) {
00353     emit messageRetrieved( 0 );
00354     deleteLater();
00355     return;
00356   }
00357   KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00358   if (msg->transferInProgress())
00359     msg->setTransferInProgress( false );
00360   KMAcctImap *account = parent->account();
00361   if ( !account ) {
00362     emit messageRetrieved( 0 );
00363     deleteLater();
00364     return;
00365   }
00366   ImapAccountBase::JobIterator it = account->findJob( job );
00367   if ( it == account->jobsEnd() ) return;
00368 
00369   bool gotData = true;
00370   if (job->error())
00371   {
00372     QString errorStr = i18n( "Error while retrieving messages from the server." );
00373     if ( (*it).progressItem )
00374       (*it).progressItem->setStatus( errorStr );
00375     account->handleJobError( job, errorStr );
00376     return;
00377   } else {
00378     if ((*it).data.size() > 0)
00379     {
00380       kdDebug(5006) << "ImapJob::slotGetMessageResult - retrieved part " << mPartSpecifier << endl;
00381       if ( mPartSpecifier.isEmpty() ||
00382            mPartSpecifier == "HEADER" )
00383       {
00384         uint size = msg->msgSizeServer();
00385         if ( size > 0 && mPartSpecifier.isEmpty() )
00386           (*it).done = size;
00387         ulong uid = msg->UID();
00388         // must set this first so that msg->fromByteArray sets the attachment status
00389         if ( mPartSpecifier.isEmpty() )
00390           msg->setComplete( true );
00391         else
00392           msg->setReadyToShow( false );
00393 
00394         // Convert CR/LF to LF.
00395         size_t dataSize = (*it).data.size();
00396         dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
00397         (*it).data.resize( dataSize );
00398 
00399         // During the construction of the message from the byteArray it does
00400         // not have a uid. Therefore we have to make sure that no connected
00401         // slots are called, since they would operate on uid == 0.
00402         msg->parent()->storage()->blockSignals( true );
00403         msg->fromByteArray( (*it).data );
00404         // now let others react
00405         msg->parent()->storage()->blockSignals( false );
00406         if ( size > 0 && msg->msgSizeServer() == 0 ) {
00407           msg->setMsgSizeServer(size);
00408         }
00409         // reconstruct the UID as it gets overwritten above
00410         msg->setUID(uid);
00411 
00412       } else {
00413         // Convert CR/LF to LF.
00414         size_t dataSize = (*it).data.size();
00415         dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
00416         (*it).data.resize( dataSize );
00417 
00418         // Update the body of the retrieved part (the message notifies all observers)
00419         msg->updateBodyPart( mPartSpecifier, (*it).data );
00420         msg->setReadyToShow( true );
00421         // Update the attachment state, we have to do this for every part as we actually
00422         // do not know if the message has no attachment or we simply did not load the header
00423         if (msg->attachmentState() != KMMsgHasAttachment)
00424           msg->updateAttachmentState();
00425       }
00426     } else {
00427       kdDebug(5006) << "ImapJob::slotGetMessageResult - got no data for " << mPartSpecifier << endl;
00428       gotData = false;
00429       msg->setReadyToShow( true );
00430       // nevertheless give visual feedback
00431       msg->notify();
00432     }
00433   }
00434   if (account->slave()) {
00435       account->removeJob(it);
00436       account->mJobList.remove(this);
00437   }
00438   /* This needs to be emitted last, so the slots that are hooked to it
00439    * don't unGetMsg the msg before we have finished. */
00440   if ( mPartSpecifier.isEmpty() ||
00441        mPartSpecifier == "HEADER" )
00442   {
00443     if ( gotData )
00444       emit messageRetrieved(msg);
00445     else
00446     {
00447       /* we got an answer but not data
00448        * this means that the msg is not on the server anymore so delete it */
00449       emit messageRetrieved( 0 );
00450       parent->ignoreJobsForMessage( msg );
00451       int idx = parent->find( msg );
00452       if (idx != -1) parent->removeMsg( idx, true );
00453       // the removeMsg will unGet the message, which will delete all
00454       // jobs, including this one
00455       return;
00456     }
00457   } else {
00458     emit messageUpdated(msg, mPartSpecifier);
00459   }
00460   deleteLater();
00461 }
00462 
00463 //-----------------------------------------------------------------------------
00464 void ImapJob::slotGetBodyStructureResult( KIO::Job * job )
00465 {
00466   KMMessage *msg = mMsgList.first();
00467   if (!msg || !msg->parent() || !job) {
00468     deleteLater();
00469     return;
00470   }
00471   KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
00472   if (msg->transferInProgress())
00473     msg->setTransferInProgress( false );
00474   KMAcctImap *account = parent->account();
00475   if ( !account ) {
00476     deleteLater();
00477     return;
00478   }
00479   ImapAccountBase::JobIterator it = account->findJob( job );
00480   if ( it == account->jobsEnd() ) return;
00481 
00482 
00483   if (job->error())
00484   {
00485     account->handleJobError( job, i18n( "Error while retrieving information on the structure of a message." ) );
00486     return;
00487   } else {
00488     if ((*it).data.size() > 0)
00489     {
00490       QDataStream stream( (*it).data, IO_ReadOnly );
00491       account->handleBodyStructure(stream, msg, mAttachmentStrategy);
00492     }
00493   }
00494   if (account->slave()) {
00495       account->removeJob(it);
00496       account->mJobList.remove(this);
00497   }
00498   deleteLater();
00499 }
00500 
00501 //-----------------------------------------------------------------------------
00502 void ImapJob::slotPutMessageDataReq( KIO::Job *job, QByteArray &data )
00503 {
00504   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00505   ImapAccountBase::JobIterator it = account->findJob( job );
00506   if ( it == account->jobsEnd() ) return;
00507 
00508   if ((*it).data.size() - (*it).offset > 0x8000)
00509   {
00510     data.duplicate((*it).data.data() + (*it).offset, 0x8000);
00511     (*it).offset += 0x8000;
00512   }
00513   else if ((*it).data.size() - (*it).offset > 0)
00514   {
00515     data.duplicate((*it).data.data() + (*it).offset, (*it).data.size() - (*it).offset);
00516     (*it).offset = (*it).data.size();
00517   } else data.resize(0);
00518 }
00519 
00520 
00521 //-----------------------------------------------------------------------------
00522 void ImapJob::slotPutMessageResult( KIO::Job *job )
00523 {
00524   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00525   ImapAccountBase::JobIterator it = account->findJob( job );
00526   if ( it == account->jobsEnd() ) return;
00527   bool deleteMe = false;
00528   if (job->error())
00529   {
00530     if ( (*it).progressItem )
00531       (*it).progressItem->setStatus( i18n("Uploading message data failed.") );
00532     account->handlePutError( job, *it, mDestFolder );
00533     return;
00534   } else {
00535     if ( (*it).progressItem )
00536       (*it).progressItem->setStatus( i18n("Uploading message data completed.") );
00537     if ( mParentProgressItem )
00538     {
00539       mParentProgressItem->incCompletedItems();
00540       mParentProgressItem->updateProgress();
00541     }
00542     KMMessage *msg = (*it).msgList.first();
00543     emit messageStored( msg );
00544     if ( msg == mMsgList.getLast() )
00545     {
00546       emit messageCopied( mMsgList );
00547       if (account->slave()) {
00548         account->mJobList.remove( this );
00549       }
00550       deleteMe = true;
00551     }
00552   }
00553   if (account->slave()) {
00554     account->removeJob( it ); // also clears progressitem
00555   }
00556   if ( deleteMe )
00557     deleteLater();
00558 }
00559 
00560 //-----------------------------------------------------------------------------
00561 void ImapJob::slotCopyMessageInfoData(KIO::Job * job, const QString & data)
00562 {
00563   KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00564   KMAcctImap *account = imapFolder->account();
00565   ImapAccountBase::JobIterator it = account->findJob( job );
00566   if ( it == account->jobsEnd() ) return;
00567 
00568   if (data.find("UID") != -1)
00569   {
00570     // split
00571     QString oldUid = data.section(' ', 1, 1);
00572     QString newUid = data.section(' ', 2, 2);
00573 
00574     // get lists of uids
00575     QValueList<ulong> olduids = KMFolderImap::splitSets(oldUid);
00576     QValueList<ulong> newuids = KMFolderImap::splitSets(newUid);
00577 
00578     int index = -1;
00579     KMMessage * msg;
00580     for ( msg = (*it).msgList.first(); msg; msg = (*it).msgList.next() )
00581     {
00582       ulong uid = msg->UID();
00583       index = olduids.findIndex(uid);
00584       if (index > -1)
00585       {
00586         // found, get the new uid
00587         imapFolder->saveMsgMetaData( msg, newuids[index] );
00588       }
00589     }
00590   }
00591 }
00592 
00593 //----------------------------------------------------------------------------
00594 void ImapJob::slotPutMessageInfoData(KIO::Job *job, const QString &data)
00595 {
00596   KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
00597   KMAcctImap *account = imapFolder->account();
00598   ImapAccountBase::JobIterator it = account->findJob( job );
00599   if ( it == account->jobsEnd() ) return;
00600 
00601   if ( data.find("UID") != -1 )
00602   {
00603     ulong uid = ( data.right(data.length()-4) ).toInt();
00604     if ( !(*it).msgList.isEmpty() )
00605     {
00606       imapFolder->saveMsgMetaData( (*it).msgList.first(), uid );
00607     }
00608   }
00609 }
00610 
00611 
00612 //-----------------------------------------------------------------------------
00613 void ImapJob::slotCopyMessageResult( KIO::Job *job )
00614 {
00615   KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
00616   ImapAccountBase::JobIterator it = account->findJob( job );
00617   if ( it == account->jobsEnd() ) return;
00618 
00619   if (job->error())
00620   {
00621     mErrorCode = job->error();
00622     QString errStr = i18n("Error while copying messages.");
00623     if ( (*it).progressItem )
00624       (*it).progressItem->setStatus( errStr );
00625     account->handleJobError( job, errStr  );
00626     deleteLater();
00627     return;
00628   } else {
00629     if ( !(*it).msgList.isEmpty() )
00630     {
00631       emit messageCopied((*it).msgList);
00632     } else if (mMsgList.first()) {
00633       emit messageCopied(mMsgList.first());
00634     }
00635   }
00636   if (account->slave()) {
00637     account->removeJob(it);
00638     account->mJobList.remove(this);
00639   }
00640   deleteLater();
00641 }
00642 
00643 //-----------------------------------------------------------------------------
00644 void ImapJob::execute()
00645 {
00646   init( mType, mSets, mDestFolder?
00647         dynamic_cast<KMFolderImap*>( mDestFolder->storage() ):0, mMsgList );
00648 }
00649 
00650 //-----------------------------------------------------------------------------
00651 void ImapJob::setParentFolder( const KMFolderImap* parent )
00652 {
00653   mParentFolder = const_cast<KMFolderImap*>( parent );
00654 }
00655 
00656 //-----------------------------------------------------------------------------
00657 void ImapJob::slotProcessedSize(KIO::Job * job, KIO::filesize_t processed)
00658 {
00659   KMMessage *msg = mMsgList.first();
00660   if (!msg || !job) {
00661     return;
00662   }
00663   KMFolderImap* parent = 0;
00664   if ( msg->parent() && msg->parent()->folderType() == KMFolderTypeImap )
00665     parent = static_cast<KMFolderImap*>(msg->parent()->storage());
00666   else if (mDestFolder) // put
00667     parent = static_cast<KMFolderImap*>(mDestFolder->storage());
00668   if (!parent) return;
00669   KMAcctImap *account = parent->account();
00670   if ( !account ) return;
00671   ImapAccountBase::JobIterator it = account->findJob( job );
00672   if ( it == account->jobsEnd() ) return;
00673   (*it).done = processed;
00674   if ( (*it).progressItem ) {
00675     (*it).progressItem->setCompletedItems( processed );
00676     (*it).progressItem->updateProgress();
00677   }
00678   emit progress( (*it).done, (*it).total );
00679 }
00680 
00681 }//namespace KMail
00682 
00683 #include "imapjob.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys