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 #include "kmcommands.h"
00030
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034
00035 #include <errno.h>
00036 #include <mimelib/enum.h>
00037 #include <mimelib/field.h>
00038 #include <mimelib/mimepp.h>
00039 #include <mimelib/string.h>
00040 #include <kapplication.h>
00041 #include <dcopclient.h>
00042
00043 #include <qtextcodec.h>
00044
00045 #include <libkdepim/email.h>
00046 #include <kdebug.h>
00047 #include <kencodingfiledialog.h>
00048 #include <kio/netaccess.h>
00049 #include <kabc/stdaddressbook.h>
00050 #include <kabc/addresseelist.h>
00051 #include <klocale.h>
00052 #include <kmessagebox.h>
00053 #include <kparts/browserextension.h>
00054 #include <kprogress.h>
00055 #include <krun.h>
00056 #include <kbookmarkmanager.h>
00057 #include <kstandarddirs.h>
00058 #include <ktempfile.h>
00059 #if !KDE_IS_VERSION( 3, 3, 0 )
00060 # include <storedtransferjob.h>
00061 #endif
00062 #include "actionscheduler.h"
00063 using KMail::ActionScheduler;
00064 #include "mailinglist-magic.h"
00065 #include "kmaddrbook.h"
00066 #include <kaddrbook.h>
00067 #include "kmcomposewin.h"
00068 #include "kmfiltermgr.h"
00069 #include "kmfoldermbox.h"
00070 #include "kmfolderimap.h"
00071 #include "kmfoldermgr.h"
00072 #include "kmheaders.h"
00073 #include "kmmainwidget.h"
00074 #include "kmmsgdict.h"
00075 #include "messagesender.h"
00076 #include "undostack.h"
00077 #include "kcursorsaver.h"
00078 #include "partNode.h"
00079 #include "objecttreeparser.h"
00080 using KMail::ObjectTreeParser;
00081 using KMail::FolderJob;
00082 #include "mailsourceviewer.h"
00083 using KMail::MailSourceViewer;
00084 #include "kmreadermainwin.h"
00085 #include "secondarywindow.h"
00086 using KMail::SecondaryWindow;
00087 #include "kimproxy.h"
00088
00089 #include "progressmanager.h"
00090 using KPIM::ProgressManager;
00091 using KPIM::ProgressItem;
00092
00093 #include "broadcaststatus.h"
00094
00095 #include "headerstrategy.h"
00096 using KMail::HeaderStrategy;
00097 #include "headerstyle.h"
00098 using KMail::HeaderStyle;
00099
00100 #include "kmcommands.moc"
00101
00102 KMCommand::KMCommand( QWidget *parent )
00103 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00104 mEmitsCompletedItself( false ), mParent( parent )
00105 {
00106 }
00107
00108 KMCommand::KMCommand( QWidget *parent, const QPtrList<KMMsgBase> &msgList )
00109 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00110 mEmitsCompletedItself( false ), mParent( parent ), mMsgList( msgList )
00111 {
00112 }
00113
00114 KMCommand::KMCommand( QWidget *parent, KMMsgBase *msgBase )
00115 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00116 mEmitsCompletedItself( false ), mParent( parent )
00117 {
00118 mMsgList.append( msgBase );
00119 }
00120
00121 KMCommand::KMCommand( QWidget *parent, KMMessage *msg )
00122 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
00123 mEmitsCompletedItself( false ), mParent( parent )
00124 {
00125 mMsgList.append( &msg->toMsgBase() );
00126 }
00127
00128 KMCommand::~KMCommand()
00129 {
00130 QValueListIterator<QGuardedPtr<KMFolder> > fit;
00131 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
00132 if (!(*fit))
00133 continue;
00134 (*fit)->close();
00135 }
00136 }
00137
00138 KMCommand::Result KMCommand::result()
00139 {
00140 if ( mResult == Undefined )
00141 kdDebug(5006) << k_funcinfo << "mResult is Undefined" << endl;
00142 return mResult;
00143 }
00144
00145 void KMCommand::start()
00146 {
00147 QTimer::singleShot( 0, this, SLOT( slotStart() ) );
00148 }
00149
00150
00151 const QPtrList<KMMessage> KMCommand::retrievedMsgs() const
00152 {
00153 return mRetrievedMsgs;
00154 }
00155
00156 KMMessage *KMCommand::retrievedMessage() const
00157 {
00158 return mRetrievedMsgs.getFirst();
00159 }
00160
00161 QWidget *KMCommand::parentWidget() const
00162 {
00163 return mParent;
00164 }
00165
00166 int KMCommand::mCountJobs = 0;
00167
00168 void KMCommand::slotStart()
00169 {
00170 connect( this, SIGNAL( messagesTransfered( KMCommand::Result ) ),
00171 this, SLOT( slotPostTransfer( KMCommand::Result ) ) );
00172 kmkernel->filterMgr()->ref();
00173
00174 if (mMsgList.find(0) != -1) {
00175 emit messagesTransfered( Failed );
00176 return;
00177 }
00178
00179 if ((mMsgList.count() == 1) &&
00180 (mMsgList.getFirst()->isMessage()) &&
00181 (mMsgList.getFirst()->parent() == 0))
00182 {
00183
00184 mRetrievedMsgs.append((KMMessage*)mMsgList.getFirst());
00185 emit messagesTransfered( OK );
00186 return;
00187 }
00188
00189 for (KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next())
00190 if (!mb->parent()) {
00191 emit messagesTransfered( Failed );
00192 return;
00193 } else {
00194 mFolders.append( mb->parent() );
00195 mb->parent()->open();
00196 }
00197
00198
00199 transferSelectedMsgs();
00200 }
00201
00202 void KMCommand::slotPostTransfer( KMCommand::Result result )
00203 {
00204 disconnect( this, SIGNAL( messagesTransfered( KMCommand::Result ) ),
00205 this, SLOT( slotPostTransfer( KMCommand::Result ) ) );
00206 if ( result == OK )
00207 result = execute();
00208 mResult = result;
00209 QPtrListIterator<KMMessage> it( mRetrievedMsgs );
00210 KMMessage* msg;
00211 while ( (msg = it.current()) != 0 )
00212 {
00213 ++it;
00214 if (msg->parent())
00215 msg->setTransferInProgress(false);
00216 }
00217 kmkernel->filterMgr()->deref();
00218 if ( !emitsCompletedItself() )
00219 emit completed( this );
00220 if ( !deletesItself() )
00221 deleteLater();
00222 }
00223
00224 void KMCommand::transferSelectedMsgs()
00225 {
00226
00227 if (KMCommand::mCountJobs > 0) {
00228 emit messagesTransfered( Failed );
00229 return;
00230 }
00231
00232 bool complete = true;
00233 KMCommand::mCountJobs = 0;
00234 mCountMsgs = 0;
00235 mRetrievedMsgs.clear();
00236 mCountMsgs = mMsgList.count();
00237 uint totalSize = 0;
00238
00239
00240
00241
00242 if ( mCountMsgs > 0 ) {
00243 mProgressDialog = new KProgressDialog(mParent, "transferProgress",
00244 i18n("Please wait"),
00245 i18n("Please wait while the message is transferred",
00246 "Please wait while the %n messages are transferred", mMsgList.count()),
00247 true);
00248 mProgressDialog->setMinimumDuration(1000);
00249 }
00250 for (KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next())
00251 {
00252
00253 KMMessage *thisMsg = 0;
00254 if ( mb->isMessage() )
00255 thisMsg = static_cast<KMMessage*>(mb);
00256 else
00257 {
00258 KMFolder *folder = mb->parent();
00259 int idx = folder->find(mb);
00260 if (idx < 0) continue;
00261 thisMsg = folder->getMsg(idx);
00262 }
00263 if (!thisMsg) continue;
00264 if ( thisMsg->transferInProgress() &&
00265 thisMsg->parent()->folderType() == KMFolderTypeImap )
00266 {
00267 thisMsg->setTransferInProgress( false, true );
00268 thisMsg->parent()->ignoreJobsForMessage( thisMsg );
00269 }
00270
00271 if ( thisMsg->parent() && !thisMsg->isComplete() &&
00272 ( !mProgressDialog || !mProgressDialog->wasCancelled() ) )
00273 {
00274 kdDebug(5006)<<"### INCOMPLETE\n";
00275
00276 complete = false;
00277 KMCommand::mCountJobs++;
00278 FolderJob *job = thisMsg->parent()->createJob(thisMsg);
00279 job->setCancellable( false );
00280 totalSize += thisMsg->msgSizeServer();
00281
00282 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
00283 this, SLOT(slotMsgTransfered(KMMessage*)));
00284
00285 connect(job, SIGNAL(finished()),
00286 this, SLOT(slotJobFinished()));
00287 connect(job, SIGNAL(progress(unsigned long, unsigned long)),
00288 this, SLOT(slotProgress(unsigned long, unsigned long)));
00289
00290 thisMsg->setTransferInProgress(true);
00291 job->start();
00292 } else {
00293 thisMsg->setTransferInProgress(true);
00294 mRetrievedMsgs.append(thisMsg);
00295 }
00296 }
00297
00298 if (complete)
00299 {
00300 delete mProgressDialog;
00301 mProgressDialog = 0;
00302 emit messagesTransfered( OK );
00303 } else {
00304
00305 if ( mProgressDialog ) {
00306 connect(mProgressDialog, SIGNAL(cancelClicked()),
00307 this, SLOT(slotTransferCancelled()));
00308 mProgressDialog->progressBar()->setTotalSteps(totalSize);
00309 }
00310 }
00311 }
00312
00313 void KMCommand::slotMsgTransfered(KMMessage* msg)
00314 {
00315 if ( mProgressDialog && mProgressDialog->wasCancelled() ) {
00316 emit messagesTransfered( Canceled );
00317 return;
00318 }
00319
00320
00321 mRetrievedMsgs.append(msg);
00322 }
00323
00324 void KMCommand::slotProgress( unsigned long done, unsigned long )
00325 {
00326 mProgressDialog->progressBar()->setProgress( done );
00327 }
00328
00329 void KMCommand::slotJobFinished()
00330 {
00331
00332 KMCommand::mCountJobs--;
00333
00334 if ( mProgressDialog && mProgressDialog->wasCancelled() ) return;
00335
00336 if ( (mCountMsgs - static_cast<int>(mRetrievedMsgs.count())) > KMCommand::mCountJobs )
00337 {
00338
00339 if ( mProgressDialog )
00340 mProgressDialog->hide();
00341 slotTransferCancelled();
00342 return;
00343 }
00344
00345 if ( mProgressDialog ) {
00346 mProgressDialog->setLabel(i18n("Please wait while the message is transferred",
00347 "Please wait while the %n messages are transferred", KMCommand::mCountJobs));
00348 }
00349 if (KMCommand::mCountJobs == 0)
00350 {
00351
00352 delete mProgressDialog;
00353 mProgressDialog = 0;
00354 emit messagesTransfered( OK );
00355 }
00356 }
00357
00358 void KMCommand::slotTransferCancelled()
00359 {
00360
00361 QValueListIterator<QGuardedPtr<KMFolder> > fit;
00362 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
00363 if (!(*fit))
00364 continue;
00365 KMFolder *folder = *fit;
00366 KMFolderImap *imapFolder = dynamic_cast<KMFolderImap*>(folder);
00367 if (imapFolder && imapFolder->account()) {
00368 imapFolder->account()->killAllJobs();
00369 }
00370 }
00371
00372 KMCommand::mCountJobs = 0;
00373 mCountMsgs = 0;
00374
00375 QPtrListIterator<KMMessage> it( mRetrievedMsgs );
00376 KMMessage* msg;
00377 while ( (msg = it.current()) != 0 )
00378 {
00379 KMFolder *folder = msg->parent();
00380 ++it;
00381 if (!folder)
00382 continue;
00383 msg->setTransferInProgress(false);
00384 int idx = folder->find(msg);
00385 if (idx > 0) folder->unGetMsg(idx);
00386 }
00387 mRetrievedMsgs.clear();
00388 emit messagesTransfered( Canceled );
00389 }
00390
00391 void KMCommand::keepFolderOpen( KMFolder *folder )
00392 {
00393 folder->open();
00394 mFolders.append( folder );
00395 }
00396
00397 KMMailtoComposeCommand::KMMailtoComposeCommand( const KURL &url,
00398 KMMessage *msg )
00399 :mUrl( url ), mMessage( msg )
00400 {
00401 }
00402
00403 KMCommand::Result KMMailtoComposeCommand::execute()
00404 {
00405 KMComposeWin *win;
00406 KMMessage *msg = new KMMessage;
00407 uint id = 0;
00408
00409 if ( mMessage && mMessage->parent() )
00410 id = mMessage->parent()->identity();
00411
00412 msg->initHeader(id);
00413 msg->setCharset("utf-8");
00414 msg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00415
00416 win = new KMComposeWin(msg, id);
00417 win->setCharset("", TRUE);
00418 win->setFocusToSubject();
00419 win->show();
00420
00421 return OK;
00422 }
00423
00424
00425 KMMailtoReplyCommand::KMMailtoReplyCommand( QWidget *parent,
00426 const KURL &url, KMMessage *msg, const QString &selection )
00427 :KMCommand( parent, msg ), mUrl( url ), mSelection( selection )
00428 {
00429 }
00430
00431 KMCommand::Result KMMailtoReplyCommand::execute()
00432 {
00433
00434 KMMessage *msg = retrievedMessage();
00435 KMComposeWin *win;
00436 KMMessage *rmsg = msg->createReply( KMail::ReplyNone, mSelection );
00437 rmsg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00438
00439 win = new KMComposeWin(rmsg, 0);
00440 win->setCharset(msg->codec()->mimeName(), TRUE);
00441 win->setReplyFocus();
00442 win->show();
00443
00444 return OK;
00445 }
00446
00447
00448 KMMailtoForwardCommand::KMMailtoForwardCommand( QWidget *parent,
00449 const KURL &url, KMMessage *msg )
00450 :KMCommand( parent, msg ), mUrl( url )
00451 {
00452 }
00453
00454 KMCommand::Result KMMailtoForwardCommand::execute()
00455 {
00456
00457 KMMessage *msg = retrievedMessage();
00458 KMComposeWin *win;
00459 KMMessage *fmsg = msg->createForward();
00460 fmsg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
00461
00462 win = new KMComposeWin(fmsg);
00463 win->setCharset(msg->codec()->mimeName(), TRUE);
00464 win->show();
00465
00466 return OK;
00467 }
00468
00469
00470 KMAddBookmarksCommand::KMAddBookmarksCommand( const KURL &url, QWidget *parent )
00471 : KMCommand( parent ), mUrl( url )
00472 {
00473 }
00474
00475 KMCommand::Result KMAddBookmarksCommand::execute()
00476 {
00477 QString filename = locateLocal( "data", QString::fromLatin1("konqueror/bookmarks.xml") );
00478 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename,
00479 false );
00480 KBookmarkGroup group = bookManager->root();
00481 group.addBookmark( bookManager, mUrl.path(), KURL( mUrl ) );
00482 if( bookManager->save() ) {
00483 bookManager->emitChanged( group );
00484 }
00485
00486 return OK;
00487 }
00488
00489 KMMailtoAddAddrBookCommand::KMMailtoAddAddrBookCommand( const KURL &url,
00490 QWidget *parent )
00491 : KMCommand( parent ), mUrl( url )
00492 {
00493 }
00494
00495 KMCommand::Result KMMailtoAddAddrBookCommand::execute()
00496 {
00497 KAddrBookExternal::addEmail( KMMessage::decodeMailtoUrl( mUrl.path() ),
00498 parentWidget() );
00499
00500 return OK;
00501 }
00502
00503
00504 KMMailtoOpenAddrBookCommand::KMMailtoOpenAddrBookCommand( const KURL &url,
00505 QWidget *parent )
00506 : KMCommand( parent ), mUrl( url )
00507 {
00508 }
00509
00510 KMCommand::Result KMMailtoOpenAddrBookCommand::execute()
00511 {
00512 QString addr = KMMessage::decodeMailtoUrl( mUrl.path() );
00513 KAddrBookExternal::openEmail( KPIM::getEmailAddr(addr), addr ,
00514 parentWidget() );
00515
00516 return OK;
00517 }
00518
00519
00520 KMUrlCopyCommand::KMUrlCopyCommand( const KURL &url, KMMainWidget *mainWidget )
00521 :mUrl( url ), mMainWidget( mainWidget )
00522 {
00523 }
00524
00525 KMCommand::Result KMUrlCopyCommand::execute()
00526 {
00527 QClipboard* clip = QApplication::clipboard();
00528
00529 if (mUrl.protocol() == "mailto") {
00530
00531 QString address = KMMessage::decodeMailtoUrl( mUrl.path() );
00532 clip->setSelectionMode( true );
00533 clip->setText( address );
00534 clip->setSelectionMode( false );
00535 clip->setText( address );
00536 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n( "Address copied to clipboard." ));
00537 } else {
00538
00539 clip->setSelectionMode( true );
00540 clip->setText( mUrl.url() );
00541 clip->setSelectionMode( false );
00542 clip->setText( mUrl.url() );
00543 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n( "URL copied to clipboard." ));
00544 }
00545
00546 return OK;
00547 }
00548
00549
00550 KMUrlOpenCommand::KMUrlOpenCommand( const KURL &url, KMReaderWin *readerWin )
00551 :mUrl( url ), mReaderWin( readerWin )
00552 {
00553 }
00554
00555 KMCommand::Result KMUrlOpenCommand::execute()
00556 {
00557 if ( !mUrl.isEmpty() )
00558 mReaderWin->slotUrlOpen( mUrl, KParts::URLArgs() );
00559
00560 return OK;
00561 }
00562
00563
00564 KMUrlSaveCommand::KMUrlSaveCommand( const KURL &url, QWidget *parent )
00565 : KMCommand( parent ), mUrl( url )
00566 {
00567 }
00568
00569 KMCommand::Result KMUrlSaveCommand::execute()
00570 {
00571 if ( mUrl.isEmpty() )
00572 return OK;
00573 KURL saveUrl = KFileDialog::getSaveURL(mUrl.fileName(), QString::null,
00574 parentWidget() );
00575 if ( saveUrl.isEmpty() )
00576 return Canceled;
00577 if ( KIO::NetAccess::exists( saveUrl, false, parentWidget() ) )
00578 {
00579 if (KMessageBox::warningContinueCancel(0,
00580 i18n("<qt>File <b>%1</b> exists.<br>Do you want to replace it?</qt>")
00581 .arg(saveUrl.prettyURL()), i18n("Save to File"), i18n("&Replace"))
00582 != KMessageBox::Continue)
00583 return Canceled;
00584 }
00585 KIO::Job *job = KIO::file_copy(mUrl, saveUrl, -1, true);
00586 connect(job, SIGNAL(result(KIO::Job*)), SLOT(slotUrlSaveResult(KIO::Job*)));
00587 setEmitsCompletedItself( true );
00588 return OK;
00589 }
00590
00591 void KMUrlSaveCommand::slotUrlSaveResult( KIO::Job *job )
00592 {
00593 if ( job->error() ) {
00594 job->showErrorDialog();
00595 setResult( Failed );
00596 emit completed( this );
00597 }
00598 else {
00599 setResult( OK );
00600 emit completed( this );
00601 }
00602 }
00603
00604 #if KDE_IS_VERSION( 3, 3, 0 )
00605 # define KIO_STORED_PUT KIO::storedPut
00606 #else
00607
00608 # define KIO_STORED_PUT KIOext::put
00609 #endif
00610
00611 KMail::SaveTextAsCommand::SaveTextAsCommand( const QString & txt, QWidget * parent )
00612 : KMCommand( parent ), mText( txt ) {}
00613
00614 KMCommand::Result KMail::SaveTextAsCommand::execute() {
00615 if ( mText.isEmpty() )
00616 return OK;
00617
00618 const KEncodingFileDialog::Result res = KEncodingFileDialog::getSaveURLAndEncoding( QString::null, QString::null, QString::null, parentWidget() );
00619 if ( res.URLs.empty() )
00620 return Canceled;
00621 const KURL saveUrl = res.URLs.front();
00622 if ( !saveUrl.isValid() )
00623 return Canceled;
00624 if ( KIO::NetAccess::exists( saveUrl, false, parentWidget() ) ) {
00625 if (KMessageBox::warningContinueCancel(0,
00626 i18n("<qt>File <b>%1</b> exists.<br>Do you want to replace it?</qt>")
00627 .arg(saveUrl.prettyURL()), i18n("Save to File"), i18n("&Replace"))
00628 != KMessageBox::Continue)
00629 return Canceled;
00630 }
00631 const QTextCodec * codec = QTextCodec::codecForName( res.encoding.latin1() );
00632 Q_ASSERT( codec );
00633 if ( !codec )
00634 return Canceled;
00635 int len = -1;
00636 QByteArray data = codec->fromUnicode( mText, len );
00637 data.resize( len );
00638 KIO::Job * uploadJob = KIO_STORED_PUT( data, saveUrl, -1, true , false );
00639 uploadJob->setWindow( parentWidget() );
00640 connect( uploadJob, SIGNAL(result(KIO::Job*)), SLOT(slotResult(KIO::Job*)) );
00641 setEmitsCompletedItself( true );
00642 return OK;
00643 }
00644
00645 #undef KIO_STORED_PUT
00646
00647 void KMail::SaveTextAsCommand::slotResult( KIO::Job * job ) {
00648 if ( job->error() ) {
00649 job->showErrorDialog();
00650 setResult( Failed );
00651 } else {
00652 setResult( OK );
00653 }
00654 emit completed( this );
00655 }
00656
00657 KMEditMsgCommand::KMEditMsgCommand( QWidget *parent, KMMessage *msg )
00658 :KMCommand( parent, msg )
00659 {
00660 }
00661
00662 KMCommand::Result KMEditMsgCommand::execute()
00663 {
00664 KMMessage *msg = retrievedMessage();
00665 if (!msg || !msg->parent() ||
00666 !kmkernel->folderIsDraftOrOutbox( msg->parent() ))
00667 return Failed;
00668
00669
00670
00671
00672 KMFolder *parent = msg->parent();
00673 if ( parent )
00674 parent->take( parent->find( msg ) );
00675
00676 KMComposeWin *win = new KMComposeWin();
00677 msg->setTransferInProgress(false);
00678 win->setMsg(msg, FALSE, TRUE);
00679 win->setFolder( parent );
00680 win->show();
00681
00682 return OK;
00683 }
00684
00685 KMShowMsgSrcCommand::KMShowMsgSrcCommand( KMMessage *msg, bool fixedFont )
00686 : mFixedFont( fixedFont ), mMsg ( msg )
00687 {
00688 }
00689
00690 void KMShowMsgSrcCommand::start()
00691 {
00692 QString str = mMsg->codec()->toUnicode( mMsg->asString() );
00693
00694 MailSourceViewer *viewer = new MailSourceViewer();
00695 viewer->setCaption( i18n("Message as Plain Text") );
00696 viewer->setText(str);
00697 if( mFixedFont )
00698 viewer->setFont(KGlobalSettings::fixedFont());
00699
00700
00701
00702
00703 if (QApplication::desktop()->isVirtualDesktop()) {
00704 int scnum = QApplication::desktop()->screenNumber(QCursor::pos());
00705 viewer->resize(QApplication::desktop()->screenGeometry(scnum).width()/2,
00706 2*QApplication::desktop()->screenGeometry(scnum).height()/3);
00707 } else {
00708 viewer->resize(QApplication::desktop()->geometry().width()/2,
00709 2*QApplication::desktop()->geometry().height()/3);
00710 }
00711 viewer->show();
00712 }
00713
00714 static KURL subjectToUrl( const QString & subject ) {
00715 return KFileDialog::getSaveURL( subject.stripWhiteSpace()
00716 .replace( QDir::separator(), '_' ),
00717 "*.mbox" );
00718 }
00719
00720 KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, KMMessage * msg )
00721 : KMCommand( parent ),
00722 mMsgListIndex( 0 ),
00723 mStandAloneMessage( 0 ),
00724 mOffset( 0 ),
00725 mTotalSize( msg ? msg->msgSize() : 0 )
00726 {
00727 if ( !msg ) return;
00728 setDeletesItself( true );
00729
00730
00731
00732
00733 if ( msg->getMsgSerNum() != 0 ) {
00734 mMsgList.append( msg->getMsgSerNum() );
00735 if ( msg->parent() ) {
00736 msg->parent()->open();
00737 }
00738 } else {
00739 mStandAloneMessage = msg;
00740 }
00741 mUrl = subjectToUrl( msg->cleanSubject() );
00742 }
00743
00744 KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent,
00745 const QPtrList<KMMsgBase> &msgList )
00746 : KMCommand( parent ),
00747 mMsgListIndex( 0 ),
00748 mStandAloneMessage( 0 ),
00749 mOffset( 0 ),
00750 mTotalSize( 0 )
00751 {
00752 if (!msgList.getFirst())
00753 return;
00754 setDeletesItself( true );
00755 KMMsgBase *msgBase = msgList.getFirst();
00756
00757
00758
00759
00760 QPtrListIterator<KMMsgBase> it(msgList);
00761 while ( it.current() ) {
00762 mMsgList.append( (*it)->getMsgSerNum() );
00763 mTotalSize += (*it)->msgSize();
00764 if ((*it)->parent() != 0)
00765 (*it)->parent()->open();
00766 ++it;
00767 }
00768 mMsgListIndex = 0;
00769 mUrl = subjectToUrl( msgBase->cleanSubject() );
00770 }
00771
00772 KURL KMSaveMsgCommand::url()
00773 {
00774 return mUrl;
00775 }
00776
00777 KMCommand::Result KMSaveMsgCommand::execute()
00778 {
00779 mJob = KIO::put( mUrl, S_IRUSR|S_IWUSR, false, false );
00780 mJob->slotTotalSize( mTotalSize );
00781 mJob->setAsyncDataEnabled( true );
00782 mJob->setReportDataSent( true );
00783 connect(mJob, SIGNAL(dataReq(KIO::Job*, QByteArray &)),
00784 SLOT(slotSaveDataReq()));
00785 connect(mJob, SIGNAL(result(KIO::Job*)),
00786 SLOT(slotSaveResult(KIO::Job*)));
00787 setEmitsCompletedItself( true );
00788 return OK;
00789 }
00790
00791 void KMSaveMsgCommand::slotSaveDataReq()
00792 {
00793 int remainingBytes = mData.size() - mOffset;
00794 if ( remainingBytes > 0 ) {
00795
00796 if ( remainingBytes > MAX_CHUNK_SIZE )
00797 remainingBytes = MAX_CHUNK_SIZE;
00798
00799 QByteArray data;
00800 data.duplicate( mData.data() + mOffset, remainingBytes );
00801 mJob->sendAsyncData( data );
00802 mOffset += remainingBytes;
00803 return;
00804 }
00805
00806 if ( mMsgListIndex < mMsgList.size() ) {
00807 KMMessage *msg = 0;
00808 int idx = -1;
00809 KMFolder * p = 0;
00810 kmkernel->msgDict()->getLocation( mMsgList[mMsgListIndex], &p, &idx );
00811 assert( p );
00812 assert( idx >= 0 );
00813 msg = p->getMsg(idx);
00814
00815 if ( msg ) {
00816 if (msg->transferInProgress()) {
00817 QByteArray data = QByteArray();
00818 mJob->sendAsyncData( data );
00819 }
00820 msg->setTransferInProgress( true );
00821 if (msg->isComplete() ) {
00822 slotMessageRetrievedForSaving(msg);
00823 } else {
00824
00825 if (msg->parent() && !msg->isComplete() ) {
00826 FolderJob *job = msg->parent()->createJob(msg);
00827 job->setCancellable( false );
00828 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
00829 this, SLOT(slotMessageRetrievedForSaving(KMMessage*)));
00830 job->start();
00831 }
00832 }
00833 } else {
00834 mJob->slotError( KIO::ERR_ABORTED,
00835 i18n("The message was removed while saving it. "
00836 "It has not been saved.") );
00837 }
00838 } else {
00839 if ( mStandAloneMessage ) {
00840
00841 slotMessageRetrievedForSaving( mStandAloneMessage );
00842 mStandAloneMessage = 0;
00843 } else {
00844
00845 QByteArray data = QByteArray();
00846 mJob->sendAsyncData( data );
00847 }
00848 }
00849 }
00850
00851 void KMSaveMsgCommand::slotMessageRetrievedForSaving(KMMessage *msg)
00852 {
00853 QCString str( msg->mboxMessageSeparator() );
00854 str += KMFolderMbox::escapeFrom( msg->asString() );
00855 str += "\n";
00856 msg->setTransferInProgress(false);
00857
00858 mData = str;
00859 mData.resize(mData.size() - 1);
00860 mOffset = 0;
00861 QByteArray data;
00862 int size;
00863
00864 if( mData.size() > (unsigned int) MAX_CHUNK_SIZE )
00865 size = MAX_CHUNK_SIZE;
00866 else
00867 size = mData.size();
00868
00869 data.duplicate( mData, size );
00870 mJob->sendAsyncData( data );
00871 mOffset += size;
00872 ++mMsgListIndex;
00873
00874 if (msg->parent()) {
00875 int idx = -1;
00876 KMFolder * p = 0;
00877 kmkernel->msgDict()->getLocation( msg, &p, &idx );
00878 assert( p == msg->parent() ); assert( idx >= 0 );
00879 p->unGetMsg( idx );
00880 p->close();
00881 }
00882 }
00883
00884 void KMSaveMsgCommand::slotSaveResult(KIO::Job *job)
00885 {
00886 if (job->error())
00887 {
00888 if (job->error() == KIO::ERR_FILE_ALREADY_EXIST)
00889 {
00890 if (KMessageBox::warningContinueCancel(0,
00891 i18n("File %1 exists.\nDo you want to replace it?")
00892 .arg(mUrl.prettyURL()), i18n("Save to File"), i18n("&Replace"))
00893 == KMessageBox::Continue) {
00894 mOffset = 0;
00895
00896 mJob = KIO::put( mUrl, S_IRUSR|S_IWUSR, true, false );
00897 mJob->slotTotalSize( mTotalSize );
00898 mJob->setAsyncDataEnabled( true );
00899 mJob->setReportDataSent( true );
00900 connect(mJob, SIGNAL(dataReq(KIO::Job*, QByteArray &)),
00901 SLOT(slotSaveDataReq()));
00902 connect(mJob, SIGNAL(result(KIO::Job*)),
00903 SLOT(slotSaveResult(KIO::Job*)));
00904 }
00905 }
00906 else
00907 {
00908 job->showErrorDialog();
00909 setResult( Failed );
00910 emit completed( this );
00911 deleteLater();
00912 }
00913 } else {
00914 setResult( OK );
00915 emit completed( this );
00916 deleteLater();
00917 }
00918 }
00919
00920
00921
00922 KMOpenMsgCommand::KMOpenMsgCommand( QWidget *parent, const KURL & url,
00923 const QString & encoding )
00924 : KMCommand( parent ),
00925 mUrl( url ),
00926 mEncoding( encoding )
00927 {
00928 setDeletesItself( true );
00929 }
00930
00931 KMCommand::Result KMOpenMsgCommand::execute()
00932 {
00933 if ( mUrl.isEmpty() ) {
00934 mUrl = KFileDialog::getOpenURL( ":OpenMessage", "message/rfc822",
00935 parentWidget(), i18n("Open Message") );
00936 }
00937 if ( mUrl.isEmpty() ) {
00938 setDeletesItself( false );
00939 return Canceled;
00940 }
00941 mJob = KIO::get( mUrl, false, false );
00942 mJob->setReportDataSent( true );
00943 connect( mJob, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
00944 this, SLOT( slotDataArrived( KIO::Job*, const QByteArray & ) ) );
00945 connect( mJob, SIGNAL( result( KIO::Job * ) ),
00946 SLOT( slotResult( KIO::Job * ) ) );
00947 setEmitsCompletedItself( true );
00948 return OK;
00949 }
00950
00951 void KMOpenMsgCommand::slotDataArrived( KIO::Job *, const QByteArray & data )
00952 {
00953 if ( data.isEmpty() )
00954 return;
00955
00956 mMsgString.append( data.data(), data.size() );
00957 }
00958
00959 void KMOpenMsgCommand::slotResult( KIO::Job *job )
00960 {
00961 if ( job->error() ) {
00962
00963 job->showErrorDialog();
00964 setResult( Failed );
00965 emit completed( this );
00966 }
00967 else {
00968 int startOfMessage = 0;
00969 if ( mMsgString.compare( 0, 5, "From ", 5 ) == 0 ) {
00970 startOfMessage = mMsgString.find( '\n' );
00971 if ( startOfMessage == -1 ) {
00972 KMessageBox::sorry( parentWidget(),
00973 i18n( "The file doesn't contain a message." ) );
00974 setResult( Failed );
00975 emit completed( this );
00976
00977
00978
00979 SecondaryWindow *win = new SecondaryWindow();
00980 win->close();
00981 win->deleteLater();
00982 deleteLater();
00983 return;
00984 }
00985 startOfMessage += 1;
00986 }
00987
00988 bool multipleMessages = true;
00989 int endOfMessage = mMsgString.find( "\nFrom " );
00990 if ( endOfMessage == -1 ) {
00991 endOfMessage = mMsgString.length();
00992 multipleMessages = false;
00993 }
00994 DwMessage *dwMsg = new DwMessage;
00995 dwMsg->FromString( mMsgString.substr( startOfMessage,
00996 endOfMessage - startOfMessage ) );
00997 dwMsg->Parse();
00998
00999 if ( dwMsg->Headers().NumFields() == 0 ) {
01000 KMessageBox::sorry( parentWidget(),
01001 i18n( "The file doesn't contain a message." ) );
01002 delete dwMsg; dwMsg = 0;
01003 setResult( Failed );
01004 emit completed( this );
01005
01006 SecondaryWindow *win = new SecondaryWindow();
01007 win->close();
01008 win->deleteLater();
01009 deleteLater();
01010 return;
01011 }
01012 KMMessage *msg = new KMMessage( dwMsg );
01013 msg->setComplete( true );
01014 msg->setReadyToShow( true );
01015 KMReaderMainWin *win = new KMReaderMainWin();
01016 win->showMsg( mEncoding, msg );
01017 win->show();
01018 if ( multipleMessages )
01019 KMessageBox::information( win,
01020 i18n( "The file contains multiple messages. "
01021 "Only the first message is shown." ) );
01022 setResult( OK );
01023 emit completed( this );
01024 }
01025 deleteLater();
01026 }
01027
01028
01029
01030
01031
01032 KMReplyToCommand::KMReplyToCommand( QWidget *parent, KMMessage *msg,
01033 const QString &selection )
01034 : KMCommand( parent, msg ), mSelection( selection )
01035 {
01036 }
01037
01038 KMCommand::Result KMReplyToCommand::execute()
01039 {
01040 KCursorSaver busy(KBusyPtr::busy());
01041 KMMessage *msg = retrievedMessage();
01042 KMMessage *reply = msg->createReply( KMail::ReplySmart, mSelection );
01043 KMComposeWin *win = new KMComposeWin( reply );
01044 win->setCharset( msg->codec()->mimeName(), TRUE );
01045 win->setReplyFocus();
01046 win->show();
01047
01048 return OK;
01049 }
01050
01051
01052 KMNoQuoteReplyToCommand::KMNoQuoteReplyToCommand( QWidget *parent,
01053 KMMessage *msg )
01054 : KMCommand( parent, msg )
01055 {
01056 }
01057
01058 KMCommand::Result KMNoQuoteReplyToCommand::execute()
01059 {
01060 KCursorSaver busy(KBusyPtr::busy());
01061 KMMessage *msg = retrievedMessage();
01062 KMMessage *reply = msg->createReply( KMail::ReplySmart, "", TRUE);
01063 KMComposeWin *win = new KMComposeWin( reply );
01064 win->setCharset(msg->codec()->mimeName(), TRUE);
01065 win->setReplyFocus(false);
01066 win->show();
01067
01068 return OK;
01069 }
01070
01071
01072 KMReplyListCommand::KMReplyListCommand( QWidget *parent,
01073 KMMessage *msg, const QString &selection )
01074 : KMCommand( parent, msg ), mSelection( selection )
01075 {
01076 }
01077
01078 KMCommand::Result KMReplyListCommand::execute()
01079 {
01080 KCursorSaver busy(KBusyPtr::busy());
01081 KMMessage *msg = retrievedMessage();
01082 KMMessage *reply = msg->createReply( KMail::ReplyList, mSelection);
01083 KMComposeWin *win = new KMComposeWin( reply );
01084 win->setCharset(msg->codec()->mimeName(), TRUE);
01085 win->setReplyFocus(false);
01086 win->show();
01087
01088 return OK;
01089 }
01090
01091
01092 KMReplyToAllCommand::KMReplyToAllCommand( QWidget *parent,
01093 KMMessage *msg, const QString &selection )
01094 :KMCommand( parent, msg ), mSelection( selection )
01095 {
01096 }
01097
01098 KMCommand::Result KMReplyToAllCommand::execute()
01099 {
01100 KCursorSaver busy(KBusyPtr::busy());
01101 KMMessage *msg = retrievedMessage();
01102 KMMessage *reply = msg->createReply( KMail::ReplyAll, mSelection );
01103 KMComposeWin *win = new KMComposeWin( reply );
01104 win->setCharset( msg->codec()->mimeName(), TRUE );
01105 win->setReplyFocus();
01106 win->show();
01107
01108 return OK;
01109 }
01110
01111
01112 KMReplyAuthorCommand::KMReplyAuthorCommand( QWidget *parent, KMMessage *msg,
01113 const QString &selection )
01114 : KMCommand( parent, msg ), mSelection( selection )
01115 {
01116 }
01117
01118 KMCommand::Result KMReplyAuthorCommand::execute()
01119 {
01120 KCursorSaver busy(KBusyPtr::busy());
01121 KMMessage *msg = retrievedMessage();
01122 KMMessage *reply = msg->createReply( KMail::ReplyAuthor, mSelection );
01123 KMComposeWin *win = new KMComposeWin( reply );
01124 win->setCharset( msg->codec()->mimeName(), TRUE );
01125 win->setReplyFocus();
01126 win->show();
01127
01128 return OK;
01129 }
01130
01131
01132 KMForwardCommand::KMForwardCommand( QWidget *parent,
01133 const QPtrList<KMMsgBase> &msgList, uint identity )
01134 : KMCommand( parent, msgList ),
01135 mIdentity( identity )
01136 {
01137 }
01138
01139 KMForwardCommand::KMForwardCommand( QWidget *parent, KMMessage *msg,
01140 uint identity )
01141 : KMCommand( parent, msg ),
01142 mIdentity( identity )
01143 {
01144 }
01145
01146 KMCommand::Result KMForwardCommand::execute()
01147 {
01148 KMComposeWin *win;
01149 QPtrList<KMMessage> msgList = retrievedMsgs();
01150
01151 if (msgList.count() >= 2) {
01152
01153
01154 if (KMessageBox::questionYesNo( parentWidget(),
01155 i18n("Forward selected messages as "
01156 "a MIME digest?") )
01157 == KMessageBox::Yes) {
01158 uint id = 0;
01159 KMMessage *fwdMsg = new KMMessage;
01160 KMMessagePart *msgPart = new KMMessagePart;
01161 QString msgPartText;
01162 int msgCnt = 0;
01163
01164
01165
01166 fwdMsg->initHeader(id);
01167 fwdMsg->setAutomaticFields(true);
01168 fwdMsg->mMsg->Headers().ContentType().CreateBoundary(1);
01169 QCString boundary( fwdMsg->mMsg->Headers().ContentType().Boundary().c_str() );
01170 msgPartText = i18n("\nThis is a MIME digest forward. The content of the"
01171 " message is contained in the attachment(s).\n\n\n");
01172
01173 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01174
01175 if (id == 0)
01176 id = msg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt();
01177
01178 msgPartText += "--";
01179 msgPartText += QString::fromLatin1( boundary );
01180 msgPartText += "\nContent-Type: MESSAGE/RFC822";
01181 msgPartText += QString("; CHARSET=%1").arg(msg->charset());
01182 msgPartText += "\n";
01183 DwHeaders dwh;
01184 dwh.MessageId().CreateDefault();
01185 msgPartText += QString("Content-ID: %1\n").arg(dwh.MessageId().AsString().c_str());
01186 msgPartText += QString("Content-Description: %1").arg(msg->subject());
01187 if (!msg->subject().contains("(fwd)"))
01188 msgPartText += " (fwd)";
01189 msgPartText += "\n\n";
01190
01191 msg->removePrivateHeaderFields();
01192 msg->removeHeaderField("BCC");
01193
01194 msgPartText += msg->headerAsString();
01195 msgPartText += "\n";
01196 msgPartText += msg->body();
01197 msgPartText += "\n";
01198 msgCnt++;
01199 fwdMsg->link(msg, KMMsgStatusForwarded);
01200 }
01201 if ( id == 0 )
01202 id = mIdentity;
01203 fwdMsg->initHeader(id);
01204 msgPartText += "--";
01205 msgPartText += QString::fromLatin1( boundary );
01206 msgPartText += "--\n";
01207 QCString tmp;
01208 msgPart->setTypeStr("MULTIPART");
01209 tmp.sprintf( "Digest; boundary=\"%s\"", boundary.data() );
01210 msgPart->setSubtypeStr( tmp );
01211 msgPart->setName("unnamed");
01212 msgPart->setCte(DwMime::kCte7bit);
01213 msgPart->setContentDescription(QString("Digest of %1 messages.").arg(msgCnt));
01214
01215 msgPart->setBodyEncoded(QCString(msgPartText.ascii()));
01216 KCursorSaver busy(KBusyPtr::busy());
01217 win = new KMComposeWin(fwdMsg, id);
01218 win->addAttach(msgPart);
01219 win->show();
01220 return OK;
01221 } else {
01222 uint id = 0;
01223 QCString msgText = "";
01224 QPtrList<KMMessage> linklist;
01225 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01226
01227 if (id == 0)
01228 id = msg->headerField("X-KMail-Identity").stripWhiteSpace().toUInt();
01229
01230 msgText += msg->createForwardBody();
01231 linklist.append(msg);
01232 }
01233 if ( id == 0 )
01234 id = mIdentity;
01235 KMMessage *fwdMsg = new KMMessage;
01236 fwdMsg->initHeader(id);
01237 fwdMsg->setAutomaticFields(true);
01238 fwdMsg->setCharset("utf-8");
01239 fwdMsg->setBody(msgText);
01240
01241 for (KMMessage *msg = linklist.first(); msg; msg = linklist.next())
01242 fwdMsg->link(msg, KMMsgStatusForwarded);
01243
01244 KCursorSaver busy(KBusyPtr::busy());
01245 win = new KMComposeWin(fwdMsg, id);
01246 win->setCharset("");
01247 win->show();
01248 return OK;
01249 }
01250 }
01251
01252
01253 KMMessage *msg = msgList.getFirst();
01254 if ( !msg || !msg->codec() )
01255 return Failed;
01256
01257 KCursorSaver busy(KBusyPtr::busy());
01258 KMMessage *fwdMsg = msg->createForward();
01259
01260 win = new KMComposeWin( fwdMsg );
01261 win->setCharset( fwdMsg->codec()->mimeName(), true );
01262 win->setBody( QString::fromUtf8( msg->createForwardBody() ) );
01263 win->show();
01264
01265 return OK;
01266 }
01267
01268
01269 KMForwardAttachedCommand::KMForwardAttachedCommand( QWidget *parent,
01270 const QPtrList<KMMsgBase> &msgList, uint identity, KMComposeWin *win )
01271 : KMCommand( parent, msgList ), mIdentity( identity ),
01272 mWin( QGuardedPtr< KMComposeWin >( win ))
01273 {
01274 }
01275
01276 KMForwardAttachedCommand::KMForwardAttachedCommand( QWidget *parent,
01277 KMMessage * msg, uint identity, KMComposeWin *win )
01278 : KMCommand( parent, msg ), mIdentity( identity ),
01279 mWin( QGuardedPtr< KMComposeWin >( win ))
01280 {
01281 }
01282
01283 KMCommand::Result KMForwardAttachedCommand::execute()
01284 {
01285 QPtrList<KMMessage> msgList = retrievedMsgs();
01286 KMMessage *fwdMsg = new KMMessage;
01287
01288 if (msgList.count() >= 2) {
01289
01290
01291 fwdMsg->initHeader(mIdentity);
01292 }
01293 else if (msgList.count() == 1) {
01294 KMMessage *msg = msgList.getFirst();
01295 fwdMsg->initFromMessage(msg);
01296 fwdMsg->setSubject( msg->forwardSubject() );
01297 }
01298
01299 fwdMsg->setAutomaticFields(true);
01300
01301 KCursorSaver busy(KBusyPtr::busy());
01302 if (!mWin)
01303 mWin = new KMComposeWin(fwdMsg, mIdentity);
01304
01305
01306 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01307
01308 msg->removePrivateHeaderFields();
01309 msg->removeHeaderField("BCC");
01310
01311 KMMessagePart *msgPart = new KMMessagePart;
01312 msgPart->setTypeStr("message");
01313 msgPart->setSubtypeStr("rfc822");
01314 msgPart->setCharset(msg->charset());
01315 msgPart->setName("forwarded message");
01316 msgPart->setContentDescription(msg->from()+": "+msg->subject());
01317 msgPart->setContentDisposition( "inline" );
01318
01319 msgPart->setMessageBody( msg->asString() );
01320 msgPart->setCharset("");
01321
01322 fwdMsg->link(msg, KMMsgStatusForwarded);
01323 mWin->addAttach(msgPart);
01324 }
01325
01326 mWin->show();
01327
01328 return OK;
01329 }
01330
01331
01332 KMRedirectCommand::KMRedirectCommand( QWidget *parent,
01333 KMMessage *msg )
01334 : KMCommand( parent, msg )
01335 {
01336 }
01337
01338 KMCommand::Result KMRedirectCommand::execute()
01339 {
01340
01341 KMComposeWin *win;
01342 KMMessage *msg = retrievedMessage();
01343 if ( !msg || !msg->codec() )
01344 return Failed;
01345
01346 KCursorSaver busy(KBusyPtr::busy());
01347 win = new KMComposeWin();
01348 win->setMsg(msg->createRedirect(), FALSE);
01349 win->setCharset(msg->codec()->mimeName());
01350 win->show();
01351
01352 return OK;
01353 }
01354
01355
01356 KMBounceCommand::KMBounceCommand( QWidget *parent,
01357 KMMessage *msg )
01358 : KMCommand( parent, msg )
01359 {
01360 }
01361
01362 KMCommand::Result KMBounceCommand::execute()
01363 {
01364 KMMessage *msg = retrievedMessage();
01365 KMMessage *newMsg = msg->createBounce( TRUE );
01366 if (newMsg)
01367 kmkernel->msgSender()->send(newMsg, kmkernel->msgSender()->sendImmediate());
01368
01369 return OK;
01370 }
01371
01372
01373 KMPrintCommand::KMPrintCommand( QWidget *parent,
01374 KMMessage *msg, bool htmlOverride, const QString & encoding,
01375 const HeaderStyle * style,
01376 const HeaderStrategy * strategy )
01377 : KMCommand( parent, msg ), mHtmlOverride( htmlOverride ), mEncoding( encoding ),
01378 mStyle( style ), mStrategy( strategy )
01379 {
01380 }
01381
01382 KMCommand::Result KMPrintCommand::execute()
01383 {
01384 KMReaderWin printWin( 0, 0, 0 );
01385 printWin.setPrinting(TRUE);
01386 printWin.readConfig();
01387 if( mStyle != 0 && mStrategy != 0 )
01388 printWin.setHeaderStyleAndStrategy( mStyle, mStrategy );
01389 printWin.setHtmlOverride( mHtmlOverride );
01390 printWin.setOverrideEncoding( mEncoding );
01391 printWin.setMsg(retrievedMessage(), TRUE);
01392 printWin.printMsg();
01393
01394 return OK;
01395 }
01396
01397
01398 KMSetStatusCommand::KMSetStatusCommand( KMMsgStatus status,
01399 const QValueList<Q_UINT32> &serNums, bool toggle )
01400 : mStatus( status ), mSerNums( serNums ), mToggle( toggle )
01401 {
01402 }
01403
01404 KMCommand::Result KMSetStatusCommand::execute()
01405 {
01406 QValueListIterator<Q_UINT32> it;
01407 int idx = -1;
01408 KMFolder *folder = 0;
01409 bool parentStatus = false;
01410
01411
01412
01413 if (mToggle) {
01414 KMMsgBase *msg;
01415 kmkernel->msgDict()->getLocation( *mSerNums.begin(), &folder, &idx );
01416 if (folder) {
01417 msg = folder->getMsgBase(idx);
01418 if (msg && (msg->status()&mStatus))
01419 parentStatus = true;
01420 else
01421 parentStatus = false;
01422 }
01423 }
01424 QMap< KMFolder*, QValueList<int> > folderMap;
01425 for ( it = mSerNums.begin(); it != mSerNums.end(); ++it ) {
01426 kmkernel->msgDict()->getLocation( *it, &folder, &idx );
01427 if (folder) {
01428 if (mToggle) {
01429 KMMsgBase *msg = folder->getMsgBase(idx);
01430
01431 if (msg) {
01432 bool myStatus;
01433 if (msg->status()&mStatus)
01434 myStatus = true;
01435 else
01436 myStatus = false;
01437 if (myStatus != parentStatus)
01438 continue;
01439 }
01440 }
01441
01442
01443 folderMap[folder].append(idx);
01444 }
01445 }
01446 QMapIterator< KMFolder*, QValueList<int> > it2 = folderMap.begin();
01447 while ( it2 != folderMap.end() ) {
01448 KMFolder *f = it2.key();
01449 f->setStatus( (*it2), mStatus, mToggle );
01450 ++it2;
01451 }
01452
01453
01454 return OK;
01455 }
01456
01457
01458 KMFilterCommand::KMFilterCommand( const QCString &field, const QString &value )
01459 : mField( field ), mValue( value )
01460 {
01461 }
01462
01463 KMCommand::Result KMFilterCommand::execute()
01464 {
01465 kmkernel->filterMgr()->createFilter( mField, mValue );
01466
01467 return OK;
01468 }
01469
01470
01471 KMFilterActionCommand::KMFilterActionCommand( QWidget *parent,
01472 const QPtrList<KMMsgBase> &msgList,
01473 KMFilter *filter )
01474 : KMCommand( parent, msgList ), mFilter( filter )
01475 {
01476 }
01477
01478 KMCommand::Result KMFilterActionCommand::execute()
01479 {
01480 QPtrList<KMMessage> msgList = retrievedMsgs();
01481
01482 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next())
01483 if( msg->parent() )
01484 kmkernel->filterMgr()->tempOpenFolder(msg->parent());
01485
01486 for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01487 msg->setTransferInProgress(false);
01488
01489 int filterResult = kmkernel->filterMgr()->process(msg, mFilter);
01490 if (filterResult == 2) {
01491
01492 perror("Critical error");
01493 kmkernel->emergencyExit( i18n("Not enough free disk space?" ));
01494 }
01495 msg->setTransferInProgress(true);
01496 }
01497
01498 return OK;
01499 }
01500
01501
01502 KMMetaFilterActionCommand::KMMetaFilterActionCommand( KMFilter *filter,
01503 KMHeaders *headers,
01504 KMMainWidget *main )
01505 : QObject( main ),
01506 mFilter( filter ), mHeaders( headers ), mMainWidget( main )
01507 {
01508 }
01509
01510 void KMMetaFilterActionCommand::start()
01511 {
01512 #if 0 // use action scheduler
01513 KMFilterMgr::FilterSet set = KMFilterMgr::All;
01514 QPtrList<KMFilter> filters;
01515 filters.append( mFilter );
01516 ActionScheduler *scheduler = new ActionScheduler( set, filters, mHeaders );
01517 scheduler->setAlwaysMatch( true );
01518 scheduler->setAutoDestruct( true );
01519
01520 int contentX, contentY;
01521 KMHeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY );
01522 QPtrList<KMMsgBase> msgList = *mHeaders->selectedMsgs(true);
01523 mHeaders->finalizeMove( nextItem, contentX, contentY );
01524
01525
01526 for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
01527 scheduler->execFilters( msg );
01528 #else
01529 KMCommand *filterCommand = new KMFilterActionCommand( mMainWidget,
01530 *mHeaders->selectedMsgs(), mFilter);
01531 filterCommand->start();
01532 int contentX, contentY;
01533 KMHeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
01534 mHeaders->finalizeMove( item, contentX, contentY );
01535 #endif
01536 }
01537
01538
01539 KMMailingListFilterCommand::KMMailingListFilterCommand( QWidget *parent,
01540 KMMessage *msg )
01541 : KMCommand( parent, msg )
01542 {
01543 }
01544
01545 KMCommand::Result KMMailingListFilterCommand::execute()
01546 {
01547 QCString name;
01548 QString value;
01549 KMMessage *msg = retrievedMessage();
01550 if (!msg)
01551 return Failed;
01552
01553 if ( !MailingList::name( msg, name, value ).isEmpty() ) {
01554 kmkernel->filterMgr()->createFilter( name, value );
01555 return OK;
01556 }
01557 else
01558 return Failed;
01559 }
01560
01561
01562 void KMMenuCommand::folderToPopupMenu(bool move,
01563 QObject *receiver, KMMenuToFolder *aMenuToFolder, QPopupMenu *menu )
01564 {
01565 while ( menu->count() )
01566 {
01567 QPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
01568 if (popup)
01569 delete popup;
01570 else
01571 menu->removeItemAt( 0 );
01572 }
01573
01574 if (!kmkernel->imapFolderMgr()->dir().first() &&
01575 !kmkernel->dimapFolderMgr()->dir().first())
01576 {
01577 makeFolderMenu( &kmkernel->folderMgr()->dir(), move,
01578 receiver, aMenuToFolder, menu );
01579 } else {
01580
01581 QPopupMenu* subMenu = new QPopupMenu(menu);
01582 makeFolderMenu( &kmkernel->folderMgr()->dir(),
01583 move, receiver, aMenuToFolder, subMenu );
01584 menu->insertItem( i18n( "Local Folders" ), subMenu );
01585 KMFolderDir* fdir = &kmkernel->imapFolderMgr()->dir();
01586 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01587 if (node->isDir())
01588 continue;
01589 subMenu = new QPopupMenu(menu);
01590 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01591 menu->insertItem( node->label(), subMenu );
01592 }
01593 fdir = &kmkernel->dimapFolderMgr()->dir();
01594 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01595 if (node->isDir())
01596 continue;
01597 subMenu = new QPopupMenu(menu);
01598 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01599 menu->insertItem( node->label(), subMenu );
01600 }
01601 }
01602 }
01603
01604 void KMMenuCommand::makeFolderMenu(KMFolderNode* node, bool move,
01605 QObject *receiver, KMMenuToFolder *aMenuToFolder, QPopupMenu *menu )
01606 {
01607
01608 if (move)
01609 {
01610 disconnect(menu, SIGNAL(activated(int)), receiver,
01611 SLOT(moveSelectedToFolder(int)));
01612 connect(menu, SIGNAL(activated(int)), receiver,
01613 SLOT(moveSelectedToFolder(int)));
01614 } else {
01615 disconnect(menu, SIGNAL(activated(int)), receiver,
01616 SLOT(copySelectedToFolder(int)));
01617 connect(menu, SIGNAL(activated(int)), receiver,
01618 SLOT(copySelectedToFolder(int)));
01619 }
01620
01621 KMFolder *folder = 0;
01622 KMFolderDir *folderDir = 0;
01623 if (node->isDir()) {
01624 folderDir = static_cast<KMFolderDir*>(node);
01625 } else {
01626 folder = static_cast<KMFolder*>(node);
01627 folderDir = folder->child();
01628 }
01629
01630 if (folder && !folder->noContent())
01631 {
01632 int menuId;
01633 if (move)
01634 menuId = menu->insertItem(i18n("Move to This Folder"));
01635 else
01636 menuId = menu->insertItem(i18n("Copy to This Folder"));
01637 aMenuToFolder->insert( menuId, folder );
01638 menu->setItemEnabled( menuId, !folder->isReadOnly() );
01639 menu->insertSeparator();
01640 }
01641
01642 if (!folderDir)
01643 return;
01644
01645 for (KMFolderNode *it = folderDir->first(); it; it = folderDir->next() ) {
01646 if (it->isDir())
01647 continue;
01648 KMFolder *child = static_cast<KMFolder*>(it);
01649 QString label = child->label();
01650 label.replace("&","&&");
01651 if (child->child() && child->child()->first()) {
01652
01653 QPopupMenu *subMenu = new QPopupMenu(menu, "subMenu");
01654 makeFolderMenu( child, move, receiver,
01655 aMenuToFolder, subMenu );
01656 menu->insertItem( label, subMenu );
01657 } else {
01658
01659 int menuId = menu->insertItem( label );
01660 aMenuToFolder->insert( menuId, child );
01661 menu->setItemEnabled( menuId, !child->isReadOnly() );
01662 }
01663 }
01664 return;
01665 }
01666
01667
01668 KMCopyCommand::KMCopyCommand( KMFolder* destFolder,
01669 const QPtrList<KMMsgBase> &msgList )
01670 :mDestFolder( destFolder ), mMsgList( msgList )
01671 {
01672 }
01673
01674 KMCopyCommand::KMCopyCommand( KMFolder* destFolder, KMMessage * msg )
01675 :mDestFolder( destFolder )
01676 {
01677 mMsgList.append( &msg->toMsgBase() );
01678 }
01679
01680 KMCommand::Result KMCopyCommand::execute()
01681 {
01682 KMMsgBase *msgBase;
01683 KMMessage *msg, *newMsg;
01684 int idx = -1;
01685 bool isMessage;
01686 QPtrList<KMMessage> list;
01687
01688 if (mDestFolder && mDestFolder->open() != 0)
01689 return Failed;
01690
01691 KCursorSaver busy(KBusyPtr::busy());
01692
01693 for (msgBase = mMsgList.first(); msgBase; msgBase = mMsgList.next() )
01694 {
01695 KMFolder *srcFolder = msgBase->parent();
01696 if (isMessage = msgBase->isMessage())
01697 {
01698 msg = static_cast<KMMessage*>(msgBase);
01699 } else {
01700 idx = srcFolder->find(msgBase);
01701 assert(idx != -1);
01702 msg = srcFolder->getMsg(idx);
01703 }
01704
01705 if (srcFolder &&
01706 (srcFolder->folderType()== KMFolderTypeImap) &&
01707 (mDestFolder->folderType() == KMFolderTypeImap) &&
01708 (static_cast<KMFolderImap*>(srcFolder->storage())->account() ==
01709 static_cast<KMFolderImap*>(mDestFolder->storage())->account()))
01710 {
01711 list.append(msg);
01712 } else {
01713 newMsg = new KMMessage;
01714 newMsg->setComplete(msg->isComplete());
01715
01716 if (!newMsg->isComplete())
01717 newMsg->setReadyToShow(false);
01718 newMsg->fromString(msg->asString());
01719 newMsg->setStatus(msg->status());
01720
01721 if (srcFolder && !newMsg->isComplete())
01722 {
01723 newMsg->setParent(msg->parent());
01724 FolderJob *job = srcFolder->createJob(newMsg);
01725 job->setCancellable( false );
01726 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
01727 mDestFolder, SLOT(reallyAddCopyOfMsg(KMMessage*)));
01728
01729 newMsg->setTransferInProgress(true);
01730 job->start();
01731 } else {
01732 int rc, index;
01733 mDestFolder->open();
01734 rc = mDestFolder->addMsg(newMsg, &index);
01735 if (rc == 0 && index != -1)
01736 mDestFolder->unGetMsg( mDestFolder->count() - 1 );
01737 mDestFolder->close();
01738 }
01739 }
01740
01741 if (!isMessage && list.isEmpty())
01742 {
01743 assert(idx != -1);
01744 srcFolder->unGetMsg( idx );
01745 }
01746
01747 }
01748 mDestFolder->close();
01749
01750
01751
01752
01753 if (!list.isEmpty())
01754 {
01755
01756 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
01757 imapDestFolder->copyMsg(list);
01758 imapDestFolder->getFolder();
01759 }
01760
01761 return OK;
01762 }
01763
01764
01765 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
01766 const QPtrList<KMMsgBase> &msgList)
01767 :mDestFolder( destFolder ), mMsgList( msgList ), mProgressItem( 0 )
01768 {
01769 setDeletesItself( true );
01770 }
01771
01772 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
01773 KMMessage *msg )
01774 :mDestFolder( destFolder ), mProgressItem( 0 )
01775 {
01776 setDeletesItself( true );
01777 mMsgList.append( &msg->toMsgBase() );
01778 }
01779
01780 KMMoveCommand::KMMoveCommand( KMFolder* destFolder,
01781 KMMsgBase *msgBase )
01782 :mDestFolder( destFolder ), mProgressItem( 0 )
01783 {
01784 setDeletesItself( true );
01785 mMsgList.append( msgBase );
01786 }
01787
01788 KMMoveCommand::KMMoveCommand( Q_UINT32 )
01789 :mProgressItem( 0 )
01790 {
01791 setDeletesItself( true );
01792 }
01793
01794 KMCommand::Result KMMoveCommand::execute()
01795 {
01796 setEmitsCompletedItself( true );
01797 typedef QMap< KMFolder*, QPtrList<KMMessage>* > FolderToMessageListMap;
01798 FolderToMessageListMap folderDeleteList;
01799
01800 if (mDestFolder && mDestFolder->open() != 0) {
01801 completeMove( Failed );
01802 return Failed;
01803 }
01804 KCursorSaver busy(KBusyPtr::busy());
01805
01806
01807 Q_ASSERT( !mProgressItem );
01808 mProgressItem =
01809 ProgressManager::createProgressItem (
01810 "move"+ProgressManager::getUniqueID(),
01811 mDestFolder ? i18n( "Moving messages" ) : i18n( "Deleting messages" ) );
01812 connect( mProgressItem, SIGNAL( progressItemCanceled( ProgressItem* ) ),
01813 this, SLOT( slotMoveCanceled() ) );
01814
01815 KMMessage *msg;
01816 KMMsgBase *msgBase;
01817 int rc = 0;
01818 int index;
01819 QPtrList<KMMessage> list;
01820 int undoId = -1;
01821
01822 if (mDestFolder) {
01823 connect (mDestFolder, SIGNAL(msgAdded(KMFolder*, Q_UINT32)),
01824 this, SLOT(slotMsgAddedToDestFolder(KMFolder*, Q_UINT32)));
01825
01826 }
01827 for ( msgBase=mMsgList.first(); msgBase; msgBase=mMsgList.next() ) {
01828 mLostBoys.append( msgBase->getMsgSerNum() );
01829 }
01830 mProgressItem->setTotalItems( mMsgList.count() );
01831
01832 for (msgBase=mMsgList.first(); msgBase && !rc; msgBase=mMsgList.next()) {
01833 KMFolder *srcFolder = msgBase->parent();
01834 if (srcFolder == mDestFolder)
01835 continue;
01836 bool undo = msgBase->enableUndo();
01837 int idx = srcFolder->find(msgBase);
01838 assert(idx != -1);
01839 if ( msgBase->isMessage() )
01840 msg = static_cast<KMMessage*>(msgBase);
01841 else
01842 msg = srcFolder->getMsg(idx);
01843
01844 if ( msg->transferInProgress() &&
01845 srcFolder->folderType() == KMFolderTypeImap )
01846 {
01847
01848 msg->setTransferInProgress( false, true );
01849 static_cast<KMFolderImap*>(srcFolder->storage())->ignoreJobsForMessage( msg );
01850 }
01851
01852 if (mDestFolder) {
01853 if (mDestFolder->folderType() == KMFolderTypeImap) {
01854
01855
01856
01857 KMFolderImap *imapFolder = static_cast<KMFolderImap*> ( mDestFolder->storage() );
01858 disconnect (imapFolder, SIGNAL(folderComplete( KMFolderImap*, bool )),
01859 this, SLOT(slotImapFolderCompleted( KMFolderImap*, bool )));
01860
01861 connect (imapFolder, SIGNAL(folderComplete( KMFolderImap*, bool )),
01862 this, SLOT(slotImapFolderCompleted( KMFolderImap*, bool )));
01863 list.append(msg);
01864 } else {
01865
01866 mDestFolder->open();
01867 rc = mDestFolder->moveMsg(msg, &index);
01868 if (rc == 0 && index != -1) {
01869 KMMsgBase *mb = mDestFolder->unGetMsg( mDestFolder->count() - 1 );
01870 if (undo && mb)
01871 {
01872 if ( undoId == -1 )
01873 undoId = kmkernel->undoStack()->newUndoAction( srcFolder, mDestFolder );
01874 kmkernel->undoStack()->addMsgToAction( undoId, mb->getMsgSerNum() );
01875 }
01876 mDestFolder->close();
01877 } else if (rc != 0) {
01878
01879
01880 completeMove( Failed );
01881 mDestFolder->close();
01882 return Failed;
01883 }
01884 }
01885 } else {
01886
01887
01888 if (srcFolder->folderType() == KMFolderTypeImap) {
01889 if (!folderDeleteList[srcFolder])
01890 folderDeleteList[srcFolder] = new QPtrList<KMMessage>;
01891 folderDeleteList[srcFolder]->append( msg );
01892 } else {
01893 srcFolder->removeMsg(idx);
01894 delete msg;
01895 }
01896 }
01897 }
01898 if (!list.isEmpty() && mDestFolder) {
01899 mDestFolder->moveMsg(list, &index);
01900 } else {
01901 FolderToMessageListMap::Iterator it;
01902 for ( it = folderDeleteList.begin(); it != folderDeleteList.end(); ++it ) {
01903 it.key()->removeMsg(*it.data());
01904 delete it.data();
01905 }
01906
01907
01908
01909 KMFolder *srcFolder = 0;
01910 if ( mMsgList.first() ) {
01911 srcFolder = mMsgList.first()->parent();
01912 if ( mDestFolder && mDestFolder == srcFolder ) {
01913 completeMove( OK );
01914 }
01915 }
01916 if ( !mDestFolder ) {
01917 completeMove( OK );
01918 }
01919 }
01920
01921 return OK;
01922 }
01923
01924 void KMMoveCommand::slotImapFolderCompleted(KMFolderImap *, bool success)
01925 {
01926 if ( success ) {
01927
01928
01929
01930
01931
01932
01933 if ( !mLostBoys.isEmpty() ) {
01934 kdDebug(5006) << "### Not all moved messages reported back that they were " << endl
01935 << "### added to the target folder. Did uidValidity change? " << endl;
01936 }
01937 completeMove( OK );
01938 } else {
01939
01940 completeMove( Failed );
01941 }
01942 }
01943
01944 void KMMoveCommand::slotMsgAddedToDestFolder(KMFolder *folder, Q_UINT32 serNum)
01945 {
01946 if (folder != mDestFolder || !mLostBoys.contains( serNum ) ) {
01947 kdDebug(5006) << "KMMoveCommand::msgAddedToDestFolder different "
01948 "folder or invalid serial number." << endl;
01949 return;
01950 }
01951 mLostBoys.remove(serNum);
01952 if ( mLostBoys.isEmpty() ) {
01953
01954 if (mDestFolder && mDestFolder->folderType() != KMFolderTypeImap) {
01955 mDestFolder->sync();
01956 }
01957 completeMove( OK );
01958 } else {
01959 mProgressItem->incCompletedItems();
01960 mProgressItem->updateProgress();
01961 }
01962 }
01963
01964 void KMMoveCommand::completeMove( Result result )
01965 {
01966 if ( mDestFolder )
01967 mDestFolder->close();
01968 while ( !mOpenedFolders.empty() ) {
01969 KMFolder *folder = mOpenedFolders.back();
01970 mOpenedFolders.pop_back();
01971 folder->close();
01972 }
01973 if ( mProgressItem )
01974 mProgressItem->setComplete();
01975 setResult( result );
01976 emit completed( this );
01977 deleteLater();
01978 }
01979
01980 void KMMoveCommand::slotMoveCanceled()
01981 {
01982 completeMove( Canceled );
01983 }
01984
01985
01986 KMDeleteMsgCommand::KMDeleteMsgCommand( KMFolder* srcFolder,
01987 const QPtrList<KMMsgBase> &msgList )
01988 :KMMoveCommand( findTrashFolder( srcFolder ), msgList)
01989 {
01990 srcFolder->open();
01991 mOpenedFolders.push_back( srcFolder );
01992 }
01993
01994 KMDeleteMsgCommand::KMDeleteMsgCommand( KMFolder* srcFolder, KMMessage * msg )
01995 :KMMoveCommand( findTrashFolder( srcFolder ), msg)
01996 {
01997 srcFolder->open();
01998 mOpenedFolders.push_back( srcFolder );
01999 }
02000
02001 KMDeleteMsgCommand::KMDeleteMsgCommand( Q_UINT32 sernum )
02002 :KMMoveCommand( sernum )
02003 {
02004 KMFolder *srcFolder;
02005 int idx;
02006 kmkernel->msgDict()->getLocation( sernum, &srcFolder, &idx );
02007 KMMsgBase *msg = srcFolder->getMsgBase( idx );
02008 srcFolder->open();
02009 mOpenedFolders.push_back( srcFolder );
02010 addMsg( msg );
02011 setDestFolder( findTrashFolder( srcFolder ) );
02012 }
02013
02014 KMFolder * KMDeleteMsgCommand::findTrashFolder( KMFolder * folder )
02015 {
02016 KMFolder* trash = folder->trashFolder();
02017 if( !trash )
02018 trash = kmkernel->trashFolder();
02019 if( trash != folder )
02020 return trash;
02021 return 0;
02022 }
02023
02024
02025 KMUrlClickedCommand::KMUrlClickedCommand( const KURL &url, uint identity,
02026 KMReaderWin *readerWin, bool htmlPref, KMMainWidget *mainWidget )
02027 :mUrl( url ), mIdentity( identity ), mReaderWin( readerWin ),
02028 mHtmlPref( htmlPref ), mMainWidget( mainWidget )
02029 {
02030 }
02031
02032 KMCommand::Result KMUrlClickedCommand::execute()
02033 {
02034 KMComposeWin *win;
02035 KMMessage* msg;
02036
02037 if (mUrl.protocol() == "mailto")
02038 {
02039 msg = new KMMessage;
02040 msg->initHeader(mIdentity);
02041 msg->setCharset("utf-8");
02042 msg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
02043 QString query=mUrl.query();
02044 while (!query.isEmpty()) {
02045 QString queryPart;
02046 int secondQuery = query.find('?',1);
02047 if (secondQuery != -1)
02048 queryPart = query.left(secondQuery);
02049 else
02050 queryPart = query;
02051 query = query.mid(queryPart.length());
02052
02053 if (queryPart.left(9) == "?subject=")
02054 msg->setSubject( KURL::decode_string(queryPart.mid(9)) );
02055 else if (queryPart.left(6) == "?body=")
02056
02057
02058 msg->setBody( KURL::decode_string(queryPart.mid(6)).latin1() );
02059 else if (queryPart.left(4) == "?cc=")
02060 msg->setCc( KURL::decode_string(queryPart.mid(4)) );
02061 }
02062
02063 win = new KMComposeWin(msg, mIdentity);
02064 win->setCharset("", TRUE);
02065 win->show();
02066 }
02067 else if ( mUrl.protocol() == "im" )
02068 {
02069 kmkernel->imProxy()->chatWithContact( mUrl.path() );
02070 }
02071 else if ((mUrl.protocol() == "http") || (mUrl.protocol() == "https") ||
02072 (mUrl.protocol() == "ftp") || (mUrl.protocol() == "file") ||
02073 (mUrl.protocol() == "ftps") || (mUrl.protocol() == "sftp" ) ||
02074 (mUrl.protocol() == "help") || (mUrl.protocol() == "vnc") ||
02075 (mUrl.protocol() == "smb"))
02076 {
02077 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n("Opening URL..."));
02078 KMimeType::Ptr mime = KMimeType::findByURL( mUrl );
02079 if (mime->name() == "application/x-desktop" ||
02080 mime->name() == "application/x-executable" ||
02081 mime->name() == "application/x-msdos-program" ||
02082 mime->name() == "application/x-shellscript" )
02083 {
02084 if (KMessageBox::warningYesNo( 0, i18n( "<qt>Do you really want to execute <b>%1</b>?</qt>" )
02085 .arg( mUrl.prettyURL() ) ) != KMessageBox::Yes)
02086 return Canceled;
02087 }
02088 (void) new KRun( mUrl );
02089 }
02090 else
02091 return Failed;
02092
02093 return OK;
02094 }
02095
02096 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( QWidget *parent, KMMessage *msg )
02097 : KMCommand( parent, msg ), mImplicitAttachments( true ), mEncoded( false )
02098 {
02099 }
02100
02101 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( QWidget *parent, const QPtrList<KMMsgBase>& msgs )
02102 : KMCommand( parent, msgs ), mImplicitAttachments( true ), mEncoded( false )
02103 {
02104 }
02105
02106 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( QWidget *parent, QPtrList<partNode>& attachments,
02107 KMMessage *msg, bool encoded )
02108 : KMCommand( parent, msg ), mImplicitAttachments( false ),
02109 mEncoded( encoded )
02110 {
02111
02112 msg->setComplete( true );
02113 for ( QPtrListIterator<partNode> it( attachments ); it.current(); ++it ) {
02114 mAttachmentMap.insert( it.current(), msg );
02115 }
02116 }
02117
02118 KMCommand::Result KMSaveAttachmentsCommand::execute()
02119 {
02120 setEmitsCompletedItself( true );
02121 if ( mImplicitAttachments ) {
02122 QPtrList<KMMessage> msgList = retrievedMsgs();
02123 KMMessage *msg;
02124 for ( QPtrListIterator<KMMessage> itr( msgList );
02125 ( msg = itr.current() );
02126 ++itr ) {
02127 partNode *rootNode = partNode::fromMessage( msg );
02128 for ( partNode *child = rootNode; child;
02129 child = child->firstChild() ) {
02130 for ( partNode *node = child; node; node = node->nextSibling() ) {
02131 if ( node->type() != DwMime::kTypeMultipart )
02132 mAttachmentMap.insert( node, msg );
02133 }
02134 }
02135 }
02136 }
02137 setDeletesItself( true );
02138
02139 KMLoadPartsCommand *command = new KMLoadPartsCommand( mAttachmentMap );
02140 connect( command, SIGNAL( partsRetrieved() ),
02141 this, SLOT( slotSaveAll() ) );
02142 command->start();
02143
02144 return OK;
02145 }
02146
02147 void KMSaveAttachmentsCommand::slotSaveAll()
02148 {
02149
02150
02151
02152 if ( mImplicitAttachments ) {
02153 for ( PartNodeMessageMap::iterator it = mAttachmentMap.begin();
02154 it != mAttachmentMap.end(); ) {
02155
02156
02157
02158 if ( it.key()->msgPart().fileName().stripWhiteSpace().isEmpty() &&
02159 ( it.key()->msgPart().name().stripWhiteSpace().isEmpty() ||
02160 !it.key()->parentNode() ) ) {
02161 PartNodeMessageMap::iterator delIt = it;
02162 ++it;
02163 mAttachmentMap.remove( delIt );
02164 }
02165 else
02166 ++it;
02167 }
02168 if ( mAttachmentMap.isEmpty() ) {
02169 KMessageBox::information( 0, i18n("Found no attachments to save.") );
02170 setResult( OK );
02171 emit completed( this );
02172 deleteLater();
02173 return;
02174 }
02175 }
02176
02177 KURL url, dirUrl;
02178 if ( mAttachmentMap.count() > 1 ) {
02179
02180 KFileDialog fdlg( ":saveAttachments", QString::null, parentWidget(),
02181 "save attachments dialog", true );
02182 fdlg.setCaption( i18n("Save Attachments To") );
02183 fdlg.setOperationMode( KFileDialog::Saving );
02184 fdlg.setMode( (unsigned int) KFile::Directory );
02185 if ( fdlg.exec() == QDialog::Rejected || !fdlg.selectedURL().isValid() ) {
02186 setResult( Canceled );
02187 emit completed( this );
02188 deleteLater();
02189 return;
02190 }
02191 dirUrl = fdlg.selectedURL();
02192 }
02193 else {
02194
02195 partNode *node = mAttachmentMap.begin().key();
02196
02197 QString s =
02198 node->msgPart().fileName().stripWhiteSpace().replace( ':', '_' );
02199 if ( s.isEmpty() )
02200 s = node->msgPart().name().stripWhiteSpace().replace( ':', '_' );
02201 if ( s.isEmpty() )
02202 s = i18n("filename for an unnamed attachment", "attachment.1");
02203 url = KFileDialog::getSaveURL( s, QString::null, parentWidget(),
02204 QString::null );
02205 if ( url.isEmpty() ) {
02206 setResult( Canceled );
02207 emit completed( this );
02208 deleteLater();
02209 return;
02210 }
02211 }
02212
02213 Result globalResult = OK;
02214 int unnamedAtmCount = 0;
02215 for ( PartNodeMessageMap::const_iterator it = mAttachmentMap.begin();
02216 it != mAttachmentMap.end();
02217 ++it ) {
02218 KURL curUrl;
02219 if ( !dirUrl.isEmpty() ) {
02220 curUrl = dirUrl;
02221 QString s =
02222 it.key()->msgPart().fileName().stripWhiteSpace().replace( ':', '_' );
02223 if ( s.isEmpty() )
02224 s = it.key()->msgPart().name().stripWhiteSpace().replace( ':', '_' );
02225 if ( s.isEmpty() ) {
02226 ++unnamedAtmCount;
02227 s = i18n("filename for the %1-th unnamed attachment",
02228 "attachment.%1")
02229 .arg( unnamedAtmCount );
02230 }
02231 curUrl.setFileName( s );
02232 } else {
02233 curUrl = url;
02234 }
02235
02236 if ( !curUrl.isEmpty() ) {
02237 if ( KIO::NetAccess::exists( curUrl, false, parentWidget() ) ) {
02238 if ( KMessageBox::warningContinueCancel( parentWidget(),
02239 i18n( "A file named %1 already exists. Do you want to overwrite it?" )
02240 .arg( curUrl.fileName() ),
02241 i18n( "File Already Exists" ), i18n("Overwrite") ) == KMessageBox::Cancel) {
02242 continue;
02243 }
02244 }
02245
02246 const Result result = saveItem( it.key(), curUrl );
02247 if ( result != OK )
02248 globalResult = result;
02249 }
02250 }
02251 setResult( globalResult );
02252 emit completed( this );
02253 deleteLater();
02254 }
02255
02256 KMCommand::Result KMSaveAttachmentsCommand::saveItem( partNode *node,
02257 const KURL& url )
02258 {
02259 bool bSaveEncrypted = false;
02260 bool bEncryptedParts = node->encryptionState() != KMMsgNotEncrypted;
02261 if( bEncryptedParts )
02262 if( KMessageBox::questionYesNo( parentWidget(),
02263 i18n( "The part %1 of the message is encrypted. Do you want to keep the encryption when saving?" ).
02264 arg( url.fileName() ),
02265 i18n( "KMail Question" ) ) ==
02266 KMessageBox::Yes )
02267 bSaveEncrypted = true;
02268
02269 bool bSaveWithSig = true;
02270 if( node->signatureState() != KMMsgNotSigned )
02271 if( KMessageBox::questionYesNo( parentWidget(),
02272 i18n( "The part %1 of the message is signed. Do you want to keep the signature when saving?" ).
02273 arg( url.fileName() ),
02274 i18n( "KMail Question" ) ) !=
02275 KMessageBox::Yes )
02276 bSaveWithSig = false;
02277
02278 QByteArray data;
02279 if ( mEncoded )
02280 {
02281
02282
02283 QCString cstr( node->msgPart().body() );
02284 data = cstr;
02285 data.resize(data.size() - 1);
02286 }
02287 else
02288 {
02289 if( bSaveEncrypted || !bEncryptedParts) {
02290 partNode *dataNode = node;
02291 QCString rawReplyString;
02292 bool gotRawReplyString = false;
02293 if( !bSaveWithSig ) {
02294 if( DwMime::kTypeMultipart == node->type() &&
02295 DwMime::kSubtypeSigned == node->subType() ){
02296
02297 if( node->findType( DwMime::kTypeApplication,
02298 DwMime::kSubtypePgpSignature,
02299 TRUE, false ) ){
02300 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02301 DwMime::kSubtypePgpSignature,
02302 TRUE, false );
02303 }else if( node->findType( DwMime::kTypeApplication,
02304 DwMime::kSubtypePkcs7Mime,
02305 TRUE, false ) ){
02306 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02307 DwMime::kSubtypePkcs7Mime,
02308 TRUE, false );
02309 }else{
02310 dataNode = node->findTypeNot( DwMime::kTypeMultipart,
02311 DwMime::kSubtypeUnknown,
02312 TRUE, false );
02313 }
02314 }else{
02315 ObjectTreeParser otp( 0, 0, false, false, false );
02316
02317
02318 dataNode->setProcessed( false, true );
02319 otp.parseObjectTree( dataNode );
02320
02321 rawReplyString = otp.rawReplyString();
02322 gotRawReplyString = true;
02323 }
02324 }
02325 QByteArray cstr = gotRawReplyString
02326 ? rawReplyString
02327 : dataNode->msgPart().bodyDecodedBinary();
02328 data = cstr;
02329 size_t size = cstr.size();
02330 if ( dataNode->msgPart().type() == DwMime::kTypeText ) {
02331
02332 size = KMFolder::crlf2lf( cstr.data(), size );
02333 }
02334 data.resize( size );
02335 }
02336 }
02337 QDataStream ds;
02338 QFile file;
02339 KTempFile tf;
02340 tf.setAutoDelete( true );
02341 if ( url.isLocalFile() )
02342 {
02343
02344 file.setName( url.path() );
02345 if ( !file.open( IO_WriteOnly ) )
02346 {
02347 KMessageBox::error( parentWidget(),
02348 i18n( "%2 is detailed error description",
02349 "Could not write the file %1:\n%2" )
02350 .arg( file.name() )
02351 .arg( QString::fromLocal8Bit( strerror( errno ) ) ),
02352 i18n( "KMail Error" ) );
02353 return Failed;
02354 }
02355
02356
02357
02358 ds.setDevice( &file );
02359 } else
02360 {
02361
02362 ds.setDevice( tf.file() );
02363 }
02364
02365 ds.writeRawBytes( data.data(), data.size() );
02366 if ( !url.isLocalFile() )
02367 {
02368 tf.close();
02369 if ( !KIO::NetAccess::upload( tf.name(), url, parentWidget() ) )
02370 {
02371 KMessageBox::error( parentWidget(),
02372 i18n( "Could not write the file %1." )
02373 .arg( url.path() ),
02374 i18n( "KMail Error" ) );
02375 return Failed;
02376 }
02377 } else
02378 file.close();
02379 return OK;
02380 }
02381
02382 KMLoadPartsCommand::KMLoadPartsCommand( QPtrList<partNode>& parts, KMMessage *msg )
02383 : mNeedsRetrieval( 0 )
02384 {
02385 for ( QPtrListIterator<partNode> it( parts ); it.current(); ++it ) {
02386 mPartMap.insert( it.current(), msg );
02387 }
02388 }
02389
02390 KMLoadPartsCommand::KMLoadPartsCommand( partNode *node, KMMessage *msg )
02391 : mNeedsRetrieval( 0 )
02392 {
02393 mPartMap.insert( node, msg );
02394 }
02395
02396 KMLoadPartsCommand::KMLoadPartsCommand( PartNodeMessageMap& partMap )
02397 : mNeedsRetrieval( 0 ), mPartMap( partMap )
02398 {
02399 }
02400
02401 void KMLoadPartsCommand::slotStart()
02402 {
02403 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02404 it != mPartMap.end();
02405 ++it ) {
02406 if ( !it.key()->msgPart().isComplete() &&
02407 !it.key()->msgPart().partSpecifier().isEmpty() ) {
02408
02409 ++mNeedsRetrieval;
02410 KMFolder* curFolder = it.data()->parent();
02411 if ( curFolder ) {
02412 FolderJob *job =
02413 curFolder->createJob( it.data(), FolderJob::tGetMessage,
02414 0, it.key()->msgPart().partSpecifier() );
02415 job->setCancellable( false );
02416 connect( job, SIGNAL(messageUpdated(KMMessage*, QString)),
02417 this, SLOT(slotPartRetrieved(KMMessage*, QString)) );
02418 job->start();
02419 } else
02420 kdWarning(5006) << "KMLoadPartsCommand - msg has no parent" << endl;
02421 }
02422 }
02423 if ( mNeedsRetrieval == 0 )
02424 execute();
02425 }
02426
02427 void KMLoadPartsCommand::slotPartRetrieved( KMMessage *msg,
02428 QString partSpecifier )
02429 {
02430 DwBodyPart *part =
02431 msg->findDwBodyPart( msg->getFirstDwBodyPart(), partSpecifier );
02432 if ( part ) {
02433
02434 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02435 it != mPartMap.end();
02436 ++it ) {
02437 if ( it.key()->dwPart()->partId() == part->partId() )
02438 it.key()->setDwPart( part );
02439 }
02440 } else
02441 kdWarning(5006) << "KMLoadPartsCommand::slotPartRetrieved - could not find bodypart!" << endl;
02442 --mNeedsRetrieval;
02443 if ( mNeedsRetrieval == 0 )
02444 execute();
02445 }
02446
02447 KMCommand::Result KMLoadPartsCommand::execute()
02448 {
02449 emit partsRetrieved();
02450 setResult( OK );
02451 emit completed( this );
02452 deleteLater();
02453 return OK;
02454 }
02455
02456 KMResendMessageCommand::KMResendMessageCommand( QWidget *parent,
02457 KMMessage *msg )
02458 :KMCommand( parent, msg )
02459 {
02460 }
02461
02462 KMCommand::Result KMResendMessageCommand::execute()
02463 {
02464 KMComposeWin *win;
02465 KMMessage *msg = retrievedMessage();
02466
02467 KMMessage *newMsg = new KMMessage(*msg);
02468 newMsg->setCharset(msg->codec()->mimeName());
02469
02470 newMsg->removeHeaderField( "Message-Id" );
02471 newMsg->setParent( 0 );
02472
02473
02474 newMsg->removeHeaderField( "Date" );
02475
02476 win = new KMComposeWin();
02477 win->setMsg(newMsg, false, true);
02478 win->show();
02479
02480 return OK;
02481 }
02482
02483 KMMailingListCommand::KMMailingListCommand( QWidget *parent, KMFolder *folder )
02484 : KMCommand( parent ), mFolder( folder )
02485 {
02486 }
02487
02488 KMCommand::Result KMMailingListCommand::execute()
02489 {
02490 KURL::List lst = urls();
02491 QString handler = ( mFolder->mailingList().handler() == MailingList::KMail )
02492 ? "mailto" : "https";
02493
02494 KMCommand *command = 0;
02495 for ( KURL::List::Iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
02496 if ( handler == (*itr).protocol() ) {
02497 command = new KMUrlClickedCommand( *itr, mFolder->identity(), 0, false );
02498 }
02499 }
02500 if ( !command && !lst.empty() ) {
02501 command =
02502 new KMUrlClickedCommand( lst.first(), mFolder->identity(), 0, false );
02503 }
02504 if ( command ) {
02505 connect( command, SIGNAL( completed( KMCommand * ) ),
02506 this, SLOT( commandCompleted( KMCommand * ) ) );
02507 setDeletesItself( true );
02508 setEmitsCompletedItself( true );
02509 command->start();
02510 return OK;
02511 }
02512 return Failed;
02513 }
02514
02515 void KMMailingListCommand::commandCompleted( KMCommand *command )
02516 {
02517 setResult( command->result() );
02518 emit completed( this );
02519 deleteLater();
02520 }
02521
02522 KMMailingListPostCommand::KMMailingListPostCommand( QWidget *parent, KMFolder *folder )
02523 : KMMailingListCommand( parent, folder )
02524 {
02525 }
02526 KURL::List KMMailingListPostCommand::urls() const
02527 {
02528 return mFolder->mailingList().postURLS();
02529 }
02530
02531 KMMailingListSubscribeCommand::KMMailingListSubscribeCommand( QWidget *parent, KMFolder *folder )
02532 : KMMailingListCommand( parent, folder )
02533 {
02534 }
02535 KURL::List KMMailingListSubscribeCommand::urls() const
02536 {
02537 return mFolder->mailingList().subscribeURLS();
02538 }
02539
02540 KMMailingListUnsubscribeCommand::KMMailingListUnsubscribeCommand( QWidget *parent, KMFolder *folder )
02541 : KMMailingListCommand( parent, folder )
02542 {
02543 }
02544 KURL::List KMMailingListUnsubscribeCommand::urls() const
02545 {
02546 return mFolder->mailingList().unsubscribeURLS();
02547 }
02548
02549 KMMailingListArchivesCommand::KMMailingListArchivesCommand( QWidget *parent, KMFolder *folder )
02550 : KMMailingListCommand( parent, folder )
02551 {
02552 }
02553 KURL::List KMMailingListArchivesCommand::urls() const
02554 {
02555 return mFolder->mailingList().archiveURLS();
02556 }
02557
02558 KMMailingListHelpCommand::KMMailingListHelpCommand( QWidget *parent, KMFolder *folder )
02559 : KMMailingListCommand( parent, folder )
02560 {
02561 }
02562 KURL::List KMMailingListHelpCommand::urls() const
02563 {
02564 return mFolder->mailingList().helpURLS();
02565 }
02566
02567 KMIMChatCommand::KMIMChatCommand( const KURL &url, KMMessage *msg )
02568 :mUrl( url ), mMessage( msg )
02569 {
02570 }
02571
02572 KMCommand::Result KMIMChatCommand::execute()
02573 {
02574 kdDebug( 5006 ) << k_funcinfo << " URL is: " << mUrl << endl;
02575
02576 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
02577 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getEmailAddr( mUrl.path() ) ) ;
02578
02579
02580 if( addresses.count() == 1 ) {
02581 kmkernel->imProxy()->chatWithContact( addresses[0].uid() );
02582 return OK;
02583 }
02584 else
02585 {
02586 kdDebug( 5006 ) << "Didn't find exactly one addressee, couldn't tell who to chat to for that email address. Count = " << addresses.count() << endl;
02587
02588 QString apology;
02589 if ( addresses.isEmpty() )
02590 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." );
02591 else
02592 {
02593 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." );
02594 QStringList nameList;
02595 KABC::AddresseeList::const_iterator it = addresses.begin();
02596 KABC::AddresseeList::const_iterator end = addresses.end();
02597 for ( ; it != end; ++it )
02598 {
02599 nameList.append( (*it).realName() );
02600 }
02601 QString names = nameList.join( QString::fromLatin1( ",\n" ) );
02602 apology = apology.arg( names );
02603 }
02604
02605 KMessageBox::sorry( parentWidget(), apology );
02606 return Failed;
02607 }
02608 }