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