00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "kmcommands.h"
00044
00045 #ifdef HAVE_CONFIG_H
00046 #include <config.h>
00047 #endif
00048
00049 #include <errno.h>
00050 #include <mimelib/enum.h>
00051 #include <mimelib/field.h>
00052 #include <mimelib/mimepp.h>
00053 #include <mimelib/string.h>
00054 #include <tdeapplication.h>
00055 #include <dcopclient.h>
00056
00057 #include <tqtextcodec.h>
00058 #include <tqpopupmenu.h>
00059 #include <tqeventloop.h>
00060
00061 #include <libemailfunctions/email.h>
00062 #include <kdcopservicestarter.h>
00063 #include <kdebug.h>
00064 #include <tdefiledialog.h>
00065 #include <tdeabc/stdaddressbook.h>
00066 #include <tdeabc/addresseelist.h>
00067 #include <kdirselectdialog.h>
00068 #include <tdelocale.h>
00069 #include <tdemessagebox.h>
00070 #include <tdeparts/browserextension.h>
00071 #include <kprogress.h>
00072 #include <krun.h>
00073 #include <kbookmarkmanager.h>
00074 #include <kstandarddirs.h>
00075 #include <tdetempfile.h>
00076 #include <tdeimproxy.h>
00077 #include <kuserprofile.h>
00078
00079 #include <tdeio/job.h>
00080 #include <tdeio/netaccess.h>
00081
00082 #include <libkpimidentities/identitymanager.h>
00083
00084 #include "actionscheduler.h"
00085 using KMail::ActionScheduler;
00086 #include "mailinglist-magic.h"
00087 #include "kmaddrbook.h"
00088 #include <kaddrbook.h>
00089 #include "composer.h"
00090 #include "kmfiltermgr.h"
00091 #include "kmfoldermbox.h"
00092 #include "kmfolderimap.h"
00093 #include "kmfoldermgr.h"
00094 #include "kmheaders.h"
00095 #include "headeritem.h"
00096 #include "kmmainwidget.h"
00097 #include "kmmsgdict.h"
00098 #include "messagesender.h"
00099 #include "kmmsgpartdlg.h"
00100 #include "undostack.h"
00101 #include "kcursorsaver.h"
00102 #include "partNode.h"
00103 #include "objecttreeparser.h"
00104 #include "csshelper.h"
00105 using KMail::ObjectTreeParser;
00106 using KMail::FolderJob;
00107 #include "chiasmuskeyselector.h"
00108 #include "mailsourceviewer.h"
00109 using KMail::MailSourceViewer;
00110 #include "kmreadermainwin.h"
00111 #include "secondarywindow.h"
00112 using KMail::SecondaryWindow;
00113 #include "redirectdialog.h"
00114 using KMail::RedirectDialog;
00115 #include "util.h"
00116 #include "templateparser.h"
00117 #include "editorwatcher.h"
00118 #include "korghelper.h"
00119
00120 #include "broadcaststatus.h"
00121 #include "globalsettings.h"
00122
00123 #include <libtdepim/tdefileio.h>
00124 #include "kcalendariface_stub.h"
00125
00126 #include "progressmanager.h"
00127 using KPIM::ProgressManager;
00128 using KPIM::ProgressItem;
00129 #include <kmime_mdn.h>
00130 using namespace KMime;
00131
00132 #include <kleo/specialjob.h>
00133 #include <kleo/cryptobackend.h>
00134 #include <kleo/cryptobackendfactory.h>
00135
00136 #include <tqclipboard.h>
00137
00138 #include <memory>
00139
00140 class LaterDeleterWithCommandCompletion : public KMail::Util::LaterDeleter
00141 {
00142 public:
00143 LaterDeleterWithCommandCompletion( KMCommand* command )
00144 :LaterDeleter( command ), m_result( KMCommand::Failed )
00145 {
00146 }
00147 ~LaterDeleterWithCommandCompletion()
00148 {
00149 setResult( m_result );
00150 KMCommand *command = static_cast<KMCommand*>( m_object );
00151 emit command->completed( command );
00152 }
00153 void setResult( KMCommand::Result v ) { m_result = v; }
00154 private:
00155 KMCommand::Result m_result;
00156 };
00157
00158
00159 KMCommand::KMCommand( TQWidget *parent )
00160 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00161 mEmitsCompletedItself( false ), mParent( parent )
00162 {
00163 }
00164
00165 KMCommand::KMCommand( TQWidget *parent, const TQPtrList<KMMsgBase> &msgList )
00166 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00167 mEmitsCompletedItself( false ), mParent( parent ), mMsgList( msgList )
00168 {
00169 }
00170
00171 KMCommand::KMCommand( TQWidget *parent, KMMsgBase *msgBase )
00172 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00173 mEmitsCompletedItself( false ), mParent( parent )
00174 {
00175 mMsgList.append( msgBase );
00176 }
00177
00178 KMCommand::KMCommand( TQWidget *parent, KMMessage *msg )
00179 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00180 mEmitsCompletedItself( false ), mParent( parent )
00181 {
00182 if (msg)
00183 mMsgList.append( &msg->toMsgBase() );
00184 }
00185
00186 KMCommand::~KMCommand()
00187 {
00188 TQValueListIterator<TQGuardedPtr<KMFolder> > fit;
00189 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
00190 if (!(*fit))
00191 continue;
00192 (*fit)->close("kmcommand");
00193 }
00194 }
00195
00196 KMCommand::Result KMCommand::result()
00197 {
00198 if ( mResult == Undefined )
00199 kdDebug(5006) << k_funcinfo << "mResult is Undefined" << endl;
00200 return mResult;
00201 }
00202
00203 void KMCommand::start()
00204 {
00205 TQTimer::singleShot( 0, this, TQT_SLOT( slotStart() ) );
00206 }
00207
00208
00209 const TQPtrList<KMMessage> KMCommand::retrievedMsgs() const
00210 {
00211 return mRetrievedMsgs;
00212 }
00213
00214 KMMessage *KMCommand::retrievedMessage() const
00215 {
00216 return mRetrievedMsgs.getFirst();
00217 }
00218
00219 TQWidget *KMCommand::parentWidget() const
00220 {
00221 return mParent;
00222 }
00223
00224 int KMCommand::mCountJobs = 0;
00225
00226 void KMCommand::slotStart()
00227 {
00228 connect( this, TQT_SIGNAL( messagesTransfered( KMCommand::Result ) ),
00229 this, TQT_SLOT( slotPostTransfer( KMCommand::Result ) ) );
00230 kmkernel->filterMgr()->ref();
00231
00232 if (mMsgList.find(0) != -1) {
00233 emit messagesTransfered( Failed );
00234 return;
00235 }
00236
00237 if ((mMsgList.count() == 1) &&
00238 (mMsgList.getFirst()->isMessage()) &&
00239 (mMsgList.getFirst()->parent() == 0))
00240 {
00241
00242 mRetrievedMsgs.append((KMMessage*)mMsgList.getFirst());
00243 emit messagesTransfered( OK );
00244 return;
00245 }
00246
00247 for ( KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next() ) {
00248 if ( mb ) {
00249 if ( !mb->parent() ) {
00250 emit messagesTransfered( Failed );
00251 return;
00252 } else {
00253 keepFolderOpen( mb->parent() );
00254 }
00255 }
00256 }
00257
00258
00259 transferSelectedMsgs();
00260 }
00261
00262 void KMCommand::slotPostTransfer( KMCommand::Result result )
00263 {
00264 disconnect( this, TQT_SIGNAL( messagesTransfered( KMCommand::Result ) ),
00265 this, TQT_SLOT( slotPostTransfer( KMCommand::Result ) ) );
00266 if ( result == OK )
00267 result = execute();
00268 mResult = result;
00269 TQPtrListIterator<KMMessage> it( mRetrievedMsgs );
00270 KMMessage* msg;
00271 while ( (msg = it.current()) != 0 )
00272 {
00273 ++it;
00274 if (msg->parent())
00275 msg->setTransferInProgress(false);
00276 }
00277 kmkernel->filterMgr()->deref();
00278 if ( !emitsCompletedItself() )
00279 emit completed( this );
00280 if ( !deletesItself() )
00281 deleteLater();
00282 }
00283
00284 void KMCommand::transferSelectedMsgs()
00285 {
00286
00287 if (KMCommand::mCountJobs > 0) {
00288 emit messagesTransfered( Failed );
00289 return;
00290 }
00291
00292 bool complete = true;
00293 KMCommand::mCountJobs = 0;
00294 mCountMsgs = 0;
00295 mRetrievedMsgs.clear();
00296 mCountMsgs = mMsgList.count();
00297 uint totalSize = 0;
00298
00299
00300
00301
00302 if ( mCountMsgs > 0 ) {
00303 mProgressDialog = new KProgressDialog(mParent, "transferProgress",
00304 i18n("Please wait"),
00305 i18n("Please wait while the message is transferred",
00306 "Please wait while the %n messages are transferred", mMsgList.count()),
00307 true);
00308 mProgressDialog->setMinimumDuration(1000);
00309 }
00310 for (KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next())
00311 {
00312
00313 KMMessage *thisMsg = 0;
00314 if ( mb->isMessage() )
00315 thisMsg = static_cast<KMMessage*>(mb);
00316 else
00317 {
00318 KMFolder *folder = mb->parent();
00319 int idx = folder->find(mb);
00320 if (idx < 0) continue;
00321 thisMsg = folder->getMsg(idx);
00322 }
00323 if (!thisMsg) continue;
00324 if ( thisMsg->transferInProgress() &&
00325 thisMsg->parent()->folderType() == KMFolderTypeImap )
00326 {
00327 thisMsg->setTransferInProgress( false, true );
00328 thisMsg->parent()->ignoreJobsForMessage( thisMsg );
00329 }
00330
00331 if ( thisMsg->parent() && !thisMsg->isComplete() &&
00332 ( !mProgressDialog || !mProgressDialog->wasCancelled() ) )
00333 {
00334 kdDebug(5006)<<"### INCOMPLETE\n";
00335
00336 complete = false;
00337 KMCommand::mCountJobs++;
00338 FolderJob *job = thisMsg->parent()->createJob(thisMsg);
00339 job->setCancellable( false );
00340 totalSize += thisMsg->msgSizeServer();
00341
00342 connect(job, TQT_SIGNAL(messageRetrieved(KMMessage*)),
00343 this, TQT_SLOT(slotMsgTransfered(KMMessage*)));
00344
00345 connect(job, TQT_SIGNAL(finished()),
00346 this, TQT_SLOT(slotJobFinished()));
00347 connect(job, TQT_SIGNAL(progress(unsigned long, unsigned long)),
00348 this, TQT_SLOT(slotProgress(unsigned long, unsigned long)));
00349
00350 thisMsg->setTransferInProgress(true);
00351 job->start();
00352 } else {
00353 thisMsg->setTransferInProgress(true);
00354 mRetrievedMsgs.append(thisMsg);
00355 }
00356 }
00357
00358 if (complete)
00359 {
00360 delete mProgressDialog;
00361 mProgressDialog = 0;
00362 emit messagesTransfered( OK );
00363 } else {
00364
00365 if ( mProgressDialog ) {
00366 connect(mProgressDialog, TQT_SIGNAL(cancelClicked()),
00367 this, TQT_SLOT(slotTransferCancelled()));
00368 mProgressDialog->progressBar()->setTotalSteps(totalSize);
00369 }
00370 }
00371 }
00372
00373 void KMCommand::slotMsgTransfered(KMMessage* msg)
00374 {
00375 if ( mProgressDialog && mProgressDialog->wasCancelled() ) {
00376 emit messagesTransfered( Canceled );
00377 return;
00378 }
00379
00380
00381 mRetrievedMsgs.append(msg);
00382 }
00383
00384 void KMCommand::slotProgress( unsigned long done, unsigned long )
00385 {
00386 mProgressDialog->progressBar()->setProgress( done );
00387 }
00388
00389 void KMCommand::slotJobFinished()
00390 {
00391
00392 KMCommand::mCountJobs--;
00393
00394 if ( mProgressDialog && mProgressDialog->wasCancelled() ) return;
00395
00396 if ( (mCountMsgs - static_cast<int>(mRetrievedMsgs.count())) > KMCommand::mCountJobs )
00397 {
00398
00399 if ( mProgressDialog )
00400 mProgressDialog->hide();
00401 slotTransferCancelled();
00402 return;
00403 }
00404
00405 if ( mProgressDialog ) {
00406 mProgressDialog->setLabel(i18n("Please wait while the message is transferred",
00407 "Please wait while the %n messages are transferred", KMCommand::mCountJobs));
00408 }
00409 if (KMCommand::mCountJobs == 0)
00410 {
00411
00412 delete mProgressDialog;
00413 mProgressDialog = 0;
00414 emit messagesTransfered( OK );
00415 }
00416 }
00417
00418 void KMCommand::slotTransferCancelled()
00419 {
00420
00421 TQValueListIterator<TQGuardedPtr<KMFolder> > fit;
00422 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
00423 if (!(*fit))
00424 continue;
00425 KMFolder *folder = *fit;
00426 KMFolderImap *imapFolder = dynamic_cast<KMFolderImap*>(folder);
00427 if (imapFolder && imapFolder->account()) {
00428 imapFolder->account()->killAllJobs();
00429 }
00430 }
00431
00432 KMCommand::mCountJobs = 0;
00433 mCountMsgs = 0;
00434
00435 TQPtrListIterator<KMMessage> it( mRetrievedMsgs );
00436 KMMessage* msg;
00437 while ( (msg = it.current()) != 0 )
00438 {
00439 KMFolder *folder = msg->parent();
00440 ++it;
00441 if (!folder)
00442 continue;
00443 msg->setTransferInProgress(false);
00444 int idx = folder->find(msg);
00445 if (idx > 0) folder->unGetMsg(idx);
00446 }
00447 mRetrievedMsgs.clear();
00448 emit messagesTransfered( Canceled );
00449 }
00450
00451 void KMCommand::keepFolderOpen( KMFolder *folder )
00452 {
00453 folder->open( "kmcommand" );
00454 mFolders.append( folder );
00455 }
00456
00457 KMMailtoComposeCommand::KMMailtoComposeCommand( const KURL &url,
00458 KMMessage *msg )
00459 :mUrl( url ), mMessage( msg )
00460 {
00461 }
00462
00463 KMCommand::Result KMMailtoComposeCommand::execute()
00464 {
00465 KMMessage *msg = new KMMessage;
00466 uint id = 0;
00467
00468 if ( mMessage && mMessage->parent() )
00469 id = mMessage->parent()->identity();
00470
00471 msg->initHeader(id);
00472 msg->setCharset("utf-8");
00473 msg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00474
00475 KMail::Composer * win = KMail::makeComposer( msg, id );
00476 win->setCharset("", true);
00477 win->setFocusToSubject();
00478 win->show();
00479
00480 return OK;
00481 }
00482
00483
00484 KMMailtoReplyCommand::KMMailtoReplyCommand( TQWidget *parent,
00485 const KURL &url, KMMessage *msg, const TQString &selection )
00486 :KMCommand( parent, msg ), mUrl( url ), mSelection( selection )
00487 {
00488 }
00489
00490 KMCommand::Result KMMailtoReplyCommand::execute()
00491 {
00492
00493 KMMessage *msg = retrievedMessage();
00494 if ( !msg || !msg->codec() ) {
00495 return Failed;
00496 }
00497 KMMessage *rmsg = msg->createReply( KMail::ReplyNone, mSelection );
00498 rmsg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00499
00500 KMail::Composer * win = KMail::makeComposer( rmsg, 0 );
00501 win->setCharset(msg->codec()->mimeName(), true);
00502 win->setReplyFocus();
00503 win->show();
00504
00505 return OK;
00506 }
00507
00508
00509 KMMailtoForwardCommand::KMMailtoForwardCommand( TQWidget *parent,
00510 const KURL &url, KMMessage *msg )
00511 :KMCommand( parent, msg ), mUrl( url )
00512 {
00513 }
00514
00515 KMCommand::Result KMMailtoForwardCommand::execute()
00516 {
00517
00518 KMMessage *msg = retrievedMessage();
00519 if ( !msg || !msg->codec() ) {
00520 return Failed;
00521 }
00522 KMMessage *fmsg = msg->createForward();
00523 fmsg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00524
00525 KMail::Composer * win = KMail::makeComposer( fmsg );
00526 win->setCharset(msg->codec()->mimeName(), true);
00527 win->show();
00528
00529 return OK;
00530 }
00531
00532
00533 KMAddBookmarksCommand::KMAddBookmarksCommand( const KURL &url, TQWidget *parent )
00534 : KMCommand( parent ), mUrl( url )
00535 {
00536 }
00537
00538 KMCommand::Result KMAddBookmarksCommand::execute()
00539 {
00540 TQString filename = locateLocal( "data", TQString::fromLatin1("konqueror/bookmarks.xml") );
00541 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename,
00542 false );
00543 KBookmarkGroup group = bookManager->root();
00544 group.addBookmark( bookManager, mUrl.path(), KURL( mUrl ) );
00545 if( bookManager->save() ) {
00546 bookManager->emitChanged( group );
00547 }
00548
00549 return OK;
00550 }
00551
00552 KMMailtoAddAddrBookCommand::KMMailtoAddAddrBookCommand( const KURL &url,
00553 TQWidget *parent )
00554 : KMCommand( parent ), mUrl( url )
00555 {
00556 }
00557
00558 KMCommand::Result KMMailtoAddAddrBookCommand::execute()
00559 {
00560 KAddrBookExternal::addEmail( KMMessage::decodeMailtoUrl( mUrl.path() ),
00561 parentWidget() );
00562
00563 return OK;
00564 }
00565
00566
00567 KMMailtoOpenAddrBookCommand::KMMailtoOpenAddrBookCommand( const KURL &url,
00568 TQWidget *parent )
00569 : KMCommand( parent ), mUrl( url )
00570 {
00571 }
00572
00573 KMCommand::Result KMMailtoOpenAddrBookCommand::execute()
00574 {
00575 KAddrBookExternal::openEmail( KMMessage::decodeMailtoUrl( mUrl.path() ),
00576 parentWidget() );
00577
00578 return OK;
00579 }
00580
00581
00582 KMUrlCopyCommand::KMUrlCopyCommand( const KURL &url, KMMainWidget *mainWidget )
00583 :mUrl( url ), mMainWidget( mainWidget )
00584 {
00585 }
00586
00587 KMCommand::Result KMUrlCopyCommand::execute()
00588 {
00589 TQClipboard* clip = TQApplication::clipboard();
00590
00591 if (mUrl.protocol() == "mailto") {
00592
00593 TQString address = KMMessage::decodeMailtoUrl( mUrl.path() );
00594 clip->setSelectionMode( true );
00595 clip->setText( address );
00596 clip->setSelectionMode( false );
00597 clip->setText( address );
00598 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n( "Address copied to clipboard." ));
00599 } else {
00600
00601 clip->setSelectionMode( true );
00602 clip->setText( mUrl.url() );
00603 clip->setSelectionMode( false );
00604 clip->setText( mUrl.url() );
00605 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n( "URL copied to clipboard." ));
00606 }
00607
00608 return OK;
00609 }
00610
00611
00612 KMUrlOpenCommand::KMUrlOpenCommand( const KURL &url, KMReaderWin *readerWin )
00613 :mUrl( url ), mReaderWin( readerWin )
00614 {
00615 }
00616
00617 KMCommand::Result KMUrlOpenCommand::execute()
00618 {
00619 if ( !mUrl.isEmpty() )
00620 mReaderWin->slotUrlOpen( mUrl, KParts::URLArgs() );
00621
00622 return OK;
00623 }
00624
00625
00626 KMUrlSaveCommand::KMUrlSaveCommand( const KURL &url, TQWidget *parent )
00627 : KMCommand( parent ), mUrl( url )
00628 {
00629 }
00630
00631 KMCommand::Result KMUrlSaveCommand::execute()
00632 {
00633 if ( mUrl.isEmpty() )
00634 return OK;
00635 KURL saveUrl = KFileDialog::getSaveURL(mUrl.fileName(), TQString(),
00636 parentWidget() );
00637 if ( saveUrl.isEmpty() )
00638 return Canceled;
00639 if ( TDEIO::NetAccess::exists( saveUrl, false, parentWidget() ) )
00640 {
00641 if (KMessageBox::warningContinueCancel(0,
00642 i18n("<qt>File <b>%1</b> exists.<br>Do you want to replace it?</qt>")
00643 .arg(saveUrl.prettyURL()), i18n("Save to File"), i18n("&Replace"))
00644 != KMessageBox::Continue)
00645 return Canceled;
00646 }
00647 TDEIO::Job *job = TDEIO::file_copy(mUrl, saveUrl, -1, true);
00648 connect(job, TQT_SIGNAL(result(TDEIO::Job*)), TQT_SLOT(slotUrlSaveResult(TDEIO::Job*)));
00649 setEmitsCompletedItself( true );
00650 return OK;
00651 }
00652
00653 void KMUrlSaveCommand::slotUrlSaveResult( TDEIO::Job *job )
00654 {
00655 if ( job->error() ) {
00656 job->showErrorDialog();
00657 setResult( Failed );
00658 emit completed( this );
00659 }
00660 else {
00661 setResult( OK );
00662 emit completed( this );
00663 }
00664 }
00665
00666
00667 KMEditMsgCommand::KMEditMsgCommand( TQWidget *parent, KMMessage *msg )
00668 :KMCommand( parent, msg )
00669 {
00670 }
00671
00672 KMCommand::Result KMEditMsgCommand::execute()
00673 {
00674 KMMessage *msg = retrievedMessage();
00675 if ( !msg || !msg->parent() ||
00676 ( !kmkernel->folderIsDraftOrOutbox( msg->parent() ) &&
00677 !kmkernel->folderIsTemplates( msg->parent() ) ) )
00678 return Failed;
00679
00680
00681
00682
00683 KMFolder *parent = msg->parent();
00684 if ( parent )
00685 parent->take( parent->find( msg ) );
00686
00687 KMail::Composer * win = KMail::makeComposer();
00688 msg->setTransferInProgress(false);
00689 win->setMsg(msg, false, true);
00690 win->setFolder( parent );
00691 win->show();
00692
00693 return OK;
00694 }
00695
00696 KMUseTemplateCommand::KMUseTemplateCommand( TQWidget *parent, KMMessage *msg )
00697 :KMCommand( parent, msg )
00698 {
00699 }
00700
00701 KMCommand::Result KMUseTemplateCommand::execute()
00702 {
00703 KMMessage *msg = retrievedMessage();
00704 if ( !msg || !msg->parent() ||
00705 !kmkernel->folderIsTemplates( msg->parent() ) )
00706 return Failed;
00707
00708
00709 KMMessage *newMsg = new KMMessage( new DwMessage( *msg->asDwMessage() ) );
00710 newMsg->setComplete( msg->isComplete() );
00711
00712
00713 newMsg->removeHeaderField("Date");
00714 newMsg->removeHeaderField("Message-ID");
00715
00716 KMail::Composer *win = KMail::makeComposer();
00717 newMsg->setTransferInProgress( false );
00718 win->setMsg( newMsg, false, true );
00719 win->show();
00720
00721 return OK;
00722 }
00723
00724 KMShowMsgSrcCommand::KMShowMsgSrcCommand( TQWidget *parent,
00725 KMMessage *msg, bool fixedFont )
00726 :KMCommand( parent, msg ), mFixedFont( fixedFont )
00727 {
00728
00729 mMsgWasComplete = msg->isComplete();
00730 }
00731
00732 KMCommand::Result KMShowMsgSrcCommand::execute()
00733 {
00734 KMMessage *msg = retrievedMessage();
00735 if ( !msg || !msg->codec() ) {
00736 return Failed;
00737 }
00738 if ( msg->isComplete() && !mMsgWasComplete )
00739 msg->notify();
00740 TQString str = msg->codec()->toUnicode( msg->asString() );
00741
00742 MailSourceViewer *viewer = new MailSourceViewer();
00743 viewer->setCaption( i18n("Message as Plain Text") );
00744 viewer->setText(str);
00745 if( mFixedFont )
00746 viewer->setFont(TDEGlobalSettings::fixedFont());
00747
00748
00749
00750
00751 if (TQApplication::desktop()->isVirtualDesktop()) {
00752 int scnum = TQApplication::desktop()->screenNumber(TQCursor::pos());
00753 viewer->resize(TQApplication::desktop()->screenGeometry(scnum).width()/2,
00754 2*TQApplication::desktop()->screenGeometry(scnum).height()/3);
00755 } else {
00756 viewer->resize(TQApplication::desktop()->geometry().width()/2,
00757 2*TQApplication::desktop()->geometry().height()/3);
00758 }
00759 viewer->show();
00760
00761 return OK;
00762 }
00763
00764 static KURL subjectToUrl( const TQString & subject )
00765 {
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 const TQString filter = i18n( "*.mbox|email messages (*.mbox)\n*|all files (*)" );
00776 TQString cleanSubject = subject.stripWhiteSpace()
00777 .replace( TQDir::separator(), '_' )
00778 .replace( ": ", "_" )
00779 .replace( ':', '_' )
00780 .replace( '.', '_' )
00781 .replace( '~', '_' );
00782 return KFileDialog::getSaveURL( cleanSubject, filter );
00783 }
00784
00785 KMSaveMsgCommand::KMSaveMsgCommand( TQWidget *parent, KMMessage * msg )
00786 : KMCommand( parent ),
00787 mMsgListIndex( 0 ),
00788 mStandAloneMessage( 0 ),
00789 mOffset( 0 ),
00790 mTotalSize( msg ? msg->msgSize() : 0 )
00791 {
00792 if ( !msg ) return;
00793 setDeletesItself( true );
00794
00795
00796
00797
00798 if ( msg->getMsgSerNum() != 0 ) {
00799 mMsgList.append( msg->getMsgSerNum() );
00800 if ( msg->parent() ) {
00801 msg->parent()->open( "kmsavemsgcommand" );
00802 }
00803 } else {
00804 mStandAloneMessage = msg;
00805 }
00806 mUrl = subjectToUrl( msg->cleanSubject() );
00807 }
00808
00809 KMSaveMsgCommand::KMSaveMsgCommand( TQWidget *parent,
00810 const TQPtrList<KMMsgBase> &msgList )
00811 : KMCommand( parent ),
00812 mMsgListIndex( 0 ),
00813 mStandAloneMessage( 0 ),
00814 mOffset( 0 ),
00815 mTotalSize( 0 )
00816 {
00817 if (!msgList.getFirst())
00818 return;
00819 setDeletesItself( true );
00820 KMMsgBase *msgBase = msgList.getFirst();
00821
00822
00823
00824
00825 TQPtrListIterator<KMMsgBase> it(msgList);
00826 while ( it.current() ) {
00827 mMsgList.append( (*it)->getMsgSerNum() );
00828 mTotalSize += (*it)->msgSize();
00829 if ((*it)->parent() != 0)
00830 (*it)->parent()->open("kmcommand");
00831 ++it;
00832 }
00833 mMsgListIndex = 0;
00834 mUrl = subjectToUrl( msgBase->cleanSubject() );
00835 }
00836
00837 KURL KMSaveMsgCommand::url()
00838 {
00839 return mUrl;
00840 }
00841
00842 KMCommand::Result KMSaveMsgCommand::execute()
00843 {
00844 mJob = TDEIO::put( mUrl, S_IRUSR|S_IWUSR, false, false );
00845 mJob->slotTotalSize( mTotalSize );
00846 mJob->setAsyncDataEnabled( true );
00847 mJob->setReportDataSent( true );
00848 connect(mJob, TQT_SIGNAL(dataReq(TDEIO::Job*, TQByteArray &)),
00849 TQT_SLOT(slotSaveDataReq()));
00850 connect(mJob, TQT_SIGNAL(result(TDEIO::Job*)),
00851 TQT_SLOT(slotSaveResult(TDEIO::Job*)));
00852 setEmitsCompletedItself( true );
00853 return OK;
00854 }
00855
00856 void KMSaveMsgCommand::slotSaveDataReq()
00857 {
00858 int remainingBytes = mData.size() - mOffset;
00859 if ( remainingBytes > 0 ) {
00860
00861 if ( remainingBytes > MAX_CHUNK_SIZE )
00862 remainingBytes = MAX_CHUNK_SIZE;
00863
00864 TQByteArray data;
00865 data.duplicate( mData.data() + mOffset, remainingBytes );
00866 mJob->sendAsyncData( data );
00867 mOffset += remainingBytes;
00868 return;
00869 }
00870
00871 if ( mMsgListIndex < mMsgList.size() ) {
00872 KMMessage *msg = 0;
00873 int idx = -1;
00874 KMFolder * p = 0;
00875 KMMsgDict::instance()->getLocation( mMsgList[mMsgListIndex], &p, &idx );
00876 assert( p );
00877 assert( idx >= 0 );
00878
00879
00880 const bool alreadyGot = p->isMessage( idx );
00881
00882 msg = p->getMsg(idx);
00883
00884 if ( msg ) {
00885
00886 if ( !alreadyGot ) {
00887 mUngetMsgs.append( msg );
00888 }
00889 if ( msg->transferInProgress() ) {
00890 TQByteArray data = TQByteArray();
00891 mJob->sendAsyncData( data );
00892 }
00893 msg->setTransferInProgress( true );
00894 if ( msg->isComplete() ) {
00895 slotMessageRetrievedForSaving( msg );
00896 } else {
00897
00898 if ( msg->parent() && !msg->isComplete() ) {
00899 FolderJob *job = msg->parent()->createJob( msg );
00900 job->setCancellable( false );
00901 connect(job, TQT_SIGNAL( messageRetrieved( KMMessage* ) ),
00902 this, TQT_SLOT( slotMessageRetrievedForSaving( KMMessage* ) ) );
00903 job->start();
00904 }
00905 }
00906 } else {
00907 mJob->slotError( TDEIO::ERR_ABORTED,
00908 i18n("The message was removed while saving it. "
00909 "It has not been saved.") );
00910 }
00911 } else {
00912 if ( mStandAloneMessage ) {
00913
00914 slotMessageRetrievedForSaving( mStandAloneMessage );
00915 mStandAloneMessage = 0;
00916 } else {
00917
00918 TQByteArray data = TQByteArray();
00919 mJob->sendAsyncData( data );
00920 }
00921 }
00922 }
00923
00924 void KMSaveMsgCommand::slotMessageRetrievedForSaving(KMMessage *msg)
00925 {
00926 if ( msg ) {
00927 mData = KMFolderMbox::escapeFrom( msg->asDwString() );
00928 KMail::Util::insert( mData, 0, msg->mboxMessageSeparator() );
00929 KMail::Util::append( mData, "\n" );
00930 msg->setTransferInProgress(false);
00931
00932 mOffset = 0;
00933 TQByteArray data;
00934 int size;
00935
00936 if( mData.size() > (unsigned int) MAX_CHUNK_SIZE )
00937 size = MAX_CHUNK_SIZE;
00938 else
00939 size = mData.size();
00940
00941 data.duplicate( mData, size );
00942 mJob->sendAsyncData( data );
00943 mOffset += size;
00944 }
00945 ++mMsgListIndex;
00946
00947 if ( msg && msg->parent() && msg->getMsgSerNum() &&
00948 mUngetMsgs.contains( msg ) ) {
00949 int idx = -1;
00950 KMFolder * p = 0;
00951 KMMsgDict::instance()->getLocation( msg, &p, &idx );
00952 assert( p == msg->parent() ); assert( idx >= 0 );
00953 p->unGetMsg( idx );
00954 p->close("kmcommand");
00955 }
00956 }
00957
00958 void KMSaveMsgCommand::slotSaveResult(TDEIO::Job *job)
00959 {
00960 if (job->error())
00961 {
00962 if (job->error() == TDEIO::ERR_FILE_ALREADY_EXIST)
00963 {
00964 if (KMessageBox::warningContinueCancel(0,
00965 i18n("File %1 exists.\nDo you want to replace it?")
00966 .arg(mUrl.prettyURL()), i18n("Save to File"), i18n("&Replace"))
00967 == KMessageBox::Continue) {
00968 mOffset = 0;
00969
00970 mJob = TDEIO::put( mUrl, S_IRUSR|S_IWUSR, true, false );
00971 mJob->slotTotalSize( mTotalSize );
00972 mJob->setAsyncDataEnabled( true );
00973 mJob->setReportDataSent( true );
00974 connect(mJob, TQT_SIGNAL(dataReq(TDEIO::Job*, TQByteArray &)),
00975 TQT_SLOT(slotSaveDataReq()));
00976 connect(mJob, TQT_SIGNAL(result(TDEIO::Job*)),
00977 TQT_SLOT(slotSaveResult(TDEIO::Job*)));
00978 }
00979 }
00980 else
00981 {
00982 job->showErrorDialog();
00983 setResult( Failed );
00984 emit completed( this );
00985 deleteLater();
00986 }
00987 } else {
00988 setResult( OK );
00989 emit completed( this );
00990 deleteLater();
00991 }
00992 }
00993
00994
00995
00996 KMOpenMsgCommand::KMOpenMsgCommand( TQWidget *parent, const KURL & url,
00997 const TQString & encoding )
00998 : KMCommand( parent ),
00999 mUrl( url ),
01000 mEncoding( encoding )
01001 {
01002 setDeletesItself( true );
01003 }
01004
01005 KMCommand::Result KMOpenMsgCommand::execute()
01006 {
01007 if ( mUrl.isEmpty() ) {
01008 mUrl = KFileDialog::getOpenURL( ":OpenMessage", "message/rfc822 application/mbox",
01009 parentWidget(), i18n("Open Message") );
01010 }
01011 if ( mUrl.isEmpty() ) {
01012 setDeletesItself( false );
01013 return Canceled;
01014 }
01015 mJob = TDEIO::get( mUrl, false, false );
01016 mJob->setReportDataSent( true );
01017 connect( mJob, TQT_SIGNAL( data( TDEIO::Job *, const TQByteArray & ) ),
01018 this, TQT_SLOT( slotDataArrived( TDEIO::Job*, const TQByteArray & ) ) );
01019 connect( mJob, TQT_SIGNAL( result( TDEIO::Job * ) ),
01020 TQT_SLOT( slotResult( TDEIO::Job * ) ) );
01021 setEmitsCompletedItself( true );
01022 return OK;
01023 }
01024
01025 void KMOpenMsgCommand::slotDataArrived( TDEIO::Job *, const TQByteArray & data )
01026 {
01027 if ( data.isEmpty() )
01028 return;
01029
01030 mMsgString.append( data.data(), data.size() );
01031 }
01032
01033 void KMOpenMsgCommand::slotResult( TDEIO::Job *job )
01034 {
01035 if ( job->error() ) {
01036
01037 job->showErrorDialog();
01038 setResult( Failed );
01039 emit completed( this );
01040 }
01041 else {
01042 int startOfMessage = 0;
01043 if ( mMsgString.compare( 0, 5, "From ", 5 ) == 0 ) {
01044 startOfMessage = mMsgString.find( '\n' );
01045 if ( startOfMessage == -1 ) {
01046 KMessageBox::sorry( parentWidget(),
01047 i18n( "The file does not contain a message." ) );
01048 setResult( Failed );
01049 emit completed( this );
01050
01051
01052
01053 SecondaryWindow *win = new SecondaryWindow();
01054 win->close();
01055 win->deleteLater();
01056 deleteLater();
01057 return;
01058 }
01059 startOfMessage += 1;
01060 }
01061
01062 bool multipleMessages = true;
01063 int endOfMessage = mMsgString.find( "\nFrom " );
01064 if ( endOfMessage == -1 ) {
01065 endOfMessage = mMsgString.length();
01066 multipleMessages = false;
01067 }
01068 DwMessage *dwMsg = new DwMessage;
01069 dwMsg->FromString( mMsgString.substr( startOfMessage,
01070 endOfMessage - startOfMessage ) );
01071 dwMsg->Parse();
01072
01073 if ( dwMsg->Headers().NumFields() == 0 ) {
01074 KMessageBox::sorry( parentWidget(),
01075 i18n( "The file does not contain a message." ) );
01076 delete dwMsg; dwMsg = 0;
01077 setResult( Failed );
01078 emit completed( this );
01079
01080 SecondaryWindow *win = new SecondaryWindow();
01081 win->close();
01082 win->deleteLater();
01083 deleteLater();
01084 return;
01085 }
01086 KMMessage *msg = new KMMessage( dwMsg );
01087 msg->setReadyToShow( true );
01088 KMReaderMainWin *win = new KMReaderMainWin();
01089 win->showMsg( mEncoding, msg );
01090 win->show();
01091 if ( multipleMessages )
01092 KMessageBox::information( win,
01093 i18n( "The file contains multiple messages. "
01094 "Only the first message is shown." ) );
01095 setResult( OK );
01096 emit completed( this );
01097 }
01098 deleteLater();
01099 }
01100
01101
01102
01103
01104
01105 KMReplyToCommand::KMReplyToCommand( TQWidget *parent, KMMessage *msg,
01106 const TQString &selection )
01107 : KMCommand( parent, msg ), mSelection( selection )
01108 {
01109 }
01110
01111 KMCommand::Result KMReplyToCommand::execute()
01112 {
01113 KCursorSaver busy(KBusyPtr::busy());
01114 KMMessage *msg = retrievedMessage();
01115 if ( !msg || !msg->codec() ) {
01116 return Failed;
01117 }
01118
01119
01120 TQString accountName;
01121 KMFolder* parentFolder = msg->parent();
01122 if (parentFolder) {
01123 KMFolderDir* parentFolderDir = parentFolder->parent();
01124 while (parentFolderDir) {
01125 TQString prettyURL = parentFolderDir->prettyURL();
01126 if (prettyURL != "") {
01127 accountName = prettyURL;
01128 }
01129 parentFolderDir = parentFolderDir->parent();
01130 }
01131 }
01132
01133 KMMessage *reply = msg->createReply( KMail::ReplySmart, mSelection, false, true, TQString(), accountName );
01134 KMail::Composer * win = KMail::makeComposer( reply );
01135 win->setCharset( msg->codec()->mimeName(), true );
01136 win->setReplyFocus();
01137 win->show();
01138
01139 return OK;
01140 }
01141
01142
01143 KMNoQuoteReplyToCommand::KMNoQuoteReplyToCommand( TQWidget *parent,
01144 KMMessage *msg )
01145 : KMCommand( parent, msg )
01146 {
01147 }
01148
01149 KMCommand::Result KMNoQuoteReplyToCommand::execute()
01150 {
01151 KCursorSaver busy(KBusyPtr::busy());
01152 KMMessage *msg = retrievedMessage();
01153 if ( !msg || !msg->codec() ) {
01154 return Failed;
01155 }
01156 KMMessage *reply = msg->createReply( KMail::ReplySmart, "", true);
01157 KMail::Composer * win = KMail::makeComposer( reply );
01158 win->setCharset(msg->codec()->mimeName(), true);
01159 win->setReplyFocus(false);
01160 win->show();
01161
01162 return OK;
01163 }
01164
01165
01166 KMReplyListCommand::KMReplyListCommand( TQWidget *parent,
01167 KMMessage *msg, const TQString &selection )
01168 : KMCommand( parent, msg ), mSelection( selection )
01169 {
01170 }
01171
01172 KMCommand::Result KMReplyListCommand::execute()
01173 {
01174 KCursorSaver busy(KBusyPtr::busy());
01175 KMMessage *msg = retrievedMessage();
01176 if ( !msg || !msg->codec() ) {
01177 return Failed;
01178 }
01179 KMMessage *reply = msg->createReply( KMail::ReplyList, mSelection);
01180 KMail::Composer * win = KMail::makeComposer( reply );
01181 win->setCharset(msg->codec()->mimeName(), true);
01182 win->setReplyFocus(false);
01183 win->show();
01184
01185 return OK;
01186 }
01187
01188
01189 KMReplyToAllCommand::KMReplyToAllCommand( TQWidget *parent,
01190 KMMessage *msg, const TQString &selection )
01191 :KMCommand( parent, msg ), mSelection( selection )
01192 {
01193 }
01194
01195 KMCommand::Result KMReplyToAllCommand::execute()
01196 {
01197 KCursorSaver busy(KBusyPtr::busy());
01198 KMMessage *msg = retrievedMessage();
01199 if ( !msg || !msg->codec() ) {
01200 return Failed;
01201 }
01202 KMMessage *reply = msg->createReply( KMail::ReplyAll, mSelection );
01203 KMail::Composer * win = KMail::makeComposer( reply );
01204 win->setCharset( msg->codec()->mimeName(), true );
01205 win->setReplyFocus();
01206 win->show();
01207
01208 return OK;
01209 }
01210
01211
01212 KMReplyAuthorCommand::KMReplyAuthorCommand( TQWidget *parent, KMMessage *msg,
01213 const TQString &selection )
01214 : KMCommand( parent, msg ), mSelection( selection )
01215 {
01216 }
01217
01218 KMCommand::Result KMReplyAuthorCommand::execute()
01219 {
01220 KCursorSaver busy(KBusyPtr::busy());
01221 KMMessage *msg = retrievedMessage();
01222 if ( !msg || !msg->codec() ) {
01223 return Failed;
01224 }
01225 KMMessage *reply = msg->createReply( KMail::ReplyAuthor, mSelection );
01226 KMail::Composer * win = KMail::makeComposer( reply );
01227 win->setCharset( msg->codec()->mimeName(), true );
01228 win->setReplyFocus();
01229 win->show();
01230
01231 return OK;
01232 }
01233
01234
01235 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
01236 const TQPtrList<KMMsgBase> &msgList, uint identity )
01237 : KMCommand( parent, msgList ),
01238 mIdentity( identity )
01239 {
01240 }
01241
01242 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
01243 KMMessage *msg, uint identity )
01244 : KMCommand( parent, msg ),
01245 mIdentity( identity )
01246 {
01247 }
01248
01249 KMCommand::Result KMForwardInlineCommand::execute()
01250 {
01251 TQPtrList<KMMessage> msgList = retrievedMsgs();
01252
01253 if (msgList.count() >= 2) {
01254
01255 uint id = 0;
01256 TQPtrList<KMMessage> linklist;
01257 for ( KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
01258
01259 if (id == 0)
01260 id = msg->headerField( "X-KMail-Identity" ).stripWhiteSpace().toUInt();
01261
01262
01263 linklist.append( msg );
01264 }
01265 if ( id == 0 )
01266 id = mIdentity;
01267 KMMessage *fwdMsg = new KMMessage;
01268 fwdMsg->initHeader( id );
01269 fwdMsg->setAutomaticFields( true );
01270 fwdMsg->setCharset( "utf-8" );
01271
01272
01273 for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
01274 TemplateParser parser( fwdMsg, TemplateParser::Forward );
01275 parser.setSelection( msg->body() );
01276 parser.process( msg, 0, true );
01277
01278 fwdMsg->link( msg, KMMsgStatusForwarded );
01279 }
01280
01281 KCursorSaver busy( KBusyPtr::busy() );
01282 KMail::Composer * win = KMail::makeComposer( fwdMsg, id );
01283 win->setCharset("");
01284 win->show();
01285
01286 } else {
01287
01288 KMMessage *msg = msgList.getFirst();
01289 if ( !msg || !msg->codec() )
01290 return Failed;
01291
01292 KCursorSaver busy( KBusyPtr::busy() );
01293 KMMessage *fwdMsg = msg->createForward();
01294
01295 uint id = msg->headerField( "X-KMail-Identity" ).stripWhiteSpace().toUInt();
01296 if ( id == 0 )
01297 id = mIdentity;
01298 {
01299 KMail::Composer * win = KMail::makeComposer( fwdMsg, id );
01300 win->setCharset( fwdMsg->codec()->mimeName(), true );
01301 win->show();
01302 }
01303 }
01304 return OK;
01305 }
01306
01307
01308 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
01309 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
01310 : KMCommand( parent, msgList ), mIdentity( identity ),
01311 mWin( TQGuardedPtr<KMail::Composer>( win ))
01312 {
01313 }
01314
01315 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
01316 KMMessage * msg, uint identity, KMail::Composer *win )
01317 : KMCommand( parent, msg ), mIdentity( identity ),
01318 mWin( TQGuardedPtr< KMail::Composer >( win ))
01319 {
01320 }
01321
01322 KMCommand::Result KMForwardAttachedCommand::execute()
01323 {
01324 TQPtrList<KMMessage> msgList = retrievedMsgs();
01325 KMMessage *fwdMsg = new KMMessage;
01326
01327 if (msgList.count() >= 2) {
01328
01329
01330 fwdMsg->initHeader(mIdentity);
01331 }
01332 else if (msgList.count() == 1) {
01333 KMMessage *msg = msgList.getFirst();
01334 fwdMsg->initFromMessage(msg);
01335 fwdMsg->setSubject( msg->forwardSubject() );
01336 }
01337
01338 fwdMsg->setAutomaticFields(true);
01339
01340 KCursorSaver busy(KBusyPtr::busy());
01341 if (!mWin)
01342 mWin = KMail::makeComposer(fwdMsg, mIdentity);
01343
01344
01345 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01346
01347 msg->removePrivateHeaderFields();
01348 msg->removeHeaderField("BCC");
01349
01350 KMMessagePart *msgPart = new KMMessagePart;
01351 msgPart->setTypeStr("message");
01352 msgPart->setSubtypeStr("rfc822");
01353 msgPart->setName("forwarded message");
01354 msgPart->setContentDescription(msg->from()+": "+msg->subject());
01355 msgPart->setContentDisposition( "inline" );
01356 msgPart->setMessageBody( KMail::Util::ByteArray( msg->asDwString() ) );
01357
01358 fwdMsg->link(msg, KMMsgStatusForwarded);
01359 mWin->addAttach(msgPart);
01360 }
01361
01362 mWin->show();
01363
01364 return OK;
01365 }
01366
01367
01368 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
01369 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
01370 : KMCommand( parent, msgList ), mIdentity( identity ),
01371 mWin( TQGuardedPtr<KMail::Composer>( win ))
01372 {
01373 }
01374
01375 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
01376 KMMessage * msg, uint identity, KMail::Composer *win )
01377 : KMCommand( parent, msg ), mIdentity( identity ),
01378 mWin( TQGuardedPtr< KMail::Composer >( win ))
01379 {
01380 }
01381
01382 KMCommand::Result KMForwardDigestCommand::execute()
01383 {
01384 TQPtrList<KMMessage> msgList = retrievedMsgs();
01385
01386 if ( msgList.count() < 2 )
01387 return Undefined;
01388
01389 uint id = 0;
01390 KMMessage *fwdMsg = new KMMessage;
01391 KMMessagePart *msgPart = new KMMessagePart;
01392 TQString msgPartText;
01393 int msgCnt = 0;
01394
01395
01396
01397 fwdMsg->initHeader( id );
01398 fwdMsg->setAutomaticFields( true );
01399 fwdMsg->mMsg->Headers().ContentType().CreateBoundary( 1 );
01400 TQCString boundary( fwdMsg->mMsg->Headers().ContentType().Boundary().c_str() );
01401 msgPartText = i18n("\nThis is a MIME digest forward. The content of the"
01402 " message is contained in the attachment(s).\n\n\n");
01403
01404 for ( KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
01405
01406 if ( id == 0 )
01407 id = msg->headerField( "X-KMail-Identity" ).stripWhiteSpace().toUInt();
01408
01409 msgPartText += "--";
01410 msgPartText += TQString::fromLatin1( boundary );
01411 msgPartText += "\nContent-Type: MESSAGE/RFC822";
01412 msgPartText += TQString( "; CHARSET=%1" ).arg( TQString(msg->charset()) );
01413 msgPartText += '\n';
01414 DwHeaders dwh;
01415 dwh.MessageId().CreateDefault();
01416 msgPartText += TQString( "Content-ID: %1\n" ).arg( dwh.MessageId().AsString().c_str() );
01417 msgPartText += TQString( "Content-Description: %1" ).arg( msg->subject() );
01418 if ( !msg->subject().contains( "(fwd)" ) )
01419 msgPartText += " (fwd)";
01420 msgPartText += "\n\n";
01421
01422 msg->removePrivateHeaderFields();
01423 msg->removeHeaderField( "BCC" );
01424
01425 msgPartText += msg->headerAsString();
01426 msgPartText += '\n';
01427 msgPartText += msg->body();
01428 msgPartText += '\n';
01429 msgCnt++;
01430 fwdMsg->link( msg, KMMsgStatusForwarded );
01431 }
01432
01433 if ( id == 0 )
01434 id = mIdentity;
01435 fwdMsg->initHeader( id );
01436 msgPartText += "--";
01437 msgPartText += TQString::fromLatin1( boundary );
01438 msgPartText += "--\n";
01439 TQCString tmp;
01440 msgPart->setTypeStr( "MULTIPART" );
01441 tmp.sprintf( "Digest; boundary=\"%s\"", boundary.data() );
01442 msgPart->setSubtypeStr( tmp );
01443 msgPart->setName( "unnamed" );
01444 msgPart->setCte( DwMime::kCte7bit );
01445 msgPart->setContentDescription( TQString( "Digest of %1 messages." ).arg( msgCnt ) );
01446
01447 msgPart->setBodyEncoded( TQCString( msgPartText.ascii() ) );
01448 KCursorSaver busy( KBusyPtr::busy() );
01449 KMail::Composer * win = KMail::makeComposer( fwdMsg, id );
01450 win->addAttach( msgPart );
01451 win->show();
01452 return OK;
01453 }
01454
01455 KMRedirectCommand::KMRedirectCommand( TQWidget *parent,
01456 KMMessage *msg )
01457 : KMCommand( parent, msg )
01458 {
01459 }
01460
01461 KMCommand::Result KMRedirectCommand::execute()
01462 {
01463 KMMessage *msg = retrievedMessage();
01464 if ( !msg || !msg->codec() )
01465 return Failed;
01466
01467 RedirectDialog dlg( parentWidget(), "redirect", true,
01468 kmkernel->msgSender()->sendImmediate() );
01469 if (dlg.exec()==TQDialog::Rejected) return Failed;
01470
01471 KMMessage *newMsg = msg->createRedirect( dlg.to() );
01472 KMFilterAction::sendMDN( msg, KMime::MDN::Dispatched );
01473
01474 const KMail::MessageSender::SendMethod method = dlg.sendImmediate()
01475 ? KMail::MessageSender::SendImmediate
01476 : KMail::MessageSender::SendLater;
01477 if ( !kmkernel->msgSender()->send( newMsg, method ) ) {
01478 kdDebug(5006) << "KMRedirectCommand: could not redirect message (sending failed)" << endl;
01479 return Failed;
01480 }
01481 return OK;
01482 }
01483
01484
01485 KMCustomReplyToCommand::KMCustomReplyToCommand( TQWidget *parent, KMMessage *msg,
01486 const TQString &selection,
01487 const TQString &tmpl )
01488 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
01489 {
01490 }
01491
01492 KMCommand::Result KMCustomReplyToCommand::execute()
01493 {
01494 KCursorSaver busy(KBusyPtr::busy());
01495 KMMessage *msg = retrievedMessage();
01496 if ( !msg || !msg->codec() ) {
01497 return Failed;
01498 }
01499 KMMessage *reply = msg->createReply( KMail::ReplySmart, mSelection,
01500 false, true, mTemplate );
01501 KMail::Composer * win = KMail::makeComposer( reply );
01502 win->setCharset( msg->codec()->mimeName(), true );
01503 win->setReplyFocus();
01504 win->show();
01505
01506 return OK;
01507 }
01508
01509
01510 KMCustomReplyAllToCommand::KMCustomReplyAllToCommand( TQWidget *parent, KMMessage *msg,
01511 const TQString &selection,
01512 const TQString &tmpl )
01513 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
01514 {
01515 }
01516
01517 KMCommand::Result KMCustomReplyAllToCommand::execute()
01518 {
01519 KCursorSaver busy(KBusyPtr::busy());
01520 KMMessage *msg = retrievedMessage();
01521 if ( !msg || !msg->codec() ) {
01522 return Failed;
01523 }
01524 KMMessage *reply = msg->createReply( KMail::ReplyAll, mSelection,
01525 false, true, mTemplate );
01526 KMail::Composer * win = KMail::makeComposer( reply );
01527 win->setCharset( msg->codec()->mimeName(), true );
01528 win->setReplyFocus();
01529 win->show();
01530
01531 return OK;
01532 }
01533
01534
01535 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
01536 const TQPtrList<KMMsgBase> &msgList, uint identity, const TQString &tmpl )
01537 : KMCommand( parent, msgList ),
01538 mIdentity( identity ), mTemplate( tmpl )
01539 {
01540 }
01541
01542 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
01543 KMMessage *msg, uint identity, const TQString &tmpl )
01544 : KMCommand( parent, msg ),
01545 mIdentity( identity ), mTemplate( tmpl )
01546 {
01547 }
01548
01549 KMCommand::Result KMCustomForwardCommand::execute()
01550 {
01551 TQPtrList<KMMessage> msgList = retrievedMsgs();
01552
01553 if (msgList.count() >= 2) {
01554
01555 uint id = 0;
01556 TQPtrList<KMMessage> linklist;
01557 for ( KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
01558
01559 if (id == 0)
01560 id = msg->headerField( "X-KMail-Identity" ).stripWhiteSpace().toUInt();
01561
01562
01563 linklist.append( msg );
01564 }
01565 if ( id == 0 )
01566 id = mIdentity;
01567 KMMessage *fwdMsg = new KMMessage;
01568 fwdMsg->initHeader( id );
01569 fwdMsg->setAutomaticFields( true );
01570 fwdMsg->setCharset( "utf-8" );
01571
01572
01573 for ( KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
01574 TemplateParser parser( fwdMsg, TemplateParser::Forward );
01575 parser.setSelection( msg->body() );
01576 parser.process( msg, 0, true );
01577
01578 fwdMsg->link( msg, KMMsgStatusForwarded );
01579 }
01580
01581 KCursorSaver busy( KBusyPtr::busy() );
01582 KMail::Composer * win = KMail::makeComposer( fwdMsg, id );
01583 win->setCharset("");
01584 win->show();
01585
01586 } else {
01587
01588 KMMessage *msg = msgList.getFirst();
01589 if ( !msg || !msg->codec() )
01590 return Failed;
01591
01592 KCursorSaver busy( KBusyPtr::busy() );
01593 KMMessage *fwdMsg = msg->createForward( mTemplate );
01594
01595 uint id = msg->headerField( "X-KMail-Identity" ).stripWhiteSpace().toUInt();
01596 if ( id == 0 )
01597 id = mIdentity;
01598 {
01599 KMail::Composer * win = KMail::makeComposer( fwdMsg, id );
01600 win->setCharset( fwdMsg->codec()->mimeName(), true );
01601 win->show();
01602 }
01603 }
01604 return OK;
01605 }
01606
01607
01608 KMPrintCommand::KMPrintCommand( TQWidget *parent, KMMessage *msg,
01609 const KMail::HeaderStyle *headerStyle,
01610 const KMail::HeaderStrategy *headerStrategy,
01611 bool htmlOverride, bool htmlLoadExtOverride,
01612 bool useFixedFont, const TQString & encoding )
01613 : KMCommand( parent, msg ),
01614 mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ),
01615 mHtmlOverride( htmlOverride ),
01616 mHtmlLoadExtOverride( htmlLoadExtOverride ),
01617 mUseFixedFont( useFixedFont ), mEncoding( encoding )
01618 {
01619 if ( GlobalSettings::useDefaultFonts() )
01620 mOverrideFont = TDEGlobalSettings::generalFont();
01621 else {
01622 TDEConfigGroup fonts( KMKernel::config(), "Fonts" );
01623 TQString tmp = fonts.readEntry( "print-font", TDEGlobalSettings::generalFont().toString() );
01624 mOverrideFont.fromString( tmp );
01625 }
01626 }
01627
01628
01629 void KMPrintCommand::setOverrideFont( const TQFont& font )
01630 {
01631 mOverrideFont = font;
01632 }
01633
01634 KMCommand::Result KMPrintCommand::execute()
01635 {
01636 KMReaderWin printWin( 0, 0, 0 );
01637 printWin.setPrinting( true );
01638 printWin.readConfig();
01639 if ( mHeaderStyle != 0 && mHeaderStrategy != 0 )
01640 printWin.setHeaderStyleAndStrategy( mHeaderStyle, mHeaderStrategy );
01641 printWin.setHtmlOverride( mHtmlOverride );
01642 printWin.setHtmlLoadExtOverride( mHtmlLoadExtOverride );
01643 printWin.setUseFixedFont( mUseFixedFont );
01644 printWin.setOverrideEncoding( mEncoding );
01645 printWin.cssHelper()->setPrintFont( mOverrideFont );
01646 printWin.setDecryptMessageOverwrite( true );
01647 printWin.setMsg( retrievedMessage(), true );
01648 printWin.printMsg();
01649
01650 return OK;
01651 }
01652
01653
01654 KMSeStatusCommand::KMSeStatusCommand( KMMsgStatus status,
01655 const TQValueList<TQ_UINT32> &serNums, bool toggle )
01656 : mStatus( status ), mSerNums( serNums ), mToggle( toggle )
01657 {
01658 }
01659
01660 KMCommand::Result KMSeStatusCommand::execute()
01661 {
01662 TQValueListIterator<TQ_UINT32> it;
01663 int idx = -1;
01664 KMFolder *folder = 0;
01665 bool parenStatus = false;
01666
01667
01668
01669 if (mToggle) {
01670 KMMsgBase *msg;
01671 KMMsgDict::instance()->getLocation( *mSerNums.begin(), &folder, &idx );
01672 if (folder) {
01673 msg = folder->getMsgBase(idx);
01674 if (msg && (msg->status()&mStatus))
01675 parenStatus = true;
01676 else
01677 parenStatus = false;
01678 }
01679 }
01680 TQMap< KMFolder*, TQValueList<int> > folderMap;
01681 for ( it = mSerNums.begin(); it != mSerNums.end(); ++it ) {
01682 KMMsgDict::instance()->getLocation( *it, &folder, &idx );
01683 if (folder) {
01684 if (mToggle) {
01685 KMMsgBase *msg = folder->getMsgBase(idx);
01686
01687 if (msg) {
01688 bool myStatus;
01689 if (msg->status()&mStatus)
01690 myStatus = true;
01691 else
01692 myStatus = false;
01693 if (myStatus != parenStatus)
01694 continue;
01695 }
01696 }
01697
01698
01699 folderMap[folder].append(idx);
01700 }
01701 }
01702 TQMapIterator< KMFolder*, TQValueList<int> > it2 = folderMap.begin();
01703 while ( it2 != folderMap.end() ) {
01704 KMFolder *f = it2.key();
01705 f->setStatus( (*it2), mStatus, mToggle );
01706 ++it2;
01707 }
01708
01709
01710 return OK;
01711 }
01712
01713
01714 KMFilterCommand::KMFilterCommand( const TQCString &field, const TQString &value )
01715 : mField( field ), mValue( value )
01716 {
01717 }
01718
01719 KMCommand::Result KMFilterCommand::execute()
01720 {
01721 kmkernel->filterMgr()->createFilter( mField, mValue );
01722
01723 return OK;
01724 }
01725
01726
01727 KMFilterActionCommand::KMFilterActionCommand( TQWidget *parent,
01728 const TQPtrList<KMMsgBase> &msgList,
01729 KMFilter *filter )
01730 : KMCommand( parent, msgList ), mFilter( filter )
01731 {
01732 TQPtrListIterator<KMMsgBase> it(msgList);
01733 while ( it.current() ) {
01734 serNumList.append( (*it)->getMsgSerNum() );
01735 ++it;
01736 }
01737 }
01738
01739 KMCommand::Result KMFilterActionCommand::execute()
01740 {
01741 KCursorSaver busy( KBusyPtr::busy() );
01742
01743 int msgCount = 0;
01744 int msgCountToFilter = serNumList.count();
01745 ProgressItem* progressItem =
01746 ProgressManager::createProgressItem ( "filter"+ProgressManager::getUniqueID(),
01747 i18n( "Filtering messages" ) );
01748 progressItem->setTotalItems( msgCountToFilter );
01749 TQValueList<TQ_UINT32>::const_iterator it;
01750 for ( it = serNumList.begin(); it != serNumList.end(); it++ ) {
01751 TQ_UINT32 serNum = *it;
01752 int diff = msgCountToFilter - ++msgCount;
01753 if ( diff < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
01754 progressItem->updateProgress();
01755 TQString statusMsg = i18n("Filtering message %1 of %2");
01756 statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
01757 KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
01758 TDEApplication::kApplication()->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput, 50 );
01759 }
01760
01761 int filterResult = kmkernel->filterMgr()->process( serNum, mFilter );
01762 if (filterResult == 2) {
01763
01764 perror("Critical error");
01765 kmkernel->emergencyExit( i18n("Not enough free disk space?" ));
01766 }
01767 progressItem->incCompletedItems();
01768 }
01769
01770 progressItem->setComplete();
01771 progressItem = 0;
01772 return OK;
01773 }
01774
01775
01776 KMMetaFilterActionCommand::KMMetaFilterActionCommand( KMFilter *filter,
01777 KMHeaders *headers,
01778 KMMainWidget *main )
01779 : TQObject( main ),
01780 mFilter( filter ), mHeaders( headers ), mMainWidget( main )
01781 {
01782 }
01783
01784 void KMMetaFilterActionCommand::start()
01785 {
01786 if (ActionScheduler::isEnabled() ) {
01787
01788 KMFilterMgr::FilterSet set = KMFilterMgr::All;
01789 TQValueList<KMFilter*> filters;
01790 filters.append( mFilter );
01791 ActionScheduler *scheduler = new ActionScheduler( set, filters, mHeaders );
01792 scheduler->setAlwaysMatch( true );
01793 scheduler->setAutoDestruct( true );
01794
01795 int contentX, contentY;
01796 HeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY );
01797 TQPtrList<KMMsgBase> msgList = *mHeaders->selectedMsgs(true);
01798 mHeaders->finalizeMove( nextItem, contentX, contentY );
01799
01800 for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
01801 scheduler->execFilters( msg );
01802 } else {
01803 KMCommand *filterCommand =
01804 new KMFilterActionCommand( mMainWidget,
01805 *mHeaders->selectedMsgs(), mFilter );
01806 filterCommand->start();
01807 int contentX, contentY;
01808 HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
01809 mHeaders->finalizeMove( item, contentX, contentY );
01810 }
01811 }
01812
01813 FolderShortcutCommand::FolderShortcutCommand( KMMainWidget *mainwidget,
01814 KMFolder *folder )
01815 : mMainWidget( mainwidget ), mFolder( folder ), mAction( 0 )
01816 {
01817 }
01818
01819
01820 FolderShortcutCommand::~FolderShortcutCommand()
01821 {
01822 if ( mAction ) mAction->unplugAll();
01823 delete mAction;
01824 }
01825
01826 void FolderShortcutCommand::start()
01827 {
01828 mMainWidget->slotSelectFolder( mFolder );
01829 }
01830
01831 void FolderShortcutCommand::setAction( TDEAction* action )
01832 {
01833 mAction = action;
01834 }
01835
01836 KMMailingListFilterCommand::KMMailingListFilterCommand( TQWidget *parent,
01837 KMMessage *msg )
01838 : KMCommand( parent, msg )
01839 {
01840 }
01841
01842 KMCommand::Result KMMailingListFilterCommand::execute()
01843 {
01844 TQCString name;
01845 TQString value;
01846 KMMessage *msg = retrievedMessage();
01847 if (!msg)
01848 return Failed;
01849
01850 if ( !MailingList::name( msg, name, value ).isEmpty() ) {
01851 kmkernel->filterMgr()->createFilter( name, value );
01852 return OK;
01853 }
01854 else
01855 return Failed;
01856 }
01857
01858
01859 void KMMenuCommand::folderToPopupMenu(bool move,
01860 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
01861 {
01862 while ( menu->count() )
01863 {
01864 TQPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
01865 if (popup)
01866 delete popup;
01867 else
01868 menu->removeItemAt( 0 );
01869 }
01870
01871 if (!kmkernel->imapFolderMgr()->dir().first() &&
01872 !kmkernel->dimapFolderMgr()->dir().first())
01873 {
01874 makeFolderMenu( &kmkernel->folderMgr()->dir(), move,
01875 receiver, aMenuToFolder, menu );
01876 } else {
01877
01878 TQPopupMenu* subMenu = new TQPopupMenu(menu);
01879 makeFolderMenu( &kmkernel->folderMgr()->dir(),
01880 move, receiver, aMenuToFolder, subMenu );
01881 menu->insertItem( i18n( "Local Folders" ), subMenu );
01882 KMFolderDir* fdir = &kmkernel->imapFolderMgr()->dir();
01883 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01884 if (node->isDir())
01885 continue;
01886 subMenu = new TQPopupMenu(menu);
01887 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01888 menu->insertItem( node->label(), subMenu );
01889 }
01890 fdir = &kmkernel->dimapFolderMgr()->dir();
01891 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01892 if (node->isDir())
01893 continue;
01894 subMenu = new TQPopupMenu(menu);
01895 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01896 menu->insertItem( node->label(), subMenu );
01897 }
01898 }
01899 }
01900
01901 void KMMenuCommand::makeFolderMenu(KMFolderNode* node, bool move,
01902 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
01903 {
01904
01905 if (move)
01906 {
01907 disconnect(menu, TQT_SIGNAL(activated(int)), receiver,
01908 TQT_SLOT(moveSelectedToFolder(int)));
01909 connect(menu, TQT_SIGNAL(activated(int)), receiver,
01910 TQT_SLOT(moveSelectedToFolder(int)));
01911 } else {
01912 disconnect(menu, TQT_SIGNAL(activated(int)), receiver,
01913 TQT_SLOT(copySelectedToFolder(int)));
01914 connect(menu, TQT_SIGNAL(activated(int)), receiver,
01915 TQT_SLOT(copySelectedToFolder(int)));
01916 }
01917
01918 KMFolder *folder = 0;
01919 KMFolderDir *folderDir = 0;
01920 if (node->isDir()) {
01921 folderDir = static_cast<KMFolderDir*>(node);
01922 } else {
01923 folder = static_cast<KMFolder*>(node);
01924 folderDir = folder->child();
01925 }
01926
01927 if (folder && !folder->noContent())
01928 {
01929 int menuId;
01930 if (move)
01931 menuId = menu->insertItem(i18n("Move to This Folder"));
01932 else
01933 menuId = menu->insertItem(i18n("Copy to This Folder"));
01934 aMenuToFolder->insert( menuId, folder );
01935 menu->setItemEnabled( menuId, !folder->isReadOnly() );
01936 menu->insertSeparator();
01937 }
01938
01939 if (!folderDir)
01940 return;
01941
01942 for (KMFolderNode *it = folderDir->first(); it; it = folderDir->next() ) {
01943 if (it->isDir())
01944 continue;
01945 KMFolder *child = static_cast<KMFolder*>(it);
01946 TQString label = child->label();
01947 label.replace("&","&&");
01948 if (child->child() && child->child()->first()) {
01949
01950 TQPopupMenu *subMenu = new TQPopupMenu(menu, "subMenu");
01951 makeFolderMenu( child, move, receiver,
01952 aMenuToFolder, subMenu );
01953 menu->insertItem( label, subMenu );
01954 } else {
01955
01956 int menuId = menu->insertItem( label );
01957 aMenuToFolder->insert( menuId, child );
01958 menu->setItemEnabled( menuId, !child->isReadOnly() );
01959 }
01960 }
01961 return;
01962 }
01963
01964
01965 KMCopyCommand::KMCopyCommand( KMFolder* destFolder,
01966 const TQPtrList<KMMsgBase> &msgList )
01967 :mDestFolder( destFolder ), mMsgList( msgList )
01968 {
01969 setDeletesItself( true );
01970 }
01971
01972 KMCopyCommand::KMCopyCommand( KMFolder* destFolder, KMMessage * msg )
01973 :mDestFolder( destFolder )
01974 {
01975 setDeletesItself( true );
01976 mMsgList.append( &msg->toMsgBase() );
01977 }
01978
01979 KMCommand::Result KMCopyCommand::execute()
01980 {
01981 KMMsgBase *msgBase;
01982 KMMessage *msg, *newMsg;
01983 int idx = -1;
01984 bool isMessage;
01985 TQPtrList<KMMessage> list;
01986 TQPtrList<KMMessage> localList;
01987
01988 if (mDestFolder && mDestFolder->open("kmcommand") != 0)
01989 {
01990 deleteLater();
01991 return Failed;
01992 }
01993
01994 setEmitsCompletedItself( true );
01995 KCursorSaver busy(KBusyPtr::busy());
01996
01997 for (msgBase = mMsgList.first(); msgBase; msgBase = mMsgList.next() )
01998 {
01999 KMFolder *srcFolder = msgBase->parent();
02000 if (( isMessage = msgBase->isMessage() ))
02001 {
02002 msg = static_cast<KMMessage*>(msgBase);
02003 } else {
02004 idx = srcFolder->find(msgBase);
02005 assert(idx != -1);
02006 msg = srcFolder->getMsg(idx);
02007
02008 if ( msg == 0 ) {
02009 KMessageBox::error( parentWidget(), i18n("Corrupt IMAP cache detected in folder %1. "
02010 "Copying of messages aborted.").arg( srcFolder->prettyURL() ) );
02011 deleteLater();
02012 return Failed;
02013 }
02014 }
02015
02016 if (srcFolder && mDestFolder &&
02017 (srcFolder->folderType()== KMFolderTypeImap) &&
02018 (mDestFolder->folderType() == KMFolderTypeImap) &&
02019 (static_cast<KMFolderImap*>(srcFolder->storage())->account() ==
02020 static_cast<KMFolderImap*>(mDestFolder->storage())->account()))
02021 {
02022
02023 list.append(msg);
02024 } else {
02025 newMsg = new KMMessage( new DwMessage( *msg->asDwMessage() ) );
02026 newMsg->setComplete(msg->isComplete());
02027
02028 if (!newMsg->isComplete())
02029 newMsg->setReadyToShow(false);
02030 newMsg->setStatus(msg->status());
02031
02032 if (srcFolder && !newMsg->isComplete())
02033 {
02034
02035 newMsg->setParent(msg->parent());
02036 FolderJob *job = srcFolder->createJob(newMsg);
02037 job->setCancellable( false );
02038 mPendingJobs << job;
02039 connect(job, TQT_SIGNAL(messageRetrieved(KMMessage*)),
02040 mDestFolder, TQT_SLOT(reallyAddCopyOfMsg(KMMessage*)));
02041 connect( job, TQT_SIGNAL(result(KMail::FolderJob*)),
02042 this, TQT_SLOT(slotJobFinished(KMail::FolderJob*)) );
02043 job->start();
02044 } else {
02045
02046 localList.append(newMsg);
02047 }
02048 }
02049
02050 if (srcFolder && !isMessage && list.isEmpty())
02051 {
02052 assert(idx != -1);
02053 srcFolder->unGetMsg( idx );
02054 }
02055
02056 }
02057
02058 bool deleteNow = false;
02059 if (!localList.isEmpty())
02060 {
02061 TQValueList<int> index;
02062 mDestFolder->addMsg( localList, index );
02063 for ( TQValueListIterator<int> it = index.begin(); it != index.end(); ++it ) {
02064 mDestFolder->unGetMsg( *it );
02065 }
02066 if ( mDestFolder->folderType() == KMFolderTypeImap ) {
02067 if ( mPendingJobs.isEmpty() ) {
02068
02069 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
02070 connect( imapDestFolder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02071 this, TQT_SLOT( slotFolderComplete( KMFolderImap*, bool ) ) );
02072 }
02073 } else {
02074 deleteNow = list.isEmpty() && mPendingJobs.isEmpty();
02075 }
02076 }
02077
02078
02079
02080 if (!list.isEmpty())
02081 {
02082
02083 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
02084 connect( imapDestFolder, TQT_SIGNAL( folderComplete( KMFolderImap*, bool ) ),
02085 this, TQT_SLOT( slotFolderComplete( KMFolderImap*, bool ) ) );
02086 imapDestFolder->copyMsg(list);
02087 imapDestFolder->getFolder();
02088 }
02089
02090
02091
02092 if ( deleteNow )
02093 {
02094 mDestFolder->close("kmcommand");
02095 setResult( OK );
02096 emit completed( this );
02097 deleteLater();
02098 }
02099
02100 return OK;
02101 }
02102
02103 void KMCopyCommand::slotJobFinished(KMail::FolderJob * job)
02104 {
02105 mPendingJobs.remove( job );
02106 if ( job->error() ) {
02107 kdDebug(5006) << k_funcinfo << "folder job failed: " << job->error() << endl;
02108
02109 for ( TQValueList<KMail::FolderJob*>::Iterator it = mPendingJobs.begin(); it != mPendingJobs.end(); ++it ) {
02110 disconnect( (*it), TQT_SIGNAL(result(KMail::FolderJob*)),
02111 this, TQT_SLOT(slotJobFinished(KMail::FolderJob*)) );
02112 (*it)->kill();
02113 }
02114 mPendingJobs.clear();
02115 setResult( Failed );
02116 }
02117
02118 if ( mPendingJobs.isEmpty() )
02119 {
02120 mDestFolder->close("kmcommand");
02121 emit completed( this );
02122 deleteLater();
02123 }
02124 }
02125
02126 void KMCopyCommand::slotFolderComplete( KMFolderImap*, bool success )
02127 {
02128 kdDebug(5006) << k_funcinfo << success << endl;
02129 if ( !success )
02130 setResult( Failed );
02131 mDestFolder->close( "kmcommand" );
02132 emit completed( this );
02133 deleteLater();
02134 }
02135
02136
02137 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
02138 const TQPtrList<KMMsgBase> &msgList)
02139 : mDestFolder( destFolder ), mProgressItem( 0 )
02140 {
02141 TQPtrList<KMMsgBase> tmp = msgList;
02142 for ( KMMsgBase *msgBase = tmp.first(); msgBase; msgBase = tmp.next() )
02143 mSerNumList.append( msgBase->getMsgSerNum() );
02144 }
02145
02146 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
02147 KMMessage *msg )
02148 : mDestFolder( destFolder ), mProgressItem( 0 )
02149 {
02150 mSerNumList.append( msg->getMsgSerNum() );
02151 }
02152
02153 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
02154 KMMsgBase *msgBase )
02155 : mDestFolder( destFolder ), mProgressItem( 0 )
02156 {
02157 mSerNumList.append( msgBase->getMsgSerNum() );
02158 }
02159
02160 KMMoveCommand::KMMoveCommand( TQ_UINT32 )
02161 : mProgressItem( 0 )
02162 {
02163 }
02164
02165 KMCommand::Result KMMoveCommand::execute()
02166 {
02167 setEmitsCompletedItself( true );
02168 setDeletesItself( true );
02169 typedef TQMap< KMFolder*, TQPtrList<KMMessage>* > FolderToMessageListMap;
02170 FolderToMessageListMap folderDeleteList;
02171
02172 if (mDestFolder && mDestFolder->open("kmcommand") != 0) {
02173 completeMove( Failed );
02174 return Failed;
02175 }
02176 KCursorSaver busy(KBusyPtr::busy());
02177
02178
02179 Q_ASSERT( !mProgressItem );
02180 mProgressItem =
02181 ProgressManager::createProgressItem (
02182 "move"+ProgressManager::getUniqueID(),
02183 mDestFolder ? i18n( "Moving messages" ) : i18n( "Deleting messages" ) );
02184 connect( mProgressItem, TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
02185 this, TQT_SLOT( slotMoveCanceled() ) );
02186
02187 KMMessage *msg;
02188 int rc = 0;
02189 int index;
02190 TQPtrList<KMMessage> list;
02191 int undoId = -1;
02192 mCompleteWithAddedMsg = false;
02193
02194 if (mDestFolder) {
02195 connect (mDestFolder, TQT_SIGNAL(msgAdded(KMFolder*, TQ_UINT32)),
02196 this, TQT_SLOT(slotMsgAddedToDestFolder(KMFolder*, TQ_UINT32)));
02197 mLostBoys = mSerNumList;
02198 }
02199 mProgressItem->setTotalItems( mSerNumList.count() );
02200
02201 for ( TQValueList<TQ_UINT32>::ConstIterator it = mSerNumList.constBegin(); it != mSerNumList.constEnd(); ++it ) {
02202 if ( *it == 0 ) {
02203 kdDebug(5006) << k_funcinfo << "serial number == 0!" << endl;
02204 continue;
02205 }
02206 KMFolder *srcFolder = 0;
02207 int idx = -1;
02208 KMMsgDict::instance()->getLocation( *it, &srcFolder, &idx );
02209 if (srcFolder == mDestFolder)
02210 continue;
02211 assert(srcFolder);
02212 assert(idx != -1);
02213 if ( !srcFolder->isOpened() ) {
02214 srcFolder->open( "kmmovecommand" );
02215 mOpenedFolders.append( srcFolder );
02216 }
02217 msg = srcFolder->getMsg(idx);
02218 if ( !msg ) {
02219 kdDebug(5006) << k_funcinfo << "No message found for serial number " << *it << endl;
02220 continue;
02221 }
02222 bool undo = msg->enableUndo();
02223
02224 if ( msg && msg->transferInProgress() &&
02225 srcFolder->folderType() == KMFolderTypeImap )
02226 {
02227
02228 msg->setTransferInProgress( false, true );
02229 static_cast<KMFolderImap*>(srcFolder->storage())->ignoreJobsForMessage( msg );
02230 }
02231
02232 if (mDestFolder) {
02233 if (mDestFolder->folderType() == KMFolderTypeImap) {
02234
02235
02236
02237 KMFolderImap *imapFolder = static_cast<KMFolderImap*> ( mDestFolder->storage() );
02238 disconnect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*, bool )),
02239 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*, bool )));
02240
02241 connect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*, bool )),
02242 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*, bool )));
02243 list.append(msg);
02244 } else {
02245
02246 if ( srcFolder->folderType() == KMFolderTypeImap )
02247 {
02248
02249 mCompleteWithAddedMsg = true;
02250 }
02251 rc = mDestFolder->moveMsg(msg, &index);
02252 if (rc == 0 && index != -1) {
02253 KMMsgBase *mb = mDestFolder->unGetMsg( mDestFolder->count() - 1 );
02254 if (undo && mb)
02255 {
02256 if ( undoId == -1 )
02257 undoId = kmkernel->undoStack()->newUndoAction( srcFolder, mDestFolder );
02258 kmkernel->undoStack()->addMsgToAction( undoId, mb->getMsgSerNum() );
02259 }
02260 } else if (rc != 0) {
02261
02262
02263 completeMove( Failed );
02264 return Failed;
02265 }
02266 }
02267 } else {
02268
02269
02270 if (srcFolder->folderType() == KMFolderTypeImap) {
02271 if (!folderDeleteList[srcFolder])
02272 folderDeleteList[srcFolder] = new TQPtrList<KMMessage>;
02273 folderDeleteList[srcFolder]->append( msg );
02274 } else {
02275 srcFolder->removeMsg(idx);
02276 delete msg;
02277 }
02278 }
02279 }
02280 if (!list.isEmpty() && mDestFolder) {
02281
02282 mDestFolder->moveMsg(list, &index);
02283 } else {
02284 FolderToMessageListMap::Iterator it;
02285 for ( it = folderDeleteList.begin(); it != folderDeleteList.end(); ++it ) {
02286 it.key()->removeMsg(*it.data());
02287 delete it.data();
02288 }
02289 if ( !mCompleteWithAddedMsg ) {
02290
02291 completeMove( OK );
02292 }
02293 }
02294
02295 return OK;
02296 }
02297
02298 void KMMoveCommand::slotImapFolderCompleted(KMFolderImap* imapFolder, bool success)
02299 {
02300 disconnect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*, bool )),
02301 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*, bool )));
02302 if ( success ) {
02303
02304
02305
02306
02307
02308
02309 if ( !mLostBoys.isEmpty() ) {
02310 kdDebug(5006) << "### Not all moved messages reported back that they were " << endl
02311 << "### added to the target folder. Did uidValidity change? " << endl;
02312 }
02313 completeMove( OK );
02314 } else {
02315
02316 completeMove( Failed );
02317 }
02318 }
02319
02320 void KMMoveCommand::slotMsgAddedToDestFolder(KMFolder *folder, TQ_UINT32 serNum)
02321 {
02322 if ( folder != mDestFolder || mLostBoys.find( serNum ) == mLostBoys.end() ) {
02323
02324
02325 return;
02326 }
02327 mLostBoys.remove(serNum);
02328 if ( mLostBoys.isEmpty() ) {
02329
02330 disconnect (mDestFolder, TQT_SIGNAL(msgAdded(KMFolder*, TQ_UINT32)),
02331 this, TQT_SLOT(slotMsgAddedToDestFolder(KMFolder*, TQ_UINT32)));
02332 if (mDestFolder && mDestFolder->folderType() != KMFolderTypeImap) {
02333 mDestFolder->sync();
02334 }
02335 if ( mCompleteWithAddedMsg ) {
02336 completeMove( OK );
02337 }
02338 } else {
02339 if ( mProgressItem ) {
02340 mProgressItem->incCompletedItems();
02341 mProgressItem->updateProgress();
02342 }
02343 }
02344 }
02345
02346 void KMMoveCommand::completeMove( Result result )
02347 {
02348 if ( mDestFolder )
02349 mDestFolder->close("kmcommand");
02350 while ( !mOpenedFolders.empty() ) {
02351 KMFolder *folder = mOpenedFolders.back();
02352 mOpenedFolders.pop_back();
02353 folder->close("kmcommand");
02354 }
02355 if ( mProgressItem ) {
02356 mProgressItem->setComplete();
02357 mProgressItem = 0;
02358 }
02359 setResult( result );
02360 emit completed( this );
02361 deleteLater();
02362 }
02363
02364 void KMMoveCommand::slotMoveCanceled()
02365 {
02366 completeMove( Canceled );
02367 }
02368
02369
02370 KMDeleteMsgCommand::KMDeleteMsgCommand( KMFolder* srcFolder,
02371 const TQPtrList<KMMsgBase> &msgList )
02372 :KMMoveCommand( findTrashFolder( srcFolder ), msgList)
02373 {
02374 srcFolder->open("kmcommand");
02375 mOpenedFolders.push_back( srcFolder );
02376 }
02377
02378 KMDeleteMsgCommand::KMDeleteMsgCommand( KMFolder* srcFolder, KMMessage * msg )
02379 :KMMoveCommand( findTrashFolder( srcFolder ), msg)
02380 {
02381 srcFolder->open("kmcommand");
02382 mOpenedFolders.push_back( srcFolder );
02383 }
02384
02385 KMDeleteMsgCommand::KMDeleteMsgCommand( TQ_UINT32 sernum )
02386 :KMMoveCommand( sernum )
02387 {
02388 if ( !sernum ) {
02389 setDestFolder( 0 );
02390 return;
02391 }
02392
02393 KMFolder *srcFolder = 0;
02394 int idx;
02395 KMMsgDict::instance()->getLocation( sernum, &srcFolder, &idx );
02396 if ( srcFolder ) {
02397 KMMsgBase *msg = srcFolder->getMsgBase( idx );
02398 srcFolder->open("kmcommand");
02399 mOpenedFolders.push_back( srcFolder );
02400 addMsg( msg );
02401 }
02402 setDestFolder( findTrashFolder( srcFolder ) );
02403 }
02404
02405 KMFolder * KMDeleteMsgCommand::findTrashFolder( KMFolder * folder )
02406 {
02407 KMFolder* trash = folder->trashFolder();
02408 if( !trash )
02409 trash = kmkernel->trashFolder();
02410 if( trash != folder )
02411 return trash;
02412 return 0;
02413 }
02414
02415
02416 KMUrlClickedCommand::KMUrlClickedCommand( const KURL &url, uint identity,
02417 KMReaderWin *readerWin, bool htmlPref, KMMainWidget *mainWidget )
02418 :mUrl( url ), mIdentity( identity ), mReaderWin( readerWin ),
02419 mHtmlPref( htmlPref ), mMainWidget( mainWidget )
02420 {
02421 }
02422
02423 KMCommand::Result KMUrlClickedCommand::execute()
02424 {
02425 KMMessage* msg;
02426
02427 if (mUrl.protocol() == "mailto")
02428 {
02429 msg = new KMMessage;
02430 msg->initHeader(mIdentity);
02431 msg->setCharset("utf-8");
02432 msg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
02433 TQString query=mUrl.query();
02434 while (!query.isEmpty()) {
02435 TQString queryPart;
02436 int secondQuery = query.find('?',1);
02437 if (secondQuery != -1)
02438 queryPart = query.left(secondQuery);
02439 else
02440 queryPart = query;
02441 query = query.mid(queryPart.length());
02442
02443 if (queryPart.left(9) == "?subject=")
02444 msg->setSubject( KURL::decode_string(queryPart.mid(9)) );
02445 else if (queryPart.left(6) == "?body=")
02446
02447
02448 msg->setBody( KURL::decode_string(queryPart.mid(6)).latin1() );
02449 else if (queryPart.left(4) == "?cc=")
02450 msg->setCc( KURL::decode_string(queryPart.mid(4)) );
02451 }
02452
02453 KMail::Composer * win = KMail::makeComposer( msg, mIdentity );
02454 win->setCharset("", true);
02455 win->show();
02456 }
02457 else if ( mUrl.protocol() == "im" )
02458 {
02459 kmkernel->imProxy()->chatWithContact( mUrl.path() );
02460 }
02461 else if ((mUrl.protocol() == "http") || (mUrl.protocol() == "https") ||
02462 (mUrl.protocol() == "ftp") || (mUrl.protocol() == "file") ||
02463 (mUrl.protocol() == "ftps") || (mUrl.protocol() == "sftp" ) ||
02464 (mUrl.protocol() == "help") || (mUrl.protocol() == "vnc") ||
02465 (mUrl.protocol() == "smb") || (mUrl.protocol() == "fish") ||
02466 (mUrl.protocol() == "news"))
02467 {
02468 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n("Opening URL..."));
02469 KMimeType::Ptr mime = KMimeType::findByURL( mUrl );
02470 if (mime->name() == "application/x-desktop" ||
02471 mime->name() == "application/x-executable" ||
02472 mime->name() == "application/x-msdos-program" ||
02473 mime->name() == "application/x-shellscript" )
02474 {
02475 if (KMessageBox::warningYesNo( 0, i18n( "<qt>Do you really want to execute <b>%1</b>?</qt>" )
02476 .arg( mUrl.prettyURL() ), TQString(), i18n("Execute"), KStdGuiItem::cancel() ) != KMessageBox::Yes)
02477 return Canceled;
02478 }
02479 KRun * runner = new KRun( mUrl );
02480 runner->setRunExecutables( false );
02481 }
02482 else
02483 return Failed;
02484
02485 return OK;
02486 }
02487
02488 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent, KMMessage *msg )
02489 : KMCommand( parent, msg ), mImplicitAttachments( true ), mEncoded( false )
02490 {
02491 }
02492
02493 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent, const TQPtrList<KMMsgBase>& msgs )
02494 : KMCommand( parent, msgs ), mImplicitAttachments( true ), mEncoded( false )
02495 {
02496 }
02497
02498 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent, TQPtrList<partNode>& attachments,
02499 KMMessage *msg, bool encoded )
02500 : KMCommand( parent ), mImplicitAttachments( false ), mEncoded( encoded )
02501 {
02502 for ( TQPtrListIterator<partNode> it( attachments ); it.current(); ++it ) {
02503 mAttachmentMap.insert( it.current(), msg );
02504 }
02505 }
02506
02507 KMCommand::Result KMSaveAttachmentsCommand::execute()
02508 {
02509 setEmitsCompletedItself( true );
02510 if ( mImplicitAttachments ) {
02511 TQPtrList<KMMessage> msgList = retrievedMsgs();
02512 KMMessage *msg;
02513 for ( TQPtrListIterator<KMMessage> itr( msgList );
02514 ( msg = itr.current() );
02515 ++itr ) {
02516 partNode *rootNode = partNode::fromMessage( msg );
02517 for ( partNode *child = rootNode; child;
02518 child = child->firstChild() ) {
02519 for ( partNode *node = child; node; node = node->nextSibling() ) {
02520 if ( node->type() != DwMime::kTypeMultipart )
02521 mAttachmentMap.insert( node, msg );
02522 }
02523 }
02524 }
02525 }
02526 setDeletesItself( true );
02527
02528 KMLoadPartsCommand *command = new KMLoadPartsCommand( mAttachmentMap );
02529 connect( command, TQT_SIGNAL( partsRetrieved() ),
02530 this, TQT_SLOT( slotSaveAll() ) );
02531 command->start();
02532
02533 return OK;
02534 }
02535
02536 void KMSaveAttachmentsCommand::slotSaveAll()
02537 {
02538
02539
02540
02541 if ( mImplicitAttachments ) {
02542 for ( PartNodeMessageMap::iterator it = mAttachmentMap.begin();
02543 it != mAttachmentMap.end(); ) {
02544
02545
02546
02547 if ( it.key()->msgPart().fileName().stripWhiteSpace().isEmpty() &&
02548 ( it.key()->msgPart().name().stripWhiteSpace().isEmpty() ||
02549 !it.key()->parentNode() ) ) {
02550 PartNodeMessageMap::iterator delIt = it;
02551 ++it;
02552 mAttachmentMap.remove( delIt );
02553 }
02554 else
02555 ++it;
02556 }
02557 if ( mAttachmentMap.isEmpty() ) {
02558 KMessageBox::information( 0, i18n("Found no attachments to save.") );
02559 setResult( OK );
02560 emit completed( this );
02561 deleteLater();
02562 return;
02563 }
02564 }
02565
02566 KURL url, dirUrl;
02567 if ( mAttachmentMap.count() > 1 ) {
02568
02569 dirUrl = KDirSelectDialog::selectDirectory( TQString(), false,
02570 parentWidget(),
02571 i18n("Save Attachments To") );
02572 if ( !dirUrl.isValid() ) {
02573 setResult( Canceled );
02574 emit completed( this );
02575 deleteLater();
02576 return;
02577 }
02578
02579
02580 dirUrl.adjustPath( 1 );
02581 }
02582 else {
02583
02584 partNode *node = mAttachmentMap.begin().key();
02585
02586 TQString s =
02587 node->msgPart().fileName().stripWhiteSpace().replace( ':', '_' );
02588 if ( s.isEmpty() )
02589 s = node->msgPart().name().stripWhiteSpace().replace( ':', '_' );
02590 if ( s.isEmpty() )
02591 s = i18n("filename for an unnamed attachment", "attachment.1");
02592 url = KFileDialog::getSaveURL( s, TQString(), parentWidget(),
02593 TQString() );
02594 if ( url.isEmpty() ) {
02595 setResult( Canceled );
02596 emit completed( this );
02597 deleteLater();
02598 return;
02599 }
02600 }
02601
02602 TQMap< TQString, int > renameNumbering;
02603
02604 Result globalResult = OK;
02605 int unnamedAtmCount = 0;
02606 for ( PartNodeMessageMap::const_iterator it = mAttachmentMap.begin();
02607 it != mAttachmentMap.end();
02608 ++it ) {
02609 KURL curUrl;
02610 if ( !dirUrl.isEmpty() ) {
02611 curUrl = dirUrl;
02612 TQString s =
02613 it.key()->msgPart().fileName().stripWhiteSpace().replace( ':', '_' );
02614 if ( s.isEmpty() )
02615 s = it.key()->msgPart().name().stripWhiteSpace().replace( ':', '_' );
02616 if ( s.isEmpty() ) {
02617 ++unnamedAtmCount;
02618 s = i18n("filename for the %1-th unnamed attachment",
02619 "attachment.%1")
02620 .arg( unnamedAtmCount );
02621 }
02622 curUrl.setFileName( s );
02623 } else {
02624 curUrl = url;
02625 }
02626
02627 if ( !curUrl.isEmpty() ) {
02628
02629
02630
02631 TQString origFile = curUrl.fileName();
02632 TQString file = origFile;
02633
02634 while ( renameNumbering.contains(file) ) {
02635 file = origFile;
02636 int num = renameNumbering[file] + 1;
02637 int dotIdx = file.findRev('.');
02638 file = file.insert( (dotIdx>=0) ? dotIdx : file.length(), TQString("_") + TQString::number(num) );
02639 }
02640 curUrl.setFileName(file);
02641
02642
02643 if ( !renameNumbering.contains(origFile))
02644 renameNumbering[origFile] = 1;
02645 else
02646 renameNumbering[origFile]++;
02647
02648 if ( file != origFile ) {
02649 if ( !renameNumbering.contains(file))
02650 renameNumbering[file] = 1;
02651 else
02652 renameNumbering[file]++;
02653 }
02654
02655
02656 if ( TDEIO::NetAccess::exists( curUrl, false, parentWidget() ) ) {
02657 if ( KMessageBox::warningContinueCancel( parentWidget(),
02658 i18n( "A file named %1 already exists. Do you want to overwrite it?" )
02659 .arg( curUrl.fileName() ),
02660 i18n( "File Already Exists" ), i18n("&Overwrite") ) == KMessageBox::Cancel) {
02661 continue;
02662 }
02663 }
02664
02665 const Result result = saveItem( it.key(), curUrl );
02666 if ( result != OK )
02667 globalResult = result;
02668 }
02669 }
02670 setResult( globalResult );
02671 emit completed( this );
02672 deleteLater();
02673 }
02674
02675 KMCommand::Result KMSaveAttachmentsCommand::saveItem( partNode *node,
02676 const KURL& url )
02677 {
02678 bool bSaveEncrypted = false;
02679 bool bEncryptedParts = node->encryptionState() != KMMsgNotEncrypted;
02680 if( bEncryptedParts )
02681 if( KMessageBox::questionYesNo( parentWidget(),
02682 i18n( "The part %1 of the message is encrypted. Do you want to keep the encryption when saving?" ).
02683 arg( url.fileName() ),
02684 i18n( "KMail Question" ), i18n("Keep Encryption"), i18n("Do Not Keep") ) ==
02685 KMessageBox::Yes )
02686 bSaveEncrypted = true;
02687
02688 bool bSaveWithSig = true;
02689 if( node->signatureState() != KMMsgNotSigned )
02690 if( KMessageBox::questionYesNo( parentWidget(),
02691 i18n( "The part %1 of the message is signed. Do you want to keep the signature when saving?" ).
02692 arg( url.fileName() ),
02693 i18n( "KMail Question" ), i18n("Keep Signature"), i18n("Do Not Keep") ) !=
02694 KMessageBox::Yes )
02695 bSaveWithSig = false;
02696
02697 TQByteArray data;
02698 if ( mEncoded )
02699 {
02700
02701
02702 data = KMail::Util::ByteArray( node->msgPart().dwBody() );
02703 }
02704 else
02705 {
02706 if( bSaveEncrypted || !bEncryptedParts) {
02707 partNode *dataNode = node;
02708 TQCString rawReplyString;
02709 bool gotRawReplyString = false;
02710 if( !bSaveWithSig ) {
02711 if( DwMime::kTypeMultipart == node->type() &&
02712 DwMime::kSubtypeSigned == node->subType() ){
02713
02714 if( node->findType( DwMime::kTypeApplication,
02715 DwMime::kSubtypePgpSignature,
02716 true, false ) ){
02717 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02718 DwMime::kSubtypePgpSignature,
02719 true, false );
02720 }else if( node->findType( DwMime::kTypeApplication,
02721 DwMime::kSubtypePkcs7Mime,
02722 true, false ) ){
02723 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02724 DwMime::kSubtypePkcs7Mime,
02725 true, false );
02726 }else{
02727 dataNode = node->findTypeNot( DwMime::kTypeMultipart,
02728 DwMime::kSubtypeUnknown,
02729 true, false );
02730 }
02731 }else{
02732 ObjectTreeParser otp( 0, 0, false, false, false );
02733
02734
02735 dataNode->setProcessed( false, true );
02736 otp.parseObjectTree( dataNode );
02737
02738 rawReplyString = otp.rawReplyString();
02739 gotRawReplyString = true;
02740 }
02741 }
02742 TQByteArray cstr = gotRawReplyString
02743 ? rawReplyString
02744 : dataNode->msgPart().bodyDecodedBinary();
02745 data = cstr;
02746 size_t size = cstr.size();
02747 if ( dataNode->msgPart().type() == DwMime::kTypeText ) {
02748
02749 size = KMail::Util::crlf2lf( cstr.data(), size );
02750 }
02751 data.resize( size );
02752 }
02753 }
02754 TQDataStream ds;
02755 TQFile file;
02756 KTempFile tf;
02757 tf.setAutoDelete( true );
02758 if ( url.isLocalFile() )
02759 {
02760
02761 file.setName( url.path() );
02762 if ( !file.open( IO_WriteOnly ) )
02763 {
02764 KMessageBox::error( parentWidget(),
02765 i18n( "%2 is detailed error description",
02766 "Could not write the file %1:\n%2" )
02767 .arg( file.name() )
02768 .arg( TQString::fromLocal8Bit( strerror( errno ) ) ),
02769 i18n( "KMail Error" ) );
02770 return Failed;
02771 }
02772
02773
02774 if ( GlobalSettings::self()->disregardUmask() )
02775 fchmod( file.handle(), S_IRUSR | S_IWUSR );
02776
02777 ds.setDevice( &file );
02778 } else
02779 {
02780
02781 ds.setDevice( tf.file() );
02782 }
02783
02784 ds.writeRawBytes( data.data(), data.size() );
02785 if ( !url.isLocalFile() )
02786 {
02787 tf.close();
02788 if ( !TDEIO::NetAccess::upload( tf.name(), url, parentWidget() ) )
02789 {
02790 KMessageBox::error( parentWidget(),
02791 i18n( "Could not write the file %1." )
02792 .arg( url.path() ),
02793 i18n( "KMail Error" ) );
02794 return Failed;
02795 }
02796 } else
02797 file.close();
02798 return OK;
02799 }
02800
02801 KMLoadPartsCommand::KMLoadPartsCommand( TQPtrList<partNode>& parts, KMMessage *msg )
02802 : mNeedsRetrieval( 0 )
02803 {
02804 for ( TQPtrListIterator<partNode> it( parts ); it.current(); ++it ) {
02805 mPartMap.insert( it.current(), msg );
02806 }
02807 }
02808
02809 KMLoadPartsCommand::KMLoadPartsCommand( partNode *node, KMMessage *msg )
02810 : mNeedsRetrieval( 0 )
02811 {
02812 mPartMap.insert( node, msg );
02813 }
02814
02815 KMLoadPartsCommand::KMLoadPartsCommand( PartNodeMessageMap& partMap )
02816 : mNeedsRetrieval( 0 ), mPartMap( partMap )
02817 {
02818 }
02819
02820 void KMLoadPartsCommand::slotStart()
02821 {
02822 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02823 it != mPartMap.end();
02824 ++it ) {
02825 if ( !it.key()->msgPart().isComplete() &&
02826 !it.key()->msgPart().partSpecifier().isEmpty() ) {
02827
02828 ++mNeedsRetrieval;
02829 KMFolder* curFolder = it.data()->parent();
02830 if ( curFolder ) {
02831 FolderJob *job =
02832 curFolder->createJob( it.data(), FolderJob::tGetMessage,
02833 0, it.key()->msgPart().partSpecifier() );
02834 job->setCancellable( false );
02835 connect( job, TQT_SIGNAL(messageUpdated(KMMessage*, TQString)),
02836 this, TQT_SLOT(slotPartRetrieved(KMMessage*, TQString)) );
02837 job->start();
02838 } else
02839 kdWarning(5006) << "KMLoadPartsCommand - msg has no parent" << endl;
02840 }
02841 }
02842 if ( mNeedsRetrieval == 0 )
02843 execute();
02844 }
02845
02846 void KMLoadPartsCommand::slotPartRetrieved( KMMessage *msg,
02847 TQString partSpecifier )
02848 {
02849 DwBodyPart *part =
02850 msg->findDwBodyPart( msg->getFirstDwBodyPart(), partSpecifier );
02851 if ( part ) {
02852
02853 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02854 it != mPartMap.end();
02855 ++it ) {
02856 if ( it.key()->dwPart()->partId() == part->partId() )
02857 it.key()->setDwPart( part );
02858 }
02859 } else
02860 kdWarning(5006) << "KMLoadPartsCommand::slotPartRetrieved - could not find bodypart!" << endl;
02861 --mNeedsRetrieval;
02862 if ( mNeedsRetrieval == 0 )
02863 execute();
02864 }
02865
02866 KMCommand::Result KMLoadPartsCommand::execute()
02867 {
02868 emit partsRetrieved();
02869 setResult( OK );
02870 emit completed( this );
02871 deleteLater();
02872 return OK;
02873 }
02874
02875 KMResendMessageCommand::KMResendMessageCommand( TQWidget *parent,
02876 KMMessage *msg )
02877 :KMCommand( parent, msg )
02878 {
02879 }
02880
02881 KMCommand::Result KMResendMessageCommand::execute()
02882 {
02883 KMMessage *msg = retrievedMessage();
02884 if ( !msg || !msg->codec() ) {
02885 return Failed;
02886 }
02887 KMMessage *newMsg = new KMMessage(*msg);
02888
02889 TQStringList whiteList;
02890 whiteList << "To" << "Cc" << "Bcc" << "Subject";
02891 newMsg->sanitizeHeaders( whiteList );
02892
02893 if( newMsg->type() == DwMime::kTypeText) {
02894 newMsg->setCharset(msg->codec()->mimeName());
02895 }
02896 newMsg->setParent( 0 );
02897
02898
02899 newMsg->setHeaderField("X-KMail-Identity", TQString::number( newMsg->identityUoid() ));
02900 newMsg->applyIdentity( newMsg->identityUoid() );
02901
02902 KMail::Composer * win = KMail::makeComposer();
02903 win->setMsg(newMsg, false, true);
02904 win->show();
02905
02906 return OK;
02907 }
02908
02909 KMMailingListCommand::KMMailingListCommand( TQWidget *parent, KMFolder *folder )
02910 : KMCommand( parent ), mFolder( folder )
02911 {
02912 }
02913
02914 KMCommand::Result KMMailingListCommand::execute()
02915 {
02916 KURL::List lst = urls();
02917 TQString handler = ( mFolder->mailingList().handler() == MailingList::KMail )
02918 ? "mailto" : "https";
02919
02920 KMCommand *command = 0;
02921 for ( KURL::List::Iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
02922 if ( handler == (*itr).protocol() ) {
02923 command = new KMUrlClickedCommand( *itr, mFolder->identity(), 0, false );
02924 }
02925 }
02926 if ( !command && !lst.empty() ) {
02927 command =
02928 new KMUrlClickedCommand( lst.first(), mFolder->identity(), 0, false );
02929 }
02930 if ( command ) {
02931 connect( command, TQT_SIGNAL( completed( KMCommand * ) ),
02932 this, TQT_SLOT( commandCompleted( KMCommand * ) ) );
02933 setDeletesItself( true );
02934 setEmitsCompletedItself( true );
02935 command->start();
02936 return OK;
02937 }
02938 return Failed;
02939 }
02940
02941 void KMMailingListCommand::commandCompleted( KMCommand *command )
02942 {
02943 setResult( command->result() );
02944 emit completed( this );
02945 deleteLater();
02946 }
02947
02948 KMMailingListPostCommand::KMMailingListPostCommand( TQWidget *parent, KMFolder *folder )
02949 : KMMailingListCommand( parent, folder )
02950 {
02951 }
02952 KURL::List KMMailingListPostCommand::urls() const
02953 {
02954 return mFolder->mailingList().postURLS();
02955 }
02956
02957 KMMailingListSubscribeCommand::KMMailingListSubscribeCommand( TQWidget *parent, KMFolder *folder )
02958 : KMMailingListCommand( parent, folder )
02959 {
02960 }
02961 KURL::List KMMailingListSubscribeCommand::urls() const
02962 {
02963 return mFolder->mailingList().subscribeURLS();
02964 }
02965
02966 KMMailingListUnsubscribeCommand::KMMailingListUnsubscribeCommand( TQWidget *parent, KMFolder *folder )
02967 : KMMailingListCommand( parent, folder )
02968 {
02969 }
02970 KURL::List KMMailingListUnsubscribeCommand::urls() const
02971 {
02972 return mFolder->mailingList().unsubscribeURLS();
02973 }
02974
02975 KMMailingListArchivesCommand::KMMailingListArchivesCommand( TQWidget *parent, KMFolder *folder )
02976 : KMMailingListCommand( parent, folder )
02977 {
02978 }
02979 KURL::List KMMailingListArchivesCommand::urls() const
02980 {
02981 return mFolder->mailingList().archiveURLS();
02982 }
02983
02984 KMMailingListHelpCommand::KMMailingListHelpCommand( TQWidget *parent, KMFolder *folder )
02985 : KMMailingListCommand( parent, folder )
02986 {
02987 }
02988 KURL::List KMMailingListHelpCommand::urls() const
02989 {
02990 return mFolder->mailingList().helpURLS();
02991 }
02992
02993 KMIMChatCommand::KMIMChatCommand( const KURL &url, KMMessage *msg )
02994 :mUrl( url ), mMessage( msg )
02995 {
02996 }
02997
02998 KMCommand::Result KMIMChatCommand::execute()
02999 {
03000 kdDebug( 5006 ) << k_funcinfo << " URL is: " << mUrl << endl;
03001 TQString addr = KMMessage::decodeMailtoUrl( mUrl.path() );
03002
03003 TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self( true );
03004 TDEABC::AddresseeList addressees = addressBook->findByEmail( KPIM::getEmailAddress( addr ) ) ;
03005
03006
03007 if( addressees.count() == 1 ) {
03008 kmkernel->imProxy()->chatWithContact( addressees[0].uid() );
03009 return OK;
03010 }
03011 else
03012 {
03013 kdDebug( 5006 ) << "Didn't find exactly one addressee, couldn't tell who to chat to for that email address. Count = " << addressees.count() << endl;
03014
03015 TQString apology;
03016 if ( addressees.isEmpty() )
03017 apology = i18n( "There is no Address Book entry for this email address. Add them to the Address Book and then add instant messaging addresses using your preferred messaging client." );
03018 else
03019 {
03020 apology = i18n( "More than one Address Book entry uses this email address:\n %1\n it is not possible to determine who to chat with." );
03021 TQStringList nameList;
03022 TDEABC::AddresseeList::const_iterator it = addressees.begin();
03023 TDEABC::AddresseeList::const_iterator end = addressees.end();
03024 for ( ; it != end; ++it )
03025 {
03026 nameList.append( (*it).realName() );
03027 }
03028 TQString names = nameList.join( TQString::fromLatin1( ",\n" ) );
03029 apology = apology.arg( names );
03030 }
03031
03032 KMessageBox::sorry( parentWidget(), apology );
03033 return Failed;
03034 }
03035 }
03036
03037 KMHandleAttachmentCommand::KMHandleAttachmentCommand( partNode* node,
03038 KMMessage* msg, int atmId, const TQString& atmName,
03039 AttachmentAction action, KService::Ptr offer, TQWidget* parent )
03040 : KMCommand( parent ), mNode( node ), mMsg( msg ), mAtmId( atmId ), mAtmName( atmName ),
03041 mAction( action ), mOffer( offer ), mJob( 0 )
03042 {
03043 }
03044
03045 void KMHandleAttachmentCommand::slotStart()
03046 {
03047 if ( !mNode->msgPart().isComplete() )
03048 {
03049
03050 kdDebug(5006) << "load part" << endl;
03051 KMLoadPartsCommand *command = new KMLoadPartsCommand( mNode, mMsg );
03052 connect( command, TQT_SIGNAL( partsRetrieved() ),
03053 this, TQT_SLOT( slotPartComplete() ) );
03054 command->start();
03055 } else
03056 {
03057 execute();
03058 }
03059 }
03060
03061 void KMHandleAttachmentCommand::slotPartComplete()
03062 {
03063 execute();
03064 }
03065
03066 KMCommand::Result KMHandleAttachmentCommand::execute()
03067 {
03068 switch( mAction )
03069 {
03070 case Open:
03071 atmOpen();
03072 break;
03073 case OpenWith:
03074 atmOpenWith();
03075 break;
03076 case View:
03077 atmView();
03078 break;
03079 case Save:
03080 atmSave();
03081 break;
03082 case Properties:
03083 atmProperties();
03084 break;
03085 case ChiasmusEncrypt:
03086 atmEncryptWithChiasmus();
03087 return Undefined;
03088 break;
03089 default:
03090 kdDebug(5006) << "unknown action " << mAction << endl;
03091 break;
03092 }
03093 setResult( OK );
03094 emit completed( this );
03095 deleteLater();
03096 return OK;
03097 }
03098
03099 TQString KMHandleAttachmentCommand::createAtmFileLink() const
03100 {
03101 TQFileInfo atmFileInfo( mAtmName );
03102
03103 if ( atmFileInfo.size() == 0 )
03104 {
03105 kdDebug(5006) << k_funcinfo << "rewriting attachment" << endl;
03106
03107 TQByteArray data = mNode->msgPart().bodyDecodedBinary();
03108 size_t size = data.size();
03109 if ( mNode->msgPart().type() == DwMime::kTypeText && size) {
03110
03111 size = KMail::Util::crlf2lf( data.data(), size );
03112 }
03113 KPIM::kBytesToFile( data.data(), size, mAtmName, false, false, false );
03114 }
03115
03116 KTempFile *linkFile = new KTempFile( locateLocal("tmp", atmFileInfo.fileName() +"_["),
03117 "]."+ atmFileInfo.extension() );
03118
03119 linkFile->setAutoDelete(true);
03120 TQString linkName = linkFile->name();
03121 delete linkFile;
03122
03123 if ( ::link(TQFile::encodeName( mAtmName ), TQFile::encodeName( linkName )) == 0 ) {
03124 return linkName;
03125 }
03126 return TQString();
03127 }
03128
03129 KService::Ptr KMHandleAttachmentCommand::getServiceOffer()
03130 {
03131 KMMessagePart& msgPart = mNode->msgPart();
03132 const TQString contentTypeStr =
03133 ( msgPart.typeStr() + '/' + msgPart.subtypeStr() ).lower();
03134
03135 if ( contentTypeStr == "text/x-vcard" ) {
03136 atmView();
03137 return 0;
03138 }
03139
03140 KMimeType::Ptr mimetype;
03141
03142 mimetype = KMimeType::mimeType( contentTypeStr );
03143 if ( mimetype->name() == "application/octet-stream" ) {
03144
03145 mimetype = KMimeType::findByPath( mAtmName, 0, true );
03146 }
03147 if ( ( mimetype->name() == "application/octet-stream" )
03148 && msgPart.isComplete() ) {
03149
03150
03151 mimetype = KMimeType::findByFileContent( mAtmName );
03152 }
03153 return KServiceTypeProfile::preferredService( mimetype->name(), "Application" );
03154 }
03155
03156 void KMHandleAttachmentCommand::atmOpen()
03157 {
03158 if ( !mOffer )
03159 mOffer = getServiceOffer();
03160 if ( !mOffer ) {
03161 kdDebug(5006) << k_funcinfo << "got no offer" << endl;
03162 return;
03163 }
03164
03165 KURL::List lst;
03166 KURL url;
03167 bool autoDelete = true;
03168 TQString fname = createAtmFileLink();
03169
03170 if ( fname.isNull() ) {
03171 autoDelete = false;
03172 fname = mAtmName;
03173 }
03174
03175 url.setPath( fname );
03176 lst.append( url );
03177 if ( (KRun::run( *mOffer, lst, autoDelete ) <= 0) && autoDelete ) {
03178 TQFile::remove(url.path());
03179 }
03180 }
03181
03182 void KMHandleAttachmentCommand::atmOpenWith()
03183 {
03184 KURL::List lst;
03185 KURL url;
03186 bool autoDelete = true;
03187 TQString fname = createAtmFileLink();
03188
03189 if ( fname.isNull() ) {
03190 autoDelete = false;
03191 fname = mAtmName;
03192 }
03193
03194 url.setPath( fname );
03195 lst.append( url );
03196 if ( (! KRun::displayOpenWithDialog(lst, autoDelete)) && autoDelete ) {
03197 TQFile::remove( url.path() );
03198 }
03199 }
03200
03201 void KMHandleAttachmentCommand::atmView()
03202 {
03203
03204 emit showAttachment( mAtmId, mAtmName );
03205 }
03206
03207 void KMHandleAttachmentCommand::atmSave()
03208 {
03209 TQPtrList<partNode> parts;
03210 parts.append( mNode );
03211
03212 KMSaveAttachmentsCommand *command =
03213 new KMSaveAttachmentsCommand( parentWidget(), parts, mMsg, false );
03214 command->start();
03215 }
03216
03217 void KMHandleAttachmentCommand::atmProperties()
03218 {
03219 KMMsgPartDialogCompat dlg( parentWidget() , 0, true );
03220 KMMessagePart& msgPart = mNode->msgPart();
03221 dlg.setMsgPart( &msgPart );
03222 dlg.exec();
03223 }
03224
03225 void KMHandleAttachmentCommand::atmEncryptWithChiasmus()
03226 {
03227 const partNode * node = mNode;
03228 Q_ASSERT( node );
03229 if ( !node )
03230 return;
03231
03232
03233 if ( !mAtmName.endsWith( ".xia", false ) )
03234 return;
03235
03236 const Kleo::CryptoBackend::Protocol * chiasmus =
03237 Kleo::CryptoBackendFactory::instance()->protocol( "Chiasmus" );
03238 Q_ASSERT( chiasmus );
03239 if ( !chiasmus )
03240 return;
03241
03242 const STD_NAMESPACE_PREFIX auto_ptr<Kleo::SpecialJob> listjob( chiasmus->specialJob( "x-obtain-keys", TQMap<TQString,TQVariant>() ) );
03243 if ( !listjob.get() ) {
03244 const TQString msg = i18n( "Chiasmus backend does not offer the "
03245 "\"x-obtain-keys\" function. Please report this bug." );
03246 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03247 return;
03248 }
03249
03250 if ( listjob->exec() ) {
03251 listjob->showErrorDialog( parentWidget(), i18n( "Chiasmus Backend Error" ) );
03252 return;
03253 }
03254
03255 const TQVariant result = listjob->property( "result" );
03256 if ( result.type() != TQVariant::StringList ) {
03257 const TQString msg = i18n( "Unexpected return value from Chiasmus backend: "
03258 "The \"x-obtain-keys\" function did not return a "
03259 "string list. Please report this bug." );
03260 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03261 return;
03262 }
03263
03264 const TQStringList keys = result.toStringList();
03265 if ( keys.empty() ) {
03266 const TQString msg = i18n( "No keys have been found. Please check that a "
03267 "valid key path has been set in the Chiasmus "
03268 "configuration." );
03269 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03270 return;
03271 }
03272
03273 ChiasmusKeySelector selectorDlg( parentWidget(), i18n( "Chiasmus Decryption Key Selection" ),
03274 keys, GlobalSettings::chiasmusDecryptionKey(),
03275 GlobalSettings::chiasmusDecryptionOptions() );
03276 if ( selectorDlg.exec() != TQDialog::Accepted )
03277 return;
03278
03279 GlobalSettings::setChiasmusDecryptionOptions( selectorDlg.options() );
03280 GlobalSettings::setChiasmusDecryptionKey( selectorDlg.key() );
03281 assert( !GlobalSettings::chiasmusDecryptionKey().isEmpty() );
03282
03283 Kleo::SpecialJob * job = chiasmus->specialJob( "x-decrypt", TQMap<TQString,TQVariant>() );
03284 if ( !job ) {
03285 const TQString msg = i18n( "Chiasmus backend does not offer the "
03286 "\"x-decrypt\" function. Please report this bug." );
03287 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03288 return;
03289 }
03290
03291 const TQByteArray input = node->msgPart().bodyDecodedBinary();
03292
03293 if ( !job->setProperty( "key", GlobalSettings::chiasmusDecryptionKey() ) ||
03294 !job->setProperty( "options", GlobalSettings::chiasmusDecryptionOptions() ) ||
03295 !job->setProperty( "input", input ) ) {
03296 const TQString msg = i18n( "The \"x-decrypt\" function does not accept "
03297 "the expected parameters. Please report this bug." );
03298 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03299 return;
03300 }
03301
03302 setDeletesItself( true );
03303 if ( job->start() ) {
03304 job->showErrorDialog( parentWidget(), i18n( "Chiasmus Decryption Error" ) );
03305 return;
03306 }
03307
03308 mJob = job;
03309 connect( job, TQT_SIGNAL(result(const GpgME::Error&,const TQVariant&)),
03310 this, TQT_SLOT(slotAtmDecryptWithChiasmusResult(const GpgME::Error&,const TQVariant&)) );
03311 }
03312
03313 static const TQString chomp( const TQString & base, const TQString & suffix, bool cs ) {
03314 return base.endsWith( suffix, cs ) ? base.left( base.length() - suffix.length() ) : base ;
03315 }
03316
03317 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusResult( const GpgME::Error & err, const TQVariant & result )
03318 {
03319 LaterDeleterWithCommandCompletion d( this );
03320 if ( !mJob )
03321 return;
03322 Q_ASSERT( mJob == sender() );
03323 if ( mJob != sender() )
03324 return;
03325 Kleo::Job * job = mJob;
03326 mJob = 0;
03327 if ( err.isCanceled() )
03328 return;
03329 if ( err ) {
03330 job->showErrorDialog( parentWidget(), i18n( "Chiasmus Decryption Error" ) );
03331 return;
03332 }
03333
03334 if ( result.type() != TQVariant::ByteArray ) {
03335 const TQString msg = i18n( "Unexpected return value from Chiasmus backend: "
03336 "The \"x-decrypt\" function did not return a "
03337 "byte array. Please report this bug." );
03338 KMessageBox::error( parentWidget(), msg, i18n( "Chiasmus Backend Error" ) );
03339 return;
03340 }
03341
03342 const KURL url = KFileDialog::getSaveURL( chomp( mAtmName, ".xia", false ), TQString(), parentWidget() );
03343 if ( url.isEmpty() )
03344 return;
03345
03346 bool overwrite = KMail::Util::checkOverwrite( url, parentWidget() );
03347 if ( !overwrite )
03348 return;
03349
03350 d.setDisabled( true );
03351 TDEIO::Job * uploadJob = TDEIO::storedPut( result.toByteArray(), url, -1, overwrite, false );
03352 uploadJob->setWindow( parentWidget() );
03353 connect( uploadJob, TQT_SIGNAL(result(TDEIO::Job*)),
03354 this, TQT_SLOT(slotAtmDecryptWithChiasmusUploadResult(TDEIO::Job*)) );
03355 }
03356
03357 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusUploadResult( TDEIO::Job * job )
03358 {
03359 if ( job->error() )
03360 job->showErrorDialog();
03361 LaterDeleterWithCommandCompletion d( this );
03362 d.setResult( OK );
03363 }
03364
03365
03366 AttachmentModifyCommand::AttachmentModifyCommand(partNode * node, KMMessage * msg, TQWidget * parent) :
03367 KMCommand( parent, msg ),
03368 mPartIndex( node->nodeId() ),
03369 mSernum( 0 )
03370 {
03371 }
03372
03373 AttachmentModifyCommand::AttachmentModifyCommand( int nodeId, KMMessage *msg, TQWidget *parent )
03374 : KMCommand( parent, msg ),
03375 mPartIndex( nodeId ),
03376 mSernum( 0 )
03377 {
03378 }
03379
03380 AttachmentModifyCommand::~ AttachmentModifyCommand()
03381 {
03382 }
03383
03384 KMCommand::Result AttachmentModifyCommand::execute()
03385 {
03386 KMMessage *msg = retrievedMessage();
03387 if ( !msg )
03388 return Failed;
03389 mSernum = msg->getMsgSerNum();
03390
03391 mFolder = msg->parent();
03392 if ( !mFolder || !mFolder->storage() )
03393 return Failed;
03394
03395 Result res = doAttachmentModify();
03396 if ( res != OK )
03397 return res;
03398
03399 setEmitsCompletedItself( true );
03400 setDeletesItself( true );
03401 return OK;
03402 }
03403
03404 void AttachmentModifyCommand::storeChangedMessage(KMMessage * msg)
03405 {
03406 if ( !mFolder || !mFolder->storage() ) {
03407 kdWarning(5006) << k_funcinfo << "We lost the folder!" << endl;
03408 setResult( Failed );
03409 emit completed( this );
03410 deleteLater();
03411 }
03412 int res = mFolder->addMsg( msg ) != 0;
03413 if ( mFolder->folderType() == KMFolderTypeImap ) {
03414 KMFolderImap *f = static_cast<KMFolderImap*>( mFolder->storage() );
03415 connect( f, TQT_SIGNAL(folderComplete(KMFolderImap*,bool)),
03416 TQT_SLOT(messageStoreResult(KMFolderImap*,bool)) );
03417 } else {
03418 messageStoreResult( 0, res == 0 );
03419 }
03420 }
03421
03422 void AttachmentModifyCommand::messageStoreResult(KMFolderImap* folder, bool success )
03423 {
03424 Q_UNUSED( folder );
03425 if ( success ) {
03426 KMCommand *delCmd = new KMDeleteMsgCommand( mSernum );
03427 connect( delCmd, TQT_SIGNAL(completed(KMCommand*)), TQT_SLOT(messageDeleteResult(KMCommand*)) );
03428 delCmd->start();
03429 return;
03430 }
03431 kdWarning(5006) << k_funcinfo << "Adding modified message failed." << endl;
03432 setResult( Failed );
03433 emit completed( this );
03434 deleteLater();
03435 }
03436
03437 void AttachmentModifyCommand::messageDeleteResult(KMCommand * cmd)
03438 {
03439 setResult( cmd->result() );
03440 emit completed( this );
03441 deleteLater();
03442 }
03443
03444 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(partNode * node, KMMessage * msg, TQWidget * parent) :
03445 AttachmentModifyCommand( node, msg, parent )
03446 {
03447 kdDebug(5006) << k_funcinfo << endl;
03448 }
03449
03450 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand( int nodeId, KMMessage *msg, TQWidget *parent )
03451 : AttachmentModifyCommand( nodeId, msg, parent )
03452 {
03453 kdDebug(5006) << k_funcinfo << endl;
03454 }
03455
03456 KMDeleteAttachmentCommand::~KMDeleteAttachmentCommand()
03457 {
03458 kdDebug(5006) << k_funcinfo << endl;
03459 }
03460
03461 KMCommand::Result KMDeleteAttachmentCommand::doAttachmentModify()
03462 {
03463 KMMessage *msg = retrievedMessage();
03464 if ( !msg || !msg->deleteBodyPart( mPartIndex ) )
03465 return Failed;
03466
03467 KMMessage *newMsg = new KMMessage();
03468 newMsg->fromDwString( msg->asDwString() );
03469 newMsg->setStatus( msg->status() );
03470
03471 storeChangedMessage( newMsg );
03472 return OK;
03473 }
03474
03475
03476 KMEditAttachmentCommand::KMEditAttachmentCommand(partNode * node, KMMessage * msg, TQWidget * parent) :
03477 AttachmentModifyCommand( node, msg, parent )
03478 {
03479 kdDebug(5006) << k_funcinfo << endl;
03480 mTempFile.setAutoDelete( true );
03481 }
03482
03483 KMEditAttachmentCommand::KMEditAttachmentCommand( int nodeId, KMMessage *msg, TQWidget *parent )
03484 : AttachmentModifyCommand( nodeId, msg, parent )
03485 {
03486 kdDebug(5006) << k_funcinfo << endl;
03487 mTempFile.setAutoDelete( true );
03488 }
03489
03490 KMEditAttachmentCommand::~ KMEditAttachmentCommand()
03491 {
03492 }
03493
03494 KMCommand::Result KMEditAttachmentCommand::doAttachmentModify()
03495 {
03496 KMMessage *msg = retrievedMessage();
03497 if ( !msg )
03498 return Failed;
03499
03500 KMMessagePart part;
03501 DwBodyPart *dwpart = msg->findPart( mPartIndex );
03502 if ( !dwpart )
03503 return Failed;
03504 KMMessage::bodyPart( dwpart, &part, true );
03505 if ( !part.isComplete() )
03506 return Failed;
03507
03508 if( !dynamic_cast<DwBody*>( dwpart->Parent() ) )
03509 return Failed;
03510
03511 mTempFile.file()->writeBlock( part.bodyDecodedBinary() );
03512 mTempFile.file()->flush();
03513
03514 KMail::EditorWatcher *watcher =
03515 new KMail::EditorWatcher( KURL( mTempFile.file()->name() ),
03516 part.typeStr() + "/" + part.subtypeStr(),
03517 false, this, parentWidget() );
03518 connect( watcher, TQT_SIGNAL(editDone(KMail::EditorWatcher*)), TQT_SLOT(editDone(KMail::EditorWatcher*)) );
03519 if ( !watcher->start() )
03520 return Failed;
03521 setEmitsCompletedItself( true );
03522 setDeletesItself( true );
03523 return OK;
03524 }
03525
03526 void KMEditAttachmentCommand::editDone(KMail::EditorWatcher * watcher)
03527 {
03528 kdDebug(5006) << k_funcinfo << endl;
03529
03530 if ( !watcher->fileChanged() ) {
03531 kdDebug(5006) << k_funcinfo << "File has not been changed" << endl;
03532 setResult( Canceled );
03533 emit completed( this );
03534 deleteLater();
03535 }
03536
03537 mTempFile.file()->reset();
03538 TQByteArray data = mTempFile.file()->readAll();
03539
03540
03541 KMMessage *msg = retrievedMessage();
03542 KMMessagePart part;
03543 DwBodyPart *dwpart = msg->findPart( mPartIndex );
03544 KMMessage::bodyPart( dwpart, &part, true );
03545
03546 DwBody *parentNode = dynamic_cast<DwBody*>( dwpart->Parent() );
03547 assert( parentNode );
03548 parentNode->RemoveBodyPart( dwpart );
03549
03550 KMMessagePart att;
03551 att.duplicate( part );
03552 att.setBodyEncodedBinary( data );
03553
03554 DwBodyPart* newDwPart = msg->createDWBodyPart( &att );
03555 parentNode->AddBodyPart( newDwPart );
03556 msg->getTopLevelPart()->Assemble();
03557
03558 KMMessage *newMsg = new KMMessage();
03559 newMsg->fromDwString( msg->asDwString() );
03560 newMsg->setStatus( msg->status() );
03561
03562 storeChangedMessage( newMsg );
03563 }
03564
03565
03566 CreateTodoCommand::CreateTodoCommand(TQWidget * parent, KMMessage * msg)
03567 : KMCommand( parent, msg )
03568 {
03569 }
03570
03571 KMCommand::Result CreateTodoCommand::execute()
03572 {
03573 KMMessage *msg = retrievedMessage();
03574 if ( !msg || !msg->codec() ) {
03575 return Failed;
03576 }
03577
03578 KMail::KorgHelper::ensureRunning();
03579
03580 TQString txt = i18n("From: %1\nTo: %2\nSubject: %3").arg( msg->from() )
03581 .arg( msg->to() ).arg( msg->subject() );
03582
03583 KTempFile tf;
03584 tf.setAutoDelete( true );
03585 TQString uri = "kmail:" + TQString::number( msg->getMsgSerNum() ) + "/" + msg->msgId();
03586 tf.file()->writeBlock( msg->asDwString().c_str(), msg->asDwString().length() );
03587 tf.close();
03588
03589 KCalendarIface_stub *iface = new KCalendarIface_stub( kapp->dcopClient(), "korganizer", "CalendarIface" );
03590 iface->openTodoEditor( i18n("Mail: %1").arg( msg->subject() ), txt, uri,
03591 tf.name(), TQStringList(), "message/rfc822", true );
03592 delete iface;
03593
03594 return OK;
03595 }
03596
03597 #include "kmcommands.moc"