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 )
01285 : KMCommand( parent, msg ), mHtmlOverride( htmlOverride )
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.setMsg(retrievedMessage(), TRUE);
01296 printWin.printMsg();
01297
01298
return OK;
01299 }
01300
01301
01302 KMSetStatusCommand::KMSetStatusCommand( KMMsgStatus status,
01303
const QValueList<Q_UINT32> &serNums,
bool toggle )
01304 : mStatus( status ), mSerNums( serNums ), mToggle( toggle )
01305 {
01306 }
01307
01308 KMCommand::Result KMSetStatusCommand::execute()
01309 {
01310
QValueListIterator<Q_UINT32> it;
01311
int idx = -1;
01312
KMFolder *folder = 0;
01313
bool parentStatus =
false;
01314
01315
01316
01317
if (mToggle) {
01318 KMMsgBase *msg;
01319 kmkernel->msgDict()->getLocation( *mSerNums.begin(), &folder, &idx );
01320
if (folder) {
01321 msg = folder->
getMsgBase(idx);
01322
if (msg && (msg->status()&mStatus))
01323 parentStatus =
true;
01324
else
01325 parentStatus =
false;
01326 }
01327 }
01328
QMap< KMFolder*, QValueList<int> > folderMap;
01329
for ( it = mSerNums.begin(); it != mSerNums.end(); ++it ) {
01330 kmkernel->msgDict()->getLocation( *it, &folder, &idx );
01331
if (folder) {
01332
if (mToggle) {
01333 KMMsgBase *msg = folder->
getMsgBase(idx);
01334
01335
if (msg) {
01336
bool myStatus;
01337
if (msg->status()&mStatus)
01338 myStatus =
true;
01339
else
01340 myStatus =
false;
01341
if (myStatus != parentStatus)
01342
continue;
01343 }
01344 }
01345
01346
01347 folderMap[folder].append(idx);
01348 }
01349 }
01350
QMapIterator< KMFolder*, QValueList<int> > it2 = folderMap.begin();
01351
while ( it2 != folderMap.end() ) {
01352
KMFolder *f = it2.key();
01353 f->
setStatus( (*it2), mStatus, mToggle );
01354 ++it2;
01355 }
01356
01357
01358
return OK;
01359 }
01360
01361
01362 KMFilterCommand::KMFilterCommand(
const QCString &field,
const QString &value )
01363 : mField( field ), mValue( value )
01364 {
01365 }
01366
01367 KMCommand::Result KMFilterCommand::execute()
01368 {
01369 kmkernel->filterMgr()->createFilter( mField, mValue );
01370
01371
return OK;
01372 }
01373
01374
01375 KMFilterActionCommand::KMFilterActionCommand(
QWidget *parent,
01376
const QPtrList<KMMsgBase> &msgList,
01377 KMFilter *filter )
01378 : KMCommand( parent, msgList ), mFilter( filter )
01379 {
01380 }
01381
01382 KMCommand::Result KMFilterActionCommand::execute()
01383 {
01384
QPtrList<KMMessage> msgList = retrievedMsgs();
01385
01386
for (KMMessage *msg = msgList.first(); msg; msg = msgList.next())
01387
if( msg->parent() )
01388 kmkernel->filterMgr()->tempOpenFolder(msg->parent());
01389
01390
for (KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
01391 msg->setTransferInProgress(
false);
01392
01393
int filterResult = kmkernel->filterMgr()->process(msg, mFilter);
01394
if (filterResult == 2) {
01395
01396 perror(
"Critical error");
01397 kmkernel->emergencyExit( i18n(
"Not enough free disk space?" ));
01398 }
01399 msg->setTransferInProgress(
true);
01400 }
01401
01402
return OK;
01403 }
01404
01405
01406 KMMetaFilterActionCommand::KMMetaFilterActionCommand( KMFilter *filter,
01407
KMHeaders *headers,
01408 KMMainWidget *main )
01409 :
QObject( main ),
01410 mFilter( filter ), mHeaders( headers ), mMainWidget( main )
01411 {
01412 }
01413
01414
void KMMetaFilterActionCommand::start()
01415 {
01416
#if 0 // use action scheduler
01417
KMFilterMgr::FilterSet set = KMFilterMgr::All;
01418
QPtrList<KMFilter> filters;
01419 filters.append( mFilter );
01420 ActionScheduler *scheduler =
new ActionScheduler( set, filters, mHeaders );
01421 scheduler->setAlwaysMatch(
true );
01422 scheduler->setAutoDestruct(
true );
01423
01424
int contentX, contentY;
01425 KMHeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY );
01426
QPtrList<KMMsgBase> msgList = *mHeaders->selectedMsgs(
true);
01427 mHeaders->finalizeMove( nextItem, contentX, contentY );
01428
01429
01430
for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
01431 scheduler->execFilters( msg );
01432
#else
01433
KMCommand *filterCommand =
new KMFilterActionCommand( mMainWidget,
01434 *mHeaders->selectedMsgs(), mFilter);
01435 filterCommand->start();
01436
int contentX, contentY;
01437 KMHeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
01438 mHeaders->finalizeMove( item, contentX, contentY );
01439
#endif
01440
}
01441
01442
01443 KMMailingListFilterCommand::KMMailingListFilterCommand(
QWidget *parent,
01444 KMMessage *msg )
01445 : KMCommand( parent, msg )
01446 {
01447 }
01448
01449 KMCommand::Result KMMailingListFilterCommand::execute()
01450 {
01451
QCString name;
01452
QString value;
01453 KMMessage *msg = retrievedMessage();
01454
if (!msg)
01455
return Failed;
01456
01457
if ( !MailingList::name( msg, name, value ).isEmpty() ) {
01458 kmkernel->filterMgr()->createFilter( name, value );
01459
return OK;
01460 }
01461
else
01462
return Failed;
01463 }
01464
01465
01466
void KMMenuCommand::folderToPopupMenu(
bool move,
01467
QObject *receiver,
KMMenuToFolder *aMenuToFolder,
QPopupMenu *menu )
01468 {
01469
while ( menu->count() )
01470 {
01471
QPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
01472
if (popup)
01473
delete popup;
01474
else
01475 menu->removeItemAt( 0 );
01476 }
01477
01478
if (!kmkernel->imapFolderMgr()->dir().first() &&
01479 !kmkernel->dimapFolderMgr()->dir().first())
01480 {
01481 makeFolderMenu( &kmkernel->folderMgr()->dir(), move,
01482 receiver, aMenuToFolder, menu );
01483 }
else {
01484
01485
QPopupMenu* subMenu =
new QPopupMenu(menu);
01486 makeFolderMenu( &kmkernel->folderMgr()->dir(),
01487 move, receiver, aMenuToFolder, subMenu );
01488 menu->insertItem( i18n(
"Local Folders" ), subMenu );
01489
KMFolderDir* fdir = &kmkernel->imapFolderMgr()->dir();
01490
for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01491
if (node->isDir())
01492
continue;
01493 subMenu =
new QPopupMenu(menu);
01494 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01495 menu->insertItem( node->label(), subMenu );
01496 }
01497 fdir = &kmkernel->dimapFolderMgr()->dir();
01498
for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
01499
if (node->isDir())
01500
continue;
01501 subMenu =
new QPopupMenu(menu);
01502 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
01503 menu->insertItem( node->label(), subMenu );
01504 }
01505 }
01506 }
01507
01508
void KMMenuCommand::makeFolderMenu(KMFolderNode* node,
bool move,
01509
QObject *receiver,
KMMenuToFolder *aMenuToFolder,
QPopupMenu *menu )
01510 {
01511
01512
if (move)
01513 {
01514 disconnect(menu, SIGNAL(activated(
int)), receiver,
01515 SLOT(moveSelectedToFolder(
int)));
01516 connect(menu, SIGNAL(activated(
int)), receiver,
01517 SLOT(moveSelectedToFolder(
int)));
01518 }
else {
01519 disconnect(menu, SIGNAL(activated(
int)), receiver,
01520 SLOT(copySelectedToFolder(
int)));
01521 connect(menu, SIGNAL(activated(
int)), receiver,
01522 SLOT(copySelectedToFolder(
int)));
01523 }
01524
01525
KMFolder *folder = 0;
01526
KMFolderDir *folderDir = 0;
01527
if (node->isDir()) {
01528 folderDir = static_cast<KMFolderDir*>(node);
01529 }
else {
01530 folder = static_cast<KMFolder*>(node);
01531 folderDir = folder->
child();
01532 }
01533
01534
if (folder && !folder->
noContent())
01535 {
01536
int menuId;
01537
if (move)
01538 menuId = menu->insertItem(i18n(
"Move to This Folder"));
01539
else
01540 menuId = menu->insertItem(i18n(
"Copy to This Folder"));
01541 aMenuToFolder->insert( menuId, folder );
01542 menu->setItemEnabled( menuId, !folder->
isReadOnly() );
01543 menu->insertSeparator();
01544 }
01545
01546
if (!folderDir)
01547
return;
01548
01549
for (KMFolderNode *it = folderDir->first(); it; it = folderDir->next() ) {
01550
if (it->isDir())
01551
continue;
01552
KMFolder *child = static_cast<KMFolder*>(it);
01553
QString label = child->
label();
01554 label.replace(
"&",
"&&");
01555
if (child->
child() && child->
child()->first()) {
01556
01557
QPopupMenu *subMenu =
new QPopupMenu(menu,
"subMenu");
01558 makeFolderMenu( child, move, receiver,
01559 aMenuToFolder, subMenu );
01560 menu->insertItem( label, subMenu );
01561 }
else {
01562
01563
int menuId = menu->insertItem( label );
01564 aMenuToFolder->insert( menuId, child );
01565 menu->setItemEnabled( menuId, !child->
isReadOnly() );
01566 }
01567 }
01568
return;
01569 }
01570
01571
01572 KMCopyCommand::KMCopyCommand(
KMFolder* destFolder,
01573
const QPtrList<KMMsgBase> &msgList )
01574 :mDestFolder( destFolder ), mMsgList( msgList )
01575 {
01576 }
01577
01578 KMCopyCommand::KMCopyCommand(
KMFolder* destFolder, KMMessage * msg )
01579 :mDestFolder( destFolder )
01580 {
01581 mMsgList.append( &msg->toMsgBase() );
01582 }
01583
01584 KMCommand::Result KMCopyCommand::execute()
01585 {
01586 KMMsgBase *msgBase;
01587 KMMessage *msg, *newMsg;
01588
int idx = -1;
01589
bool isMessage;
01590
QPtrList<KMMessage> list;
01591
01592
if (mDestFolder && mDestFolder->open() != 0)
01593
return Failed;
01594
01595
KCursorSaver busy(KBusyPtr::busy());
01596
01597
for (msgBase = mMsgList.first(); msgBase; msgBase = mMsgList.next() )
01598 {
01599
KMFolder *srcFolder = msgBase->parent();
01600
if (isMessage = msgBase->isMessage())
01601 {
01602 msg = static_cast<KMMessage*>(msgBase);
01603 }
else {
01604 idx = srcFolder->
find(msgBase);
01605 assert(idx != -1);
01606 msg = srcFolder->
getMsg(idx);
01607 }
01608
01609
if (srcFolder &&
01610 (srcFolder->
folderType()== KMFolderTypeImap) &&
01611 (mDestFolder->folderType() == KMFolderTypeImap) &&
01612 (static_cast<KMFolderImap*>(srcFolder->
storage())->account() ==
01613 static_cast<KMFolderImap*>(mDestFolder->storage())->account()))
01614 {
01615 list.append(msg);
01616 }
else {
01617 newMsg =
new KMMessage;
01618 newMsg->setComplete(msg->isComplete());
01619
01620
if (!newMsg->isComplete())
01621 newMsg->setReadyToShow(
false);
01622 newMsg->fromString(msg->asString());
01623 newMsg->setStatus(msg->status());
01624
01625
if (srcFolder && !newMsg->isComplete())
01626 {
01627 newMsg->setParent(msg->parent());
01628 FolderJob *job = srcFolder->
createJob(newMsg);
01629 job->setCancellable(
false );
01630 connect(job, SIGNAL(messageRetrieved(KMMessage*)),
01631 mDestFolder, SLOT(reallyAddCopyOfMsg(KMMessage*)));
01632
01633 newMsg->setTransferInProgress(
true);
01634 job->start();
01635 }
else {
01636
int rc, index;
01637 rc = mDestFolder->addMsg(newMsg, &index);
01638
if (rc == 0 && index != -1)
01639 mDestFolder->unGetMsg( mDestFolder->count() - 1 );
01640 }
01641 }
01642
01643
if (!isMessage && list.isEmpty())
01644 {
01645 assert(idx != -1);
01646 srcFolder->
unGetMsg( idx );
01647 }
01648
01649 }
01650 mDestFolder->close();
01651
01652
01653
01654
01655
if (!list.isEmpty())
01656 {
01657
01658 KMFolderImap *imapDestFolder = static_cast<KMFolderImap*>(mDestFolder->storage());
01659 imapDestFolder->copyMsg(list);
01660 imapDestFolder->getFolder();
01661 }
01662
01663
return OK;
01664 }
01665
01666
01667 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
01668
const QPtrList<KMMsgBase> &msgList)
01669 :mDestFolder( destFolder ), mMsgList( msgList ), mProgressItem( 0 )
01670 {
01671 setDeletesItself(
true );
01672 }
01673
01674 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
01675 KMMessage *msg )
01676 :mDestFolder( destFolder ), mProgressItem( 0 )
01677 {
01678 setDeletesItself(
true );
01679 mMsgList.append( &msg->toMsgBase() );
01680 }
01681
01682 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
01683 KMMsgBase *msgBase )
01684 :mDestFolder( destFolder ), mProgressItem( 0 )
01685 {
01686 setDeletesItself(
true );
01687 mMsgList.append( msgBase );
01688 }
01689
01690 KMCommand::Result KMMoveCommand::execute()
01691 {
01692 setEmitsCompletedItself(
true );
01693
typedef QMap< KMFolder*, QPtrList<KMMessage>* > FolderToMessageListMap;
01694 FolderToMessageListMap folderDeleteList;
01695
01696
if (mDestFolder && mDestFolder->open() != 0) {
01697 completeMove( Failed );
01698
return Failed;
01699 }
01700
KCursorSaver busy(KBusyPtr::busy());
01701
01702
01703 Q_ASSERT( !mProgressItem );
01704 mProgressItem =
01705 ProgressManager::createProgressItem (
01706
"move"+ProgressManager::getUniqueID(),
01707 mDestFolder ? i18n(
"Moving messages" ) : i18n(
"Deleting messages" ) );
01708 connect( mProgressItem, SIGNAL( progressItemCanceled( ProgressItem* ) ),
01709
this, SLOT( slotMoveCanceled() ) );
01710
01711 KMMessage *msg;
01712 KMMsgBase *msgBase;
01713
int rc = 0;
01714
int index;
01715
QPtrList<KMMessage> list;
01716
int undoId = -1;
01717
01718
if (mDestFolder) {
01719 connect (mDestFolder, SIGNAL(msgAdded(
KMFolder*, Q_UINT32)),
01720
this, SLOT(slotMsgAddedToDestFolder(
KMFolder*, Q_UINT32)));
01721
01722 }
01723
for ( msgBase=mMsgList.first(); msgBase; msgBase=mMsgList.next() ) {
01724 mLostBoys.append( msgBase->getMsgSerNum() );
01725 }
01726 mProgressItem->setTotalItems( mMsgList.count() );
01727
01728
for (msgBase=mMsgList.first(); msgBase && !rc; msgBase=mMsgList.next()) {
01729
KMFolder *srcFolder = msgBase->parent();
01730
if (srcFolder == mDestFolder)
01731
continue;
01732
bool undo = msgBase->enableUndo();
01733
int idx = srcFolder->
find(msgBase);
01734 assert(idx != -1);
01735
if ( msgBase->isMessage() )
01736 msg = static_cast<KMMessage*>(msgBase);
01737
else
01738 msg = srcFolder->
getMsg(idx);
01739
01740
if ( msg->transferInProgress() &&
01741 srcFolder->
folderType() == KMFolderTypeImap )
01742 {
01743
01744 msg->setTransferInProgress(
false,
true );
01745 static_cast<KMFolderImap*>(srcFolder->
storage())->ignoreJobsForMessage( msg );
01746 }
01747
01748
if (mDestFolder) {
01749
if (mDestFolder->folderType() == KMFolderTypeImap) {
01750
01751
01752
01753 KMFolderImap *imapFolder = static_cast<KMFolderImap*> ( mDestFolder->storage() );
01754 disconnect (imapFolder, SIGNAL(folderComplete( KMFolderImap*,
bool )),
01755
this, SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
01756
01757 connect (imapFolder, SIGNAL(folderComplete( KMFolderImap*,
bool )),
01758
this, SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
01759 list.append(msg);
01760 }
else {
01761
01762 rc = mDestFolder->moveMsg(msg, &index);
01763
if (rc == 0 && index != -1) {
01764 KMMsgBase *mb = mDestFolder->unGetMsg( mDestFolder->count() - 1 );
01765
if (undo && mb)
01766 {
01767
if ( undoId == -1 )
01768 undoId = kmkernel->undoStack()->newUndoAction( srcFolder, mDestFolder );
01769 kmkernel->undoStack()->addMsgToAction( undoId, mb->getMsgSerNum() );
01770 }
01771 }
else if (rc != 0) {
01772
01773
01774 completeMove( Failed );
01775
return Failed;
01776 }
01777 }
01778 }
else {
01779
01780
01781
if (srcFolder->
folderType() == KMFolderTypeImap) {
01782
if (!folderDeleteList[srcFolder])
01783 folderDeleteList[srcFolder] =
new QPtrList<KMMessage>;
01784 folderDeleteList[srcFolder]->append( msg );
01785 }
else {
01786 srcFolder->
removeMsg(idx);
01787
delete msg;
01788 }
01789 }
01790 }
01791
if (!list.isEmpty() && mDestFolder) {
01792 mDestFolder->moveMsg(list, &index);
01793 }
else {
01794 FolderToMessageListMap::Iterator it;
01795
for ( it = folderDeleteList.begin(); it != folderDeleteList.end(); ++it ) {
01796 it.key()->removeMsg(*it.data());
01797
delete it.data();
01798 }
01799
01800
01801
01802
KMFolder *srcFolder = 0;
01803
if ( mMsgList.first() ) {
01804 srcFolder = mMsgList.first()->parent();
01805
if ( mDestFolder && mDestFolder == srcFolder ) {
01806 completeMove( OK );
01807 }
01808 }
01809
if ( !mDestFolder ) {
01810 completeMove( OK );
01811 }
01812 }
01813
01814
return OK;
01815 }
01816
01817
void KMMoveCommand::slotImapFolderCompleted(KMFolderImap *,
bool success)
01818 {
01819
if ( success ) {
01820
01821
01822
01823
01824
01825
01826
if ( !mLostBoys.isEmpty() ) {
01827 kdDebug(5006) <<
"### Not all moved messages reported back that they were " << endl
01828 <<
"### added to the target folder. Did uidValidity change? " << endl;
01829 }
01830 completeMove( OK );
01831 }
else {
01832
01833 completeMove( Failed );
01834 }
01835 }
01836
01837
void KMMoveCommand::slotMsgAddedToDestFolder(
KMFolder *folder, Q_UINT32 serNum)
01838 {
01839
if (folder != mDestFolder || !mLostBoys.contains( serNum ) ) {
01840 kdDebug(5006) <<
"KMMoveCommand::msgAddedToDestFolder different "
01841
"folder or invalid serial number." << endl;
01842
return;
01843 }
01844 mLostBoys.remove(serNum);
01845
if ( mLostBoys.isEmpty() ) {
01846
01847
if (mDestFolder && mDestFolder->folderType() != KMFolderTypeImap) {
01848 mDestFolder->sync();
01849 }
01850 completeMove( OK );
01851 }
else {
01852 mProgressItem->incCompletedItems();
01853 mProgressItem->updateProgress();
01854 }
01855 }
01856
01857
void KMMoveCommand::completeMove( Result result )
01858 {
01859
if ( mDestFolder )
01860 mDestFolder->close();
01861
if ( mProgressItem )
01862 mProgressItem->setComplete();
01863 setResult( result );
01864 emit completed(
this );
01865 deleteLater();
01866 }
01867
01868
void KMMoveCommand::slotMoveCanceled()
01869 {
01870 completeMove( Canceled );
01871 }
01872
01873
01874 KMDeleteMsgCommand::KMDeleteMsgCommand(
KMFolder* srcFolder,
01875
const QPtrList<KMMsgBase> &msgList )
01876 :KMMoveCommand(findTrashFolder( srcFolder ), msgList)
01877 {
01878 }
01879
01880 KMDeleteMsgCommand::KMDeleteMsgCommand(
KMFolder* srcFolder, KMMessage * msg )
01881 :KMMoveCommand(findTrashFolder( srcFolder ), msg)
01882 {
01883 }
01884
01885
01886
KMFolder * KMDeleteMsgCommand::findTrashFolder(
KMFolder * folder )
01887 {
01888
KMFolder* trash = folder->
trashFolder();
01889
if( !trash )
01890 trash = kmkernel->trashFolder();
01891
if( trash != folder )
01892
return trash;
01893
return 0;
01894 }
01895
01896 KMUrlClickedCommand::KMUrlClickedCommand(
const KURL &url, uint identity,
01897 KMReaderWin *readerWin,
bool htmlPref, KMMainWidget *mainWidget )
01898 :mUrl( url ), mIdentity( identity ), mReaderWin( readerWin ),
01899 mHtmlPref( htmlPref ), mMainWidget( mainWidget )
01900 {
01901 }
01902
01903 KMCommand::Result KMUrlClickedCommand::execute()
01904 {
01905 KMComposeWin *win;
01906 KMMessage* msg;
01907
01908
if (mUrl.protocol() ==
"mailto")
01909 {
01910 msg =
new KMMessage;
01911 msg->initHeader(mIdentity);
01912 msg->setCharset(
"utf-8");
01913 msg->setTo( KMMessage::decodeMailtoUrl( mUrl.path() ) );
01914
QString query=mUrl.query();
01915
while (!query.isEmpty()) {
01916
QString queryPart;
01917
int secondQuery = query.find(
'?',1);
01918
if (secondQuery != -1)
01919 queryPart = query.left(secondQuery);
01920
else
01921 queryPart = query;
01922 query = query.mid(queryPart.length());
01923
01924
if (queryPart.left(9) ==
"?subject=")
01925 msg->setSubject( KURL::decode_string(queryPart.mid(9)) );
01926
else if (queryPart.left(6) ==
"?body=")
01927
01928
01929 msg->setBody( KURL::decode_string(queryPart.mid(6)).latin1() );
01930
else if (queryPart.left(4) ==
"?cc=")
01931 msg->setCc( KURL::decode_string(queryPart.mid(4)) );
01932 }
01933
01934 win =
new KMComposeWin(msg, mIdentity);
01935 win->setCharset(
"", TRUE);
01936 win->show();
01937 }
01938
else if ( mUrl.protocol() ==
"im" )
01939 {
01940 kmkernel->imProxy()->chatWithContact( mUrl.path() );
01941 }
01942
else if ((mUrl.protocol() ==
"http") || (mUrl.protocol() ==
"https") ||
01943 (mUrl.protocol() ==
"ftp") || (mUrl.protocol() ==
"file") ||
01944 (mUrl.protocol() ==
"ftps") || (mUrl.protocol() ==
"sftp" ) ||
01945 (mUrl.protocol() ==
"help") || (mUrl.protocol() ==
"vnc") ||
01946 (mUrl.protocol() ==
"smb"))
01947 {
01948 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n(
"Opening URL..."));
01949 KMimeType::Ptr mime = KMimeType::findByURL( mUrl );
01950
if (mime->name() ==
"application/x-desktop" ||
01951 mime->name() ==
"application/x-executable" ||
01952 mime->name() ==
"application/x-msdos-program" ||
01953 mime->name() ==
"application/x-shellscript" )
01954 {
01955
if (KMessageBox::warningYesNo( 0, i18n(
"<qt>Do you really want to execute <b>%1</b>?</qt>" )
01956 .arg( mUrl.prettyURL() ) ) != KMessageBox::Yes)
01957
return Canceled;
01958 }
01959 (
void)
new KRun( mUrl );
01960 }
01961
else
01962
return Failed;
01963
01964
return OK;
01965 }
01966
01967 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand(
QWidget *parent, KMMessage *msg )
01968 : KMCommand( parent, msg ), mImplicitAttachments( true ), mEncoded( false )
01969 {
01970 }
01971
01972 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand(
QWidget *parent,
const QPtrList<KMMsgBase>& msgs )
01973 : KMCommand( parent, msgs ), mImplicitAttachments( true ), mEncoded( false )
01974 {
01975 }
01976
01977 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand(
QWidget *parent,
QPtrList<partNode>& attachments,
01978 KMMessage *msg,
bool encoded )
01979 : KMCommand( parent, msg ), mImplicitAttachments( false ),
01980 mEncoded( encoded )
01981 {
01982
01983 msg->setComplete(
true );
01984
for (
QPtrListIterator<partNode> it( attachments ); it.current(); ++it ) {
01985 mAttachmentMap.insert( it.current(), msg );
01986 }
01987 }
01988
01989 KMCommand::Result KMSaveAttachmentsCommand::execute()
01990 {
01991 setEmitsCompletedItself(
true );
01992
if ( mImplicitAttachments ) {
01993
QPtrList<KMMessage> msgList = retrievedMsgs();
01994 KMMessage *msg;
01995
for (
QPtrListIterator<KMMessage> itr( msgList );
01996 ( msg = itr.current() );
01997 ++itr ) {
01998 partNode *rootNode = partNode::fromMessage( msg );
01999
for ( partNode *child = rootNode; child;
02000 child = child->firstChild() ) {
02001
for ( partNode *node = child; node; node = node->nextSibling() ) {
02002
if ( node->type() != DwMime::kTypeMultipart )
02003 mAttachmentMap.insert( node, msg );
02004 }
02005 }
02006 }
02007 }
02008 setDeletesItself(
true );
02009
02010 KMLoadPartsCommand *command =
new KMLoadPartsCommand( mAttachmentMap );
02011 connect( command, SIGNAL( partsRetrieved() ),
02012
this, SLOT( slotSaveAll() ) );
02013 command->start();
02014
02015
return OK;
02016 }
02017
02018
void KMSaveAttachmentsCommand::slotSaveAll()
02019 {
02020
02021
02022
02023
if ( mImplicitAttachments ) {
02024
for ( PartNodeMessageMap::iterator it = mAttachmentMap.begin();
02025 it != mAttachmentMap.end(); ) {
02026
02027
02028
02029
if ( it.key()->msgPart().fileName().stripWhiteSpace().isEmpty() &&
02030 ( it.key()->msgPart().name().stripWhiteSpace().isEmpty() ||
02031 !it.key()->parentNode() ) ) {
02032 PartNodeMessageMap::iterator delIt = it;
02033 ++it;
02034 mAttachmentMap.remove( delIt );
02035 }
02036
else
02037 ++it;
02038 }
02039
if ( mAttachmentMap.isEmpty() ) {
02040 KMessageBox::information( 0, i18n(
"Found no attachments to save.") );
02041 setResult( OK );
02042 emit completed(
this );
02043
delete this;
02044
return;
02045 }
02046 }
02047
02048 KURL url, dirUrl;
02049
if ( mAttachmentMap.count() > 1 ) {
02050
02051 KFileDialog fdlg(
":saveAttachments", QString::null, parentWidget(),
02052
"save attachments dialog",
true );
02053 fdlg.setCaption( i18n(
"Save Attachments To") );
02054 fdlg.setOperationMode( KFileDialog::Saving );
02055 fdlg.setMode( (
unsigned int) KFile::Directory );
02056
if ( fdlg.exec() == QDialog::Rejected || !fdlg.selectedURL().isValid() ) {
02057 setResult( Canceled );
02058 emit completed(
this );
02059
delete this;
02060
return;
02061 }
02062 dirUrl = fdlg.selectedURL();
02063 }
02064
else {
02065
02066 partNode *node = mAttachmentMap.begin().key();
02067
02068
QString s =
02069 node->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
02070
if ( s.isEmpty() )
02071 s = node->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
02072
if ( s.isEmpty() )
02073 s = i18n(
"filename for an unnamed attachment",
"attachment.1");
02074 url = KFileDialog::getSaveURL( s, QString::null, parentWidget(),
02075 QString::null );
02076
if ( url.isEmpty() ) {
02077 setResult( Canceled );
02078 emit completed(
this );
02079
delete this;
02080
return;
02081 }
02082 }
02083
02084 Result globalResult = OK;
02085
int unnamedAtmCount = 0;
02086
for ( PartNodeMessageMap::const_iterator it = mAttachmentMap.begin();
02087 it != mAttachmentMap.end();
02088 ++it ) {
02089 KURL curUrl;
02090
if ( !dirUrl.isEmpty() ) {
02091 curUrl = dirUrl;
02092
QString s =
02093 it.key()->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
02094
if ( s.isEmpty() )
02095 s = it.key()->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
02096
if ( s.isEmpty() ) {
02097 ++unnamedAtmCount;
02098 s = i18n(
"filename for the %1-th unnamed attachment",
02099
"attachment.%1")
02100 .arg( unnamedAtmCount );
02101 }
02102 curUrl.setFileName( s );
02103 }
else {
02104 curUrl = url;
02105 }
02106
02107
if ( !curUrl.isEmpty() ) {
02108
if ( KIO::NetAccess::exists( curUrl,
false, parentWidget() ) ) {
02109
if ( KMessageBox::warningContinueCancel( parentWidget(),
02110 i18n(
"A file named %1 already exists. Do you want to overwrite it?" )
02111 .arg( curUrl.fileName() ),
02112 i18n(
"File Already Exists" ), i18n(
"Overwrite") ) == KMessageBox::Cancel) {
02113
continue;
02114 }
02115 }
02116
02117
const Result result = saveItem( it.key(), curUrl );
02118
if ( result != OK )
02119 globalResult = result;
02120 }
02121 }
02122 setResult( globalResult );
02123 emit completed(
this );
02124
delete this;
02125 }
02126
02127 KMCommand::Result KMSaveAttachmentsCommand::saveItem( partNode *node,
02128
const KURL& url )
02129 {
02130
bool bSaveEncrypted =
false;
02131
bool bEncryptedParts = node->encryptionState() != KMMsgNotEncrypted;
02132
if( bEncryptedParts )
02133
if( KMessageBox::questionYesNo( parentWidget(),
02134 i18n(
"The part %1 of the message is encrypted. Do you want to keep the encryption when saving?" ).
02135 arg( url.fileName() ),
02136 i18n(
"KMail Question" ) ) ==
02137 KMessageBox::Yes )
02138 bSaveEncrypted =
true;
02139
02140
bool bSaveWithSig =
true;
02141
if( node->signatureState() != KMMsgNotSigned )
02142
if( KMessageBox::questionYesNo( parentWidget(),
02143 i18n(
"The part %1 of the message is signed. Do you want to keep the signature when saving?" ).
02144 arg( url.fileName() ),
02145 i18n(
"KMail Question" ) ) !=
02146 KMessageBox::Yes )
02147 bSaveWithSig =
false;
02148
02149
QByteArray data;
02150
if ( mEncoded )
02151 {
02152
02153
02154
QCString cstr( node->msgPart().body() );
02155 data = cstr;
02156 data.resize(data.size() - 1);
02157 }
02158
else
02159 {
02160
if( bSaveEncrypted || !bEncryptedParts) {
02161 partNode *dataNode = node;
02162
QCString rawReplyString;
02163
bool gotRawReplyString =
false;
02164
if( !bSaveWithSig ) {
02165
if( DwMime::kTypeMultipart == node->type() &&
02166 DwMime::kSubtypeSigned == node->subType() ){
02167
02168
if( node->findType( DwMime::kTypeApplication,
02169 DwMime::kSubtypePgpSignature,
02170 TRUE,
false ) ){
02171 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02172 DwMime::kSubtypePgpSignature,
02173 TRUE,
false );
02174 }
else if( node->findType( DwMime::kTypeApplication,
02175 DwMime::kSubtypePkcs7Mime,
02176 TRUE,
false ) ){
02177 dataNode = node->findTypeNot( DwMime::kTypeApplication,
02178 DwMime::kSubtypePkcs7Mime,
02179 TRUE,
false );
02180 }
else{
02181 dataNode = node->findTypeNot( DwMime::kTypeMultipart,
02182 DwMime::kSubtypeUnknown,
02183 TRUE,
false );
02184 }
02185 }
else{
02186 ObjectTreeParser otp( 0, 0,
false,
false,
false );
02187
02188
02189 dataNode->setProcessed(
false,
true );
02190 otp.parseObjectTree( dataNode );
02191
02192 rawReplyString = otp.rawReplyString();
02193 gotRawReplyString =
true;
02194 }
02195 }
02196
QByteArray cstr = gotRawReplyString
02197 ? rawReplyString
02198 : dataNode->msgPart().bodyDecodedBinary();
02199 data = cstr;
02200 size_t size = cstr.size();
02201
if ( dataNode->msgPart().type() == DwMime::kTypeText ) {
02202
02203 size =
KMFolder::crlf2lf( cstr.data(), size );
02204 }
02205 data.resize( size );
02206 }
02207 }
02208
QDataStream ds;
02209
QFile file;
02210 KTempFile tf;
02211 tf.setAutoDelete(
true );
02212
if ( url.isLocalFile() )
02213 {
02214
02215 file.setName( url.path() );
02216
if ( !file.open( IO_WriteOnly ) )
02217 {
02218 KMessageBox::error( parentWidget(),
02219 i18n(
"%2 is detailed error description",
02220
"Could not write the file %1:\n%2" )
02221 .arg( file.name() )
02222 .arg( QString::fromLocal8Bit( strerror( errno ) ) ),
02223 i18n(
"KMail Error" ) );
02224
return Failed;
02225 }
02226 fchmod( file.handle(), S_IRUSR | S_IWUSR );
02227 ds.setDevice( &file );
02228 }
else
02229 {
02230
02231 ds.setDevice( tf.file() );
02232 }
02233
02234 ds.writeRawBytes( data.data(), data.size() );
02235
if ( !url.isLocalFile() )
02236 {
02237 tf.close();
02238
if ( !KIO::NetAccess::upload( tf.name(), url, parentWidget() ) )
02239 {
02240 KMessageBox::error( parentWidget(),
02241 i18n(
"Could not write the file %1." )
02242 .arg( url.path() ),
02243 i18n(
"KMail Error" ) );
02244
return Failed;
02245 }
02246 }
else
02247 file.close();
02248
return OK;
02249 }
02250
02251 KMLoadPartsCommand::KMLoadPartsCommand(
QPtrList<partNode>& parts, KMMessage *msg )
02252 : mNeedsRetrieval( 0 )
02253 {
02254
for (
QPtrListIterator<partNode> it( parts ); it.current(); ++it ) {
02255 mPartMap.insert( it.current(), msg );
02256 }
02257 }
02258
02259 KMLoadPartsCommand::KMLoadPartsCommand( partNode *node, KMMessage *msg )
02260 : mNeedsRetrieval( 0 )
02261 {
02262 mPartMap.insert( node, msg );
02263 }
02264
02265 KMLoadPartsCommand::KMLoadPartsCommand(
PartNodeMessageMap& partMap )
02266 : mNeedsRetrieval( 0 ), mPartMap( partMap )
02267 {
02268 }
02269
02270
void KMLoadPartsCommand::slotStart()
02271 {
02272
for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02273 it != mPartMap.end();
02274 ++it ) {
02275
if ( !it.key()->msgPart().isComplete() &&
02276 !it.key()->msgPart().partSpecifier().isEmpty() ) {
02277
02278 ++mNeedsRetrieval;
02279
KMFolder* curFolder = it.data()->parent();
02280
if ( curFolder ) {
02281 FolderJob *job =
02282 curFolder->
createJob( it.data(), FolderJob::tGetMessage,
02283 0, it.key()->msgPart().partSpecifier() );
02284 job->setCancellable(
false );
02285 connect( job, SIGNAL(messageUpdated(KMMessage*,
QString)),
02286
this, SLOT(slotPartRetrieved(KMMessage*,
QString)) );
02287 job->start();
02288 }
else
02289 kdWarning(5006) <<
"KMLoadPartsCommand - msg has no parent" << endl;
02290 }
02291 }
02292
if ( mNeedsRetrieval == 0 )
02293 execute();
02294 }
02295
02296
void KMLoadPartsCommand::slotPartRetrieved( KMMessage *msg,
02297
QString partSpecifier )
02298 {
02299 DwBodyPart *part =
02300 msg->findDwBodyPart( msg->getFirstDwBodyPart(), partSpecifier );
02301
if ( part ) {
02302
02303
for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
02304 it != mPartMap.end();
02305 ++it ) {
02306
if ( it.key()->dwPart() == part )
02307 it.key()->setDwPart( part );
02308 }
02309 }
else
02310 kdWarning(5006) <<
"KMLoadPartsCommand::slotPartRetrieved - could not find bodypart!" << endl;
02311 --mNeedsRetrieval;
02312
if ( mNeedsRetrieval == 0 )
02313 execute();
02314 }
02315
02316 KMCommand::Result KMLoadPartsCommand::execute()
02317 {
02318 emit partsRetrieved();
02319 setResult( OK );
02320 emit completed(
this );
02321 deleteLater();
02322
return OK;
02323 }
02324
02325 KMResendMessageCommand::KMResendMessageCommand(
QWidget *parent,
02326 KMMessage *msg )
02327 :KMCommand( parent, msg )
02328 {
02329 }
02330
02331 KMCommand::Result KMResendMessageCommand::execute()
02332 {
02333 KMComposeWin *win;
02334 KMMessage *msg = retrievedMessage();
02335
02336 KMMessage *newMsg =
new KMMessage(*msg);
02337 newMsg->setCharset(msg->codec()->mimeName());
02338
02339 newMsg->removeHeaderField(
"Message-Id" );
02340 newMsg->setParent( 0 );
02341
02342
02343 newMsg->removeHeaderField(
"Date" );
02344
02345 win =
new KMComposeWin();
02346 win->setMsg(newMsg,
false,
true);
02347 win->show();
02348
02349
return OK;
02350 }
02351
02352 KMMailingListCommand::KMMailingListCommand(
QWidget *parent,
KMFolder *folder )
02353 : KMCommand( parent ), mFolder( folder )
02354 {
02355 }
02356
02357 KMCommand::Result KMMailingListCommand::execute()
02358 {
02359 KURL::List lst = urls();
02360
QString handler = ( mFolder->mailingList().handler() == MailingList::KMail )
02361 ?
"mailto" :
"https";
02362
02363 KMCommand *command = 0;
02364
for ( KURL::List::Iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
02365
if ( handler == (*itr).protocol() ) {
02366 command =
new KMUrlClickedCommand( *itr, mFolder->identity(), 0,
false );
02367 }
02368 }
02369
if ( !command && !lst.empty() ) {
02370 command =
02371
new KMUrlClickedCommand( lst.first(), mFolder->identity(), 0,
false );
02372 }
02373
if ( command ) {
02374 connect( command, SIGNAL( completed( KMCommand * ) ),
02375
this, SLOT( commandCompleted( KMCommand * ) ) );
02376 setDeletesItself(
true );
02377 setEmitsCompletedItself(
true );
02378 command->start();
02379
return OK;
02380 }
02381
return Failed;
02382 }
02383
02384
void KMMailingListCommand::commandCompleted( KMCommand *command )
02385 {
02386 setResult( command->result() );
02387 emit completed(
this );
02388
delete this;
02389 }
02390
02391 KMMailingListPostCommand::KMMailingListPostCommand(
QWidget *parent,
KMFolder *folder )
02392 : KMMailingListCommand( parent, folder )
02393 {
02394 }
02395 KURL::List KMMailingListPostCommand::urls()
const
02396
{
02397
return mFolder->mailingList().postURLS();
02398 }
02399
02400 KMMailingListSubscribeCommand::KMMailingListSubscribeCommand(
QWidget *parent,
KMFolder *folder )
02401 : KMMailingListCommand( parent, folder )
02402 {
02403 }
02404 KURL::List KMMailingListSubscribeCommand::urls()
const
02405
{
02406
return mFolder->mailingList().subscribeURLS();
02407 }
02408
02409 KMMailingListUnsubscribeCommand::KMMailingListUnsubscribeCommand(
QWidget *parent,
KMFolder *folder )
02410 : KMMailingListCommand( parent, folder )
02411 {
02412 }
02413 KURL::List KMMailingListUnsubscribeCommand::urls()
const
02414
{
02415
return mFolder->mailingList().unsubscribeURLS();
02416 }
02417
02418 KMMailingListArchivesCommand::KMMailingListArchivesCommand(
QWidget *parent,
KMFolder *folder )
02419 : KMMailingListCommand( parent, folder )
02420 {
02421 }
02422 KURL::List KMMailingListArchivesCommand::urls()
const
02423
{
02424
return mFolder->mailingList().archiveURLS();
02425 }
02426
02427 KMMailingListHelpCommand::KMMailingListHelpCommand(
QWidget *parent,
KMFolder *folder )
02428 : KMMailingListCommand( parent, folder )
02429 {
02430 }
02431 KURL::List KMMailingListHelpCommand::urls()
const
02432
{
02433
return mFolder->mailingList().helpURLS();
02434 }
02435
02436 KMIMChatCommand::KMIMChatCommand(
const KURL &url, KMMessage *msg )
02437 :mUrl( url ), mMessage( msg )
02438 {
02439 }
02440
02441 KMCommand::Result KMIMChatCommand::execute()
02442 {
02443 kdDebug( 5006 ) << k_funcinfo <<
" URL is: " << mUrl << endl;
02444
02445 KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
02446 KABC::AddresseeList addresses = addressBook->findByEmail( KPIM::getEmailAddr( mUrl.path() ) ) ;
02447
02448
02449
if( addresses.count() == 1 ) {
02450 kmkernel->imProxy()->chatWithContact( addresses[0].uid() );
02451
return OK;
02452 }
02453
else
02454 {
02455 kdDebug( 5006 ) <<
"Didn't find exactly one addressee, couldn't tell who to chat to for that email address. Count = " << addresses.count() << endl;
02456
02457
QString apology;
02458
if ( addresses.isEmpty() )
02459 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." );
02460
else
02461 {
02462 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." );
02463
QStringList nameList;
02464 KABC::AddresseeList::const_iterator it = addresses.begin();
02465 KABC::AddresseeList::const_iterator end = addresses.end();
02466
for ( ; it != end; ++it )
02467 {
02468 nameList.append( (*it).realName() );
02469 }
02470
QString names = nameList.join( QString::fromLatin1(
",\n" ) );
02471 apology = apology.arg( names );
02472 }
02473
02474 KMessageBox::sorry( parentWidget(), apology );
02475
return Failed;
02476 }
02477 }