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"
41 using 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 
53 namespace KMail {
54 
55 //-----------------------------------------------------------------------------
56 ImapJob::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 //-----------------------------------------------------------------------------
64 ImapJob::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 
71 void 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 //-----------------------------------------------------------------------------
220 ImapJob::~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 //-----------------------------------------------------------------------------
273 void 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 //-----------------------------------------------------------------------------
347 void 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 //-----------------------------------------------------------------------------
464 void 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 //-----------------------------------------------------------------------------
502 void 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 //-----------------------------------------------------------------------------
528 void 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 //-----------------------------------------------------------------------------
573 void 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 //----------------------------------------------------------------------------
612 void 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 //-----------------------------------------------------------------------------
637 void 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 //-----------------------------------------------------------------------------
674 void ImapJob::execute()
675 {
676  init( mType, mSets, mDestFolder?
677  dynamic_cast<KMFolderImap*>( mDestFolder->storage() ):0, mMsgList );
678 }
679 
680 //-----------------------------------------------------------------------------
681 void ImapJob::setParentFolder( const KMFolderImap* parent )
682 {
683  mParentFolder = const_cast<KMFolderImap*>( parent );
684 }
685 
686 //-----------------------------------------------------------------------------
687 void 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