kmail

imapjob.cpp
1/*
2 *
3 * This file is part of KMail, the KDE mail client.
4 * Copyright (c) 2002-2003 Zack Rusin <zack@kde.org>
5 * 2000-2002 Michael Haeckel <haeckel@kde.org>
6 *
7 * KMail is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License, version 2, as
9 * published by the Free Software Foundation.
10 *
11 * KMail is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * In addition, as a special exception, the copyright holders give
21 * permission to link the code of this program with any edition of
22 * the TQt library by Trolltech AS, Norway (or with modified versions
23 * of TQt that use the same license as TQt), and distribute linked
24 * combinations including the two. You must obey the GNU General
25 * Public License in all respects for all of the code used other than
26 * TQt. If you modify this file, you may extend this exception to
27 * your version of the file, but you are not obligated to do so. If
28 * you do not wish to do so, delete this exception statement from
29 * your version.
30 */
31
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "imapjob.h"
37#include "kmfolderimap.h"
38#include "kmfolder.h"
39#include "kmmsgpart.h"
40#include "progressmanager.h"
41using KPIM::ProgressManager;
42#include "util.h"
43
44#include <tqstylesheet.h>
45#include <tdeio/scheduler.h>
46#include <kdebug.h>
47#include <tdelocale.h>
48#include <mimelib/body.h>
49#include <mimelib/bodypart.h>
50#include <mimelib/string.h>
51
52
53namespace KMail {
54
55//-----------------------------------------------------------------------------
56ImapJob::ImapJob( KMMessage *msg, JobType jt, KMFolderImap* folder,
57 TQString partSpecifier, const AttachmentStrategy *as )
58 : FolderJob( msg, jt, folder? folder->folder() : 0, partSpecifier ),
59 mAttachmentStrategy( as ), mParentProgressItem(0)
60{
61}
62
63//-----------------------------------------------------------------------------
64ImapJob::ImapJob( TQPtrList<KMMessage>& msgList, TQString sets, JobType jt,
65 KMFolderImap* folder )
66 : FolderJob( msgList, sets, jt, folder? folder->folder() : 0 ),
67 mAttachmentStrategy ( 0 ), mParentProgressItem(0)
68{
69}
70
71void ImapJob::init( JobType jt, TQString sets, KMFolderImap* folder,
72 TQPtrList<KMMessage>& msgList )
73{
74 mJob = 0;
75
76 assert(jt == tGetMessage || folder);
77 KMMessage* msg = msgList.first();
78 // guard against empty list
79 if ( !msg ) {
80 deleteLater();
81 return;
82 }
83 mType = jt;
84 mDestFolder = folder? folder->folder() : 0;
85 // refcount++
86 if (folder) {
87 folder->open("imapjobdest");
88 }
89 KMFolder *msg_parent = msg->parent();
90 if (msg_parent) {
91 msg_parent->open("imapjobsrc");
92 }
93 mSrcFolder = msg_parent;
94 // If there is a destination folder, this is a copy, move or put to an
95 // imap folder, use its account for keeping track of the job. Otherwise,
96 // this is a get job and the src folder is an imap one. Use its account
97 // then.
98 KMAcctImap *account = 0;
99 if (folder) {
100 account = folder->account();
101 } else {
102 if ( msg_parent && msg_parent->storage() )
103 account = static_cast<KMFolderImap*>(msg_parent->storage())->account();
104 }
105 if ( !account ||
106 account->makeConnection() == ImapAccountBase::Error ) {
107 deleteLater();
108 return;
109 }
110 account->mJobList.append( this );
111 if ( jt == tPutMessage )
112 {
113 // transfers the complete message to the server
114 TQPtrListIterator<KMMessage> it( msgList );
115 KMMessage* curMsg;
116 while ( ( curMsg = it.current() ) != 0 )
117 {
118 ++it;
119 if ( mSrcFolder && !curMsg->isMessage() )
120 {
121 int idx = mSrcFolder->find( curMsg );
122 curMsg = mSrcFolder->getMsg( idx );
123 }
124 KURL url = account->getUrl();
125 TQString flags = KMFolderImap::statusToFlags( curMsg->status(), folder->permanentFlags() );
126 url.setPath( folder->imapPath() + ";SECTION=" + flags );
127 ImapAccountBase::jobData jd;
128 jd.parent = 0; jd.offset = 0; jd.done = 0;
129 jd.total = ( curMsg->msgSizeServer() > 0 ) ?
130 curMsg->msgSizeServer() : curMsg->msgSize();
131 jd.msgList.append( curMsg );
132 TQCString cstr( curMsg->asString() );
133 int a = cstr.find("\nX-UID: ");
134 int b = cstr.find('\n', a);
135 if (a != -1 && b != -1 && cstr.find("\n\n") > a) cstr.remove(a, b-a);
136 jd.data.resize( cstr.length() + cstr.contains( "\n" ) - cstr.contains( "\r\n" ) );
137 unsigned int i = 0;
138 char prevChar = '\0';
139 // according to RFC 2060 we need CRLF
140 for ( char *ch = cstr.data(); *ch; ch++ )
141 {
142 if ( *ch == '\n' && (prevChar != '\r') ) {
143 jd.data.at( i ) = '\r';
144 i++;
145 }
146 jd.data.at( i ) = *ch;
147 prevChar = *ch;
148 i++;
149 }
150 jd.progressItem = ProgressManager::createProgressItem(
151 mParentProgressItem,
152 "ImapJobUploading"+ProgressManager::getUniqueID(),
153 i18n("Uploading message data"),
154 TQStyleSheet::escape( curMsg->subject() ),
155 true,
156 account->useSSL() || account->useTLS() );
157 jd.progressItem->setTotalItems( jd.total );
158 connect ( jd.progressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
159 account, TQ_SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
160 TDEIO::SimpleJob *job = TDEIO::put( url, 0, false, false, false );
161 TDEIO::Scheduler::assignJobToSlave( account->slave(), job );
162 account->insertJob( job, jd );
163 connect( job, TQ_SIGNAL(result(TDEIO::Job *)),
164 TQ_SLOT(slotPutMessageResult(TDEIO::Job *)) );
165 connect( job, TQ_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)),
166 TQ_SLOT(slotPutMessageDataReq(TDEIO::Job *, TQByteArray &)) );
167 connect( job, TQ_SIGNAL(infoMessage(TDEIO::Job *, const TQString &)),
168 TQ_SLOT(slotPutMessageInfoData(TDEIO::Job *, const TQString &)) );
169 connect( job, TQ_SIGNAL(processedSize(TDEIO::Job *, TDEIO::filesize_t)),
170 TQ_SLOT(slotProcessedSize(TDEIO::Job *, TDEIO::filesize_t)));
171 }
172 }
173 else if ( jt == tCopyMessage || jt == tMoveMessage )
174 {
175 KURL url = account->getUrl();
176 KURL destUrl = account->getUrl();
177 destUrl.setPath(folder->imapPath());
178 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(msg_parent->storage());
179 url.setPath( imapDestFolder->imapPath() + ";UID=" + sets );
180 ImapAccountBase::jobData jd;
181 jd.parent = 0; jd.offset = 0;
182 jd.total = 1; jd.done = 0;
183 jd.msgList = msgList;
184
185 TQByteArray packedArgs;
186 TQDataStream stream( packedArgs, IO_WriteOnly );
187
188 stream << (int) 'C' << url << destUrl;
189 jd.progressItem = ProgressManager::createProgressItem(
190 mParentProgressItem,
191 "ImapJobCopyMove"+ProgressManager::getUniqueID(),
192 i18n("Server operation"),
193 i18n("Source folder: %1 - Destination folder: %2")
194 .arg( TQStyleSheet::escape( msg_parent->prettyURL() ),
195 TQStyleSheet::escape( mDestFolder->prettyURL() ) ),
196 true,
197 account->useSSL() || account->useTLS() );
198 jd.progressItem->setTotalItems( jd.total );
199 connect ( jd.progressItem, TQ_SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
200 account, TQ_SLOT( slotAbortRequested(KPIM::ProgressItem* ) ) );
201 TDEIO::SimpleJob *simpleJob = TDEIO::special( url, packedArgs, false );
202 TDEIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
203 mJob = simpleJob;
204 account->insertJob( mJob, jd );
205 connect( mJob, TQ_SIGNAL(result(TDEIO::Job *)),
206 TQ_SLOT(slotCopyMessageResult(TDEIO::Job *)) );
207 if ( jt == tMoveMessage )
208 {
209 connect( mJob, TQ_SIGNAL(infoMessage(TDEIO::Job *, const TQString &)),
210 TQ_SLOT(slotCopyMessageInfoData(TDEIO::Job *, const TQString &)) );
211 }
212 }
213 else {
214 slotGetNextMessage();
215 }
216}
217
218
219//-----------------------------------------------------------------------------
220ImapJob::~ImapJob()
221{
222 if ( mDestFolder )
223 {
224 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
225 if ( account ) {
226 if ( mJob ) {
227 ImapAccountBase::JobIterator it = account->findJob( mJob );
228 if ( it != account->jobsEnd() ) {
229 if( (*it).progressItem ) {
230 (*it).progressItem->setComplete();
231 (*it).progressItem = 0;
232 }
233 if ( !(*it).msgList.isEmpty() ) {
234 for ( TQPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
235 mit.current()->setTransferInProgress( false );
236 }
237 }
238 account->removeJob( mJob );
239 }
240 account->mJobList.remove( this );
241 }
242 mDestFolder->close("imapjobdest");
243 }
244
245 if ( mSrcFolder ) {
246 if (!mDestFolder || mDestFolder != mSrcFolder) {
247 if (! (mSrcFolder->folderType() == KMFolderTypeImap) ) return;
248 KMAcctImap *account = static_cast<KMFolderImap*>(mSrcFolder->storage())->account();
249 if ( account ) {
250 if ( mJob ) {
251 ImapAccountBase::JobIterator it = account->findJob( mJob );
252 if ( it != account->jobsEnd() ) {
253 if( (*it).progressItem ) {
254 (*it).progressItem->setComplete();
255 (*it).progressItem = 0;
256 }
257 if ( !(*it).msgList.isEmpty() ) {
258 for ( TQPtrListIterator<KMMessage> mit( (*it).msgList ); mit.current(); ++mit )
259 mit.current()->setTransferInProgress( false );
260 }
261 }
262 account->removeJob( mJob ); // remove the associated tdeio job
263 }
264 account->mJobList.remove( this ); // remove the folderjob
265 }
266 }
267 mSrcFolder->close("imapjobsrc");
268 }
269}
270
271
272//-----------------------------------------------------------------------------
273void ImapJob::slotGetNextMessage()
274{
275 KMMessage *msg = mMsgList.first();
276 KMFolderImap *msgParent = msg ? static_cast<KMFolderImap*>(msg->storage()) : 0;
277 if ( !msgParent || !msg || msg->UID() == 0 )
278 {
279 // broken message
280 emit messageRetrieved( 0 );
281 deleteLater();
282 return;
283 }
284 KMAcctImap *account = msgParent->account();
285 KURL url = account->getUrl();
286 TQString path = msgParent->imapPath() + ";UID=" + TQString::number(msg->UID());
287 ImapAccountBase::jobData jd;
288 jd.parent = 0; jd.offset = 0;
289 jd.total = 1; jd.done = 0;
290 jd.msgList.append( msg );
291 if ( !mPartSpecifier.isEmpty() )
292 {
293 if ( mPartSpecifier.find ("STRUCTURE", 0, false) != -1 ) {
294 path += ";SECTION=STRUCTURE";
295 } else if ( mPartSpecifier == "HEADER" ) {
296 path += ";SECTION=HEADER";
297 } else {
298 path += ";SECTION=BODY.PEEK[" + mPartSpecifier + "]";
299 DwBodyPart * part = msg->findDwBodyPart( msg->getFirstDwBodyPart(), mPartSpecifier );
300 if (part)
301 jd.total = part->BodySize();
302 }
303 } else {
304 path += ";SECTION=BODY.PEEK[]";
305 if (msg->msgSizeServer() > 0)
306 jd.total = msg->msgSizeServer();
307 }
308 url.setPath( path );
309// kdDebug(5006) << "ImapJob::slotGetNextMessage - retrieve " << url.path() << endl;
310 // protect the message, otherwise we'll get crashes afterwards
311 msg->setTransferInProgress( true );
312 jd.progressItem = ProgressManager::createProgressItem(
313 mParentProgressItem,
314 "ImapJobDownloading"+ProgressManager::getUniqueID(),
315 i18n("Downloading message data"),
316 i18n("Message with subject: ") +
317 TQStyleSheet::escape( msg->subject() ),
318 true,
319 account->useSSL() || account->useTLS() );
320 connect ( jd.progressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem*)),
321 account, TQ_SLOT( slotAbortRequested( KPIM::ProgressItem* ) ) );
322 jd.progressItem->setTotalItems( jd.total );
323
324 TDEIO::SimpleJob *simpleJob = TDEIO::get( url, false, false );
325 TDEIO::Scheduler::assignJobToSlave( account->slave(), simpleJob );
326 mJob = simpleJob;
327 account->insertJob( mJob, jd );
328 if ( mPartSpecifier.find( "STRUCTURE", 0, false ) != -1 )
329 {
330 connect( mJob, TQ_SIGNAL(result(TDEIO::Job *)),
331 this, TQ_SLOT(slotGetBodyStructureResult(TDEIO::Job *)) );
332 } else {
333 connect( mJob, TQ_SIGNAL(result(TDEIO::Job *)),
334 this, TQ_SLOT(slotGetMessageResult(TDEIO::Job *)) );
335 }
336 connect( mJob, TQ_SIGNAL(data(TDEIO::Job *, const TQByteArray &)),
337 msgParent, TQ_SLOT(slotSimpleData(TDEIO::Job *, const TQByteArray &)) );
338 if ( jd.total > 1 )
339 {
340 connect(mJob, TQ_SIGNAL(processedSize(TDEIO::Job *, TDEIO::filesize_t)),
341 this, TQ_SLOT(slotProcessedSize(TDEIO::Job *, TDEIO::filesize_t)));
342 }
343}
344
345
346//-----------------------------------------------------------------------------
347void ImapJob::slotGetMessageResult( TDEIO::Job * job )
348{
349 KMMessage *msg = mMsgList.first();
350 if (!msg || !msg->parent() || !job) {
351 emit messageRetrieved( 0 );
352 deleteLater();
353 return;
354 }
355 KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
356 if (msg->transferInProgress())
357 msg->setTransferInProgress( false );
358 KMAcctImap *account = parent->account();
359 if ( !account ) {
360 emit messageRetrieved( 0 );
361 deleteLater();
362 return;
363 }
364 ImapAccountBase::JobIterator it = account->findJob( job );
365 if ( it == account->jobsEnd() ) return;
366
367 bool gotData = true;
368 if (job->error())
369 {
370 TQString errorStr = i18n( "Error while retrieving messages from the server." );
371 if ( (*it).progressItem )
372 (*it).progressItem->setStatus( errorStr );
373 account->handleJobError( job, errorStr );
374 return;
375 } else {
376 if ((*it).data.size() > 0)
377 {
378 kdDebug(5006) << "ImapJob::slotGetMessageResult - retrieved part " << mPartSpecifier << endl;
379 if ( mPartSpecifier.isEmpty() ||
380 mPartSpecifier == "HEADER" )
381 {
382 uint size = msg->msgSizeServer();
383 if ( size > 0 && mPartSpecifier.isEmpty() )
384 (*it).done = size;
385 ulong uid = msg->UID();
386 // must set this first so that msg->fromByteArray sets the attachment status
387 if ( mPartSpecifier.isEmpty() )
388 msg->setComplete( true );
389 else
390 msg->setReadyToShow( false );
391
392 // Convert CR/LF to LF.
393 size_t dataSize = (*it).data.size();
394 dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
395 (*it).data.resize( dataSize );
396
397 // During the construction of the message from the byteArray it does
398 // not have a uid. Therefore we have to make sure that no connected
399 // slots are called, since they would operate on uid == 0.
400 msg->parent()->storage()->blockSignals( true );
401 msg->fromByteArray( (*it).data );
402 // now let others react
403 msg->parent()->storage()->blockSignals( false );
404 if ( size > 0 && msg->msgSizeServer() == 0 ) {
405 msg->setMsgSizeServer(size);
406 }
407 // reconstruct the UID as it gets overwritten above
408 msg->setUID(uid);
409
410 } else {
411 // Convert CR/LF to LF.
412 size_t dataSize = (*it).data.size();
413 dataSize = Util::crlf2lf( (*it).data.data(), dataSize ); // always <=
414 (*it).data.resize( dataSize );
415
416 // Update the body of the retrieved part (the message notifies all observers)
417 msg->updateBodyPart( mPartSpecifier, (*it).data );
418 msg->setReadyToShow( true );
419 // Update the attachment state, we have to do this for every part as we actually
420 // do not know if the message has no attachment or we simply did not load the header
421 if (msg->attachmentState() != KMMsgHasAttachment)
422 msg->updateAttachmentState();
423 if (msg->invitationState() != KMMsgHasInvitation)
424 msg->updateInvitationState();
425 }
426 } else {
427 kdDebug(5006) << "ImapJob::slotGetMessageResult - got no data for " << mPartSpecifier << endl;
428 gotData = false;
429 msg->setReadyToShow( true );
430 // nevertheless give visual feedback
431 msg->notify();
432 }
433 }
434 if (account->slave()) {
435 account->removeJob(it);
436 account->mJobList.remove(this);
437 }
438 /* This needs to be emitted last, so the slots that are hooked to it
439 * don't unGetMsg the msg before we have finished. */
440 if ( mPartSpecifier.isEmpty() ||
441 mPartSpecifier == "HEADER" )
442 {
443 if ( gotData )
444 emit messageRetrieved(msg);
445 else
446 {
447 /* we got an answer but not data
448 * this means that the msg is not on the server anymore so delete it */
449 emit messageRetrieved( 0 );
450 parent->ignoreJobsForMessage( msg );
451 int idx = parent->find( msg );
452 if (idx != -1) parent->removeMsg( idx, true );
453 // the removeMsg will unGet the message, which will delete all
454 // jobs, including this one
455 return;
456 }
457 } else {
458 emit messageUpdated(msg, mPartSpecifier);
459 }
460 deleteLater();
461}
462
463//-----------------------------------------------------------------------------
464void ImapJob::slotGetBodyStructureResult( TDEIO::Job * job )
465{
466 KMMessage *msg = mMsgList.first();
467 if (!msg || !msg->parent() || !job) {
468 deleteLater();
469 return;
470 }
471 KMFolderImap* parent = static_cast<KMFolderImap*>(msg->storage());
472 if (msg->transferInProgress())
473 msg->setTransferInProgress( false );
474 KMAcctImap *account = parent->account();
475 if ( !account ) {
476 deleteLater();
477 return;
478 }
479 ImapAccountBase::JobIterator it = account->findJob( job );
480 if ( it == account->jobsEnd() ) return;
481
482
483 if (job->error())
484 {
485 account->handleJobError( job, i18n( "Error while retrieving information on the structure of a message." ) );
486 return;
487 } else {
488 if ((*it).data.size() > 0)
489 {
490 TQDataStream stream( (*it).data, IO_ReadOnly );
491 account->handleBodyStructure(stream, msg, mAttachmentStrategy);
492 }
493 }
494 if (account->slave()) {
495 account->removeJob(it);
496 account->mJobList.remove(this);
497 }
498 deleteLater();
499}
500
501//-----------------------------------------------------------------------------
502void ImapJob::slotPutMessageDataReq( TDEIO::Job *job, TQByteArray &data )
503{
504 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
505 if ( !account )
506 {
507 emit finished();
508 deleteLater();
509 return;
510 }
511 ImapAccountBase::JobIterator it = account->findJob( job );
512 if ( it == account->jobsEnd() ) return;
513
514 if ((*it).data.size() - (*it).offset > 0x8000)
515 {
516 data.duplicate((*it).data.data() + (*it).offset, 0x8000);
517 (*it).offset += 0x8000;
518 }
519 else if ((*it).data.size() - (*it).offset > 0)
520 {
521 data.duplicate((*it).data.data() + (*it).offset, (*it).data.size() - (*it).offset);
522 (*it).offset = (*it).data.size();
523 } else data.resize(0);
524}
525
526
527//-----------------------------------------------------------------------------
528void ImapJob::slotPutMessageResult( TDEIO::Job *job )
529{
530 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
531 if ( !account )
532 {
533 emit finished();
534 deleteLater();
535 return;
536 }
537 ImapAccountBase::JobIterator it = account->findJob( job );
538 if ( it == account->jobsEnd() ) return;
539 bool deleteMe = false;
540 if (job->error())
541 {
542 if ( (*it).progressItem )
543 (*it).progressItem->setStatus( i18n("Uploading message data failed.") );
544 account->handlePutError( job, *it, mDestFolder );
545 return;
546 } else {
547 if ( (*it).progressItem )
548 (*it).progressItem->setStatus( i18n("Uploading message data completed.") );
549 if ( mParentProgressItem )
550 {
551 mParentProgressItem->incCompletedItems();
552 mParentProgressItem->updateProgress();
553 }
554 KMMessage *msg = (*it).msgList.first();
555 emit messageStored( msg );
556 if ( msg == mMsgList.getLast() )
557 {
558 emit messageCopied( mMsgList );
559 if (account->slave()) {
560 account->mJobList.remove( this );
561 }
562 deleteMe = true;
563 }
564 }
565 if (account->slave()) {
566 account->removeJob( it ); // also clears progressitem
567 }
568 if ( deleteMe )
569 deleteLater();
570}
571
572//-----------------------------------------------------------------------------
573void ImapJob::slotCopyMessageInfoData(TDEIO::Job * job, const TQString & data)
574{
575 KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
576 KMAcctImap *account = imapFolder->account();
577 if ( !account )
578 {
579 emit finished();
580 deleteLater();
581 return;
582 }
583 ImapAccountBase::JobIterator it = account->findJob( job );
584 if ( it == account->jobsEnd() ) return;
585
586 if (data.find("UID") != -1)
587 {
588 // split
589 TQString oldUid = data.section(' ', 1, 1);
590 TQString newUid = data.section(' ', 2, 2);
591
592 // get lists of uids
593 TQValueList<ulong> olduids = KMFolderImap::splitSets(oldUid);
594 TQValueList<ulong> newuids = KMFolderImap::splitSets(newUid);
595
596 int index = -1;
597 KMMessage * msg;
598 for ( msg = (*it).msgList.first(); msg; msg = (*it).msgList.next() )
599 {
600 ulong uid = msg->UID();
601 index = olduids.findIndex(uid);
602 if (index > -1)
603 {
604 // found, get the new uid
605 imapFolder->saveMsgMetaData( msg, newuids[index] );
606 }
607 }
608 }
609}
610
611//----------------------------------------------------------------------------
612void ImapJob::slotPutMessageInfoData(TDEIO::Job *job, const TQString &data)
613{
614 KMFolderImap * imapFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
615 KMAcctImap *account = imapFolder->account();
616 if ( !account )
617 {
618 emit finished();
619 deleteLater();
620 return;
621 }
622 ImapAccountBase::JobIterator it = account->findJob( job );
623 if ( it == account->jobsEnd() ) return;
624
625 if ( data.find("UID") != -1 )
626 {
627 ulong uid = ( data.right(data.length()-4) ).toInt();
628 if ( !(*it).msgList.isEmpty() )
629 {
630 imapFolder->saveMsgMetaData( (*it).msgList.first(), uid );
631 }
632 }
633}
634
635
636//-----------------------------------------------------------------------------
637void ImapJob::slotCopyMessageResult( TDEIO::Job *job )
638{
639 KMAcctImap *account = static_cast<KMFolderImap*>(mDestFolder->storage())->account();
640 if ( !account )
641 {
642 emit finished();
643 deleteLater();
644 return;
645 }
646 ImapAccountBase::JobIterator it = account->findJob( job );
647 if ( it == account->jobsEnd() ) return;
648
649 if (job->error())
650 {
651 mErrorCode = job->error();
652 TQString errStr = i18n("Error while copying messages.");
653 if ( (*it).progressItem )
654 (*it).progressItem->setStatus( errStr );
655 if ( account->handleJobError( job, errStr ) )
656 deleteLater();
657 return;
658 } else {
659 if ( !(*it).msgList.isEmpty() )
660 {
661 emit messageCopied((*it).msgList);
662 } else if (mMsgList.first()) {
663 emit messageCopied(mMsgList.first());
664 }
665 }
666 if (account->slave()) {
667 account->removeJob(it);
668 account->mJobList.remove(this);
669 }
670 deleteLater();
671}
672
673//-----------------------------------------------------------------------------
674void ImapJob::execute()
675{
676 init( mType, mSets, mDestFolder?
677 dynamic_cast<KMFolderImap*>( mDestFolder->storage() ):0, mMsgList );
678}
679
680//-----------------------------------------------------------------------------
681void ImapJob::setParentFolder( const KMFolderImap* parent )
682{
683 mParentFolder = const_cast<KMFolderImap*>( parent );
684}
685
686//-----------------------------------------------------------------------------
687void ImapJob::slotProcessedSize(TDEIO::Job * job, TDEIO::filesize_t processed)
688{
689 KMMessage *msg = mMsgList.first();
690 if (!msg || !job) {
691 return;
692 }
693 KMFolderImap* parent = 0;
694 if ( msg->parent() && msg->parent()->folderType() == KMFolderTypeImap )
695 parent = static_cast<KMFolderImap*>(msg->parent()->storage());
696 else if (mDestFolder) // put
697 parent = static_cast<KMFolderImap*>(mDestFolder->storage());
698 if (!parent) return;
699 KMAcctImap *account = parent->account();
700 if ( !account ) return;
701 ImapAccountBase::JobIterator it = account->findJob( job );
702 if ( it == account->jobsEnd() ) return;
703 (*it).done = processed;
704 if ( (*it).progressItem ) {
705 (*it).progressItem->setCompletedItems( processed );
706 (*it).progressItem->updateProgress();
707 }
708 emit progress( (*it).done, (*it).total );
709}
710
711}//namespace KMail
712
713#include "imapjob.moc"
Mail folder.
Definition: kmfolder.h:69
virtual TQString prettyURL() const
URL of the node for visualization purposes.
Definition: kmfolder.cpp:593
int open(const char *owner)
Open folder for access.
Definition: kmfolder.cpp:479
This is a Mime Message.
Definition: kmmessage.h:68
void updateBodyPart(const TQString partSpecifier, const TQByteArray &data)
Sets the body of the specified part.
Definition: kmmessage.cpp:4270
DwBodyPart * getFirstDwBodyPart() const
Get the 1st DwBodyPart.
Definition: kmmessage.cpp:2848
void setReadyToShow(bool v)
Set if the message is ready to be shown.
Definition: kmmessage.h:874
size_t msgSizeServer() const
Get/set size on server.
Definition: kmmessage.cpp:2212
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
Definition: kmmessage.cpp:243
TQString subject() const
Get or set the 'Subject' header field.
Definition: kmmessage.cpp:2049
TQCString asString() const
Return the entire message contents as a string.
Definition: kmmessage.cpp:314
bool transferInProgress() const
Return, if the message should not be deleted.
Definition: kmmessage.cpp:236
bool isMessage() const
Returns TRUE if object is a real message (not KMMsgInfo or KMMsgBase)
Definition: kmmessage.cpp:230
void setComplete(bool v)
Set if the message is a complete message.
Definition: kmmessage.h:869
KMMsgStatus status() const
Status of the message.
Definition: kmmessage.h:830
size_t msgSize() const
Get/set size of message in the folder including the whole header in bytes.
Definition: kmmessage.h:812
ulong UID() const
Get/set UID.
Definition: kmmessage.cpp:2225
DwBodyPart * findDwBodyPart(int type, int subtype) const
Return the first DwBodyPart matching a given Content-Type or zero, if no found.
Definition: kmmessage.cpp:2935
folderdiaquotatab.h
Definition: aboutdata.cpp:40