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.
DwBodyPart * getFirstDwBodyPart() const
Get the 1st DwBodyPart.
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.
void setTransferInProgress(bool value, bool force=false)
Set that the message shall not be deleted because it is still required.
TQString subject() const
Get or set the 'Subject' header field.
TQCString asString() const
Return the entire message contents as a string.
bool transferInProgress() const
Return, if the message should not be deleted.
bool isMessage() const
Returns true if object is a real message (not KMMsgInfo or KMMsgBase)
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.
DwBodyPart * findDwBodyPart(int type, int subtype) const
Return the first DwBodyPart matching a given Content-Type or zero, if no found.
folderdiaquotatab.h
Definition aboutdata.cpp:40