43 #include "kmcommands.h"
50 #include <mimelib/enum.h>
51 #include <mimelib/field.h>
52 #include <mimelib/mimepp.h>
53 #include <mimelib/string.h>
54 #include <kapplication.h>
55 #include <dcopclient.h>
57 #include <tqtextcodec.h>
58 #include <tqpopupmenu.h>
59 #include <tqeventloop.h>
61 #include <libemailfunctions/email.h>
62 #include <kdcopservicestarter.h>
64 #include <kfiledialog.h>
65 #include <kabc/stdaddressbook.h>
66 #include <kabc/addresseelist.h>
67 #include <kdirselectdialog.h>
69 #include <kmessagebox.h>
70 #include <kparts/browserextension.h>
71 #include <kprogress.h>
73 #include <kbookmarkmanager.h>
74 #include <kstandarddirs.h>
75 #include <ktempfile.h>
77 #include <kuserprofile.h>
80 #include <kio/netaccess.h>
82 #include <libkpimidentities/identitymanager.h>
84 #include "actionscheduler.h"
85 using KMail::ActionScheduler;
86 #include "mailinglist-magic.h"
87 #include "kmaddrbook.h"
88 #include <kaddrbook.h>
90 #include "kmfiltermgr.h"
91 #include "kmfoldermbox.h"
92 #include "kmfolderimap.h"
93 #include "kmfoldermgr.h"
94 #include "kmheaders.h"
95 #include "headeritem.h"
96 #include "kmmainwidget.h"
97 #include "kmmsgdict.h"
98 #include "messagesender.h"
99 #include "kmmsgpartdlg.h"
100 #include "undostack.h"
101 #include "kcursorsaver.h"
102 #include "partNode.h"
103 #include "objecttreeparser.h"
104 #include "csshelper.h"
105 using KMail::ObjectTreeParser;
106 using KMail::FolderJob;
107 #include "chiasmuskeyselector.h"
108 #include "mailsourceviewer.h"
109 using KMail::MailSourceViewer;
110 #include "kmreadermainwin.h"
111 #include "secondarywindow.h"
113 #include "redirectdialog.h"
116 #include "templateparser.h"
117 #include "editorwatcher.h"
118 #include "korghelper.h"
120 #include "broadcaststatus.h"
121 #include "globalsettings.h"
123 #include <libkdepim/kfileio.h>
124 #include "kcalendariface_stub.h"
126 #include "progressmanager.h"
127 using KPIM::ProgressManager;
128 using KPIM::ProgressItem;
129 #include <kmime_mdn.h>
130 using namespace KMime;
132 #include <kleo/specialjob.h>
133 #include <kleo/cryptobackend.h>
134 #include <kleo/cryptobackendfactory.h>
136 #include <tqclipboard.h>
143 LaterDeleterWithCommandCompletion( KMCommand* command )
144 :LaterDeleter( command ), m_result( KMCommand::Failed )
147 ~LaterDeleterWithCommandCompletion()
149 setResult( m_result );
150 KMCommand *command =
static_cast<KMCommand*
>( m_object );
151 emit command->completed( command );
153 void setResult( KMCommand::Result v ) { m_result = v; }
155 KMCommand::Result m_result;
159 KMCommand::KMCommand( TQWidget *parent )
160 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
161 mEmitsCompletedItself( false ), mParent( parent )
165 KMCommand::KMCommand( TQWidget *parent,
const TQPtrList<KMMsgBase> &msgList )
166 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
167 mEmitsCompletedItself( false ), mParent( parent ), mMsgList( msgList )
171 KMCommand::KMCommand( TQWidget *parent, KMMsgBase *msgBase )
172 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
173 mEmitsCompletedItself( false ), mParent( parent )
175 mMsgList.append( msgBase );
178 KMCommand::KMCommand( TQWidget *parent,
KMMessage *msg )
179 : mProgressDialog( 0 ), mResult( Undefined ), mDeletesItself( false ),
180 mEmitsCompletedItself( false ), mParent( parent )
186 KMCommand::~KMCommand()
188 TQValueListIterator<TQGuardedPtr<KMFolder> > fit;
189 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
192 (*fit)->close(
"kmcommand");
196 KMCommand::Result KMCommand::result()
198 if ( mResult == Undefined )
199 kdDebug(5006) << k_funcinfo <<
"mResult is Undefined" << endl;
203 void KMCommand::start()
205 TQTimer::singleShot( 0,
this, TQT_SLOT( slotStart() ) );
209 const TQPtrList<KMMessage> KMCommand::retrievedMsgs()
const
211 return mRetrievedMsgs;
214 KMMessage *KMCommand::retrievedMessage()
const
216 return mRetrievedMsgs.getFirst();
219 TQWidget *KMCommand::parentWidget()
const
224 int KMCommand::mCountJobs = 0;
226 void KMCommand::slotStart()
228 connect(
this, TQT_SIGNAL( messagesTransfered( KMCommand::Result ) ),
229 this, TQT_SLOT( slotPostTransfer( KMCommand::Result ) ) );
230 kmkernel->filterMgr()->ref();
232 if (mMsgList.find(0) != -1) {
233 emit messagesTransfered( Failed );
237 if ((mMsgList.count() == 1) &&
238 (mMsgList.getFirst()->isMessage()) &&
239 (mMsgList.getFirst()->parent() == 0))
242 mRetrievedMsgs.append((
KMMessage*)mMsgList.getFirst());
243 emit messagesTransfered( OK );
247 for ( KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next() ) {
249 if ( !mb->parent() ) {
250 emit messagesTransfered( Failed );
253 keepFolderOpen( mb->parent() );
259 transferSelectedMsgs();
262 void KMCommand::slotPostTransfer( KMCommand::Result result )
264 disconnect(
this, TQT_SIGNAL( messagesTransfered( KMCommand::Result ) ),
265 this, TQT_SLOT( slotPostTransfer( KMCommand::Result ) ) );
269 TQPtrListIterator<KMMessage> it( mRetrievedMsgs );
271 while ( (msg = it.current()) != 0 )
277 kmkernel->filterMgr()->deref();
278 if ( !emitsCompletedItself() )
279 emit completed(
this );
280 if ( !deletesItself() )
284 void KMCommand::transferSelectedMsgs()
287 if (KMCommand::mCountJobs > 0) {
288 emit messagesTransfered( Failed );
292 bool complete =
true;
293 KMCommand::mCountJobs = 0;
295 mRetrievedMsgs.clear();
296 mCountMsgs = mMsgList.count();
302 if ( mCountMsgs > 0 ) {
303 mProgressDialog =
new KProgressDialog(mParent,
"transferProgress",
305 i18n(
"Please wait while the message is transferred",
306 "Please wait while the %n messages are transferred", mMsgList.count()),
308 mProgressDialog->setMinimumDuration(1000);
310 for (KMMsgBase *mb = mMsgList.first(); mb; mb = mMsgList.next())
314 if ( mb->isMessage() )
315 thisMsg = static_cast<KMMessage*>(mb);
319 int idx = folder->
find(mb);
320 if (idx < 0)
continue;
321 thisMsg = folder->
getMsg(idx);
323 if (!thisMsg)
continue;
325 thisMsg->parent()->folderType() == KMFolderTypeImap )
328 thisMsg->parent()->ignoreJobsForMessage( thisMsg );
331 if ( thisMsg->parent() && !thisMsg->
isComplete() &&
332 ( !mProgressDialog || !mProgressDialog->wasCancelled() ) )
334 kdDebug(5006)<<
"### INCOMPLETE\n";
337 KMCommand::mCountJobs++;
338 FolderJob *job = thisMsg->parent()->createJob(thisMsg);
339 job->setCancellable(
false );
342 connect(job, TQT_SIGNAL(messageRetrieved(
KMMessage*)),
343 this, TQT_SLOT(slotMsgTransfered(
KMMessage*)));
345 connect(job, TQT_SIGNAL(finished()),
346 this, TQT_SLOT(slotJobFinished()));
347 connect(job, TQT_SIGNAL(progress(
unsigned long,
unsigned long)),
348 this, TQT_SLOT(slotProgress(
unsigned long,
unsigned long)));
354 mRetrievedMsgs.append(thisMsg);
360 delete mProgressDialog;
362 emit messagesTransfered( OK );
365 if ( mProgressDialog ) {
366 connect(mProgressDialog, TQT_SIGNAL(cancelClicked()),
367 this, TQT_SLOT(slotTransferCancelled()));
368 mProgressDialog->progressBar()->setTotalSteps(totalSize);
373 void KMCommand::slotMsgTransfered(
KMMessage* msg)
375 if ( mProgressDialog && mProgressDialog->wasCancelled() ) {
376 emit messagesTransfered( Canceled );
381 mRetrievedMsgs.append(msg);
384 void KMCommand::slotProgress(
unsigned long done,
unsigned long )
386 mProgressDialog->progressBar()->setProgress( done );
389 void KMCommand::slotJobFinished()
392 KMCommand::mCountJobs--;
394 if ( mProgressDialog && mProgressDialog->wasCancelled() )
return;
396 if ( (mCountMsgs - static_cast<int>(mRetrievedMsgs.count())) > KMCommand::mCountJobs )
399 if ( mProgressDialog )
400 mProgressDialog->hide();
401 slotTransferCancelled();
405 if ( mProgressDialog ) {
406 mProgressDialog->setLabel(i18n(
"Please wait while the message is transferred",
407 "Please wait while the %n messages are transferred", KMCommand::mCountJobs));
409 if (KMCommand::mCountJobs == 0)
412 delete mProgressDialog;
414 emit messagesTransfered( OK );
418 void KMCommand::slotTransferCancelled()
421 TQValueListIterator<TQGuardedPtr<KMFolder> > fit;
422 for ( fit = mFolders.begin(); fit != mFolders.end(); ++fit ) {
426 KMFolderImap *imapFolder =
dynamic_cast<KMFolderImap*
>(folder);
427 if (imapFolder && imapFolder->account()) {
428 imapFolder->account()->killAllJobs();
432 KMCommand::mCountJobs = 0;
435 TQPtrListIterator<KMMessage> it( mRetrievedMsgs );
437 while ( (msg = it.current()) != 0 )
444 int idx = folder->
find(msg);
447 mRetrievedMsgs.clear();
448 emit messagesTransfered( Canceled );
451 void KMCommand::keepFolderOpen(
KMFolder *folder )
453 folder->
open(
"kmcommand" );
454 mFolders.append( folder );
457 KMMailtoComposeCommand::KMMailtoComposeCommand(
const KURL &url,
459 :mUrl( url ), mMessage( msg )
463 KMCommand::Result KMMailtoComposeCommand::execute()
468 if ( mMessage && mMessage->parent() )
469 id = mMessage->parent()->identity();
475 KMail::Composer * win = KMail::makeComposer( msg,
id );
476 win->setCharset(
"",
true);
477 win->setFocusToSubject();
484 KMMailtoReplyCommand::KMMailtoReplyCommand( TQWidget *parent,
485 const KURL &url,
KMMessage *msg,
const TQString &selection )
486 :KMCommand( parent, msg ), mUrl( url ), mSelection( selection )
490 KMCommand::Result KMMailtoReplyCommand::execute()
494 if ( !msg || !msg->
codec() ) {
500 KMail::Composer * win = KMail::makeComposer( rmsg, 0 );
501 win->setCharset(msg->
codec()->mimeName(),
true);
502 win->setReplyFocus();
509 KMMailtoForwardCommand::KMMailtoForwardCommand( TQWidget *parent,
511 :KMCommand( parent, msg ), mUrl( url )
515 KMCommand::Result KMMailtoForwardCommand::execute()
519 if ( !msg || !msg->
codec() ) {
525 KMail::Composer * win = KMail::makeComposer( fmsg );
526 win->setCharset(msg->
codec()->mimeName(),
true);
533 KMAddBookmarksCommand::KMAddBookmarksCommand(
const KURL &url, TQWidget *parent )
534 : KMCommand( parent ), mUrl( url )
538 KMCommand::Result KMAddBookmarksCommand::execute()
540 TQString filename = locateLocal(
"data", TQString::fromLatin1(
"konqueror/bookmarks.xml") );
541 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename,
543 KBookmarkGroup group = bookManager->root();
544 group.addBookmark( bookManager, mUrl.path(), KURL( mUrl ) );
545 if( bookManager->save() ) {
546 bookManager->emitChanged( group );
552 KMMailtoAddAddrBookCommand::KMMailtoAddAddrBookCommand(
const KURL &url,
554 : KMCommand( parent ), mUrl( url )
558 KMCommand::Result KMMailtoAddAddrBookCommand::execute()
567 KMMailtoOpenAddrBookCommand::KMMailtoOpenAddrBookCommand(
const KURL &url,
569 : KMCommand( parent ), mUrl( url )
573 KMCommand::Result KMMailtoOpenAddrBookCommand::execute()
582 KMUrlCopyCommand::KMUrlCopyCommand(
const KURL &url, KMMainWidget *mainWidget )
583 :mUrl( url ), mMainWidget( mainWidget )
587 KMCommand::Result KMUrlCopyCommand::execute()
589 TQClipboard* clip = TQApplication::clipboard();
591 if (mUrl.protocol() ==
"mailto") {
594 clip->setSelectionMode(
true );
595 clip->setText( address );
596 clip->setSelectionMode(
false );
597 clip->setText( address );
598 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n(
"Address copied to clipboard." ));
601 clip->setSelectionMode(
true );
602 clip->setText( mUrl.url() );
603 clip->setSelectionMode(
false );
604 clip->setText( mUrl.url() );
605 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n(
"URL copied to clipboard." ));
612 KMUrlOpenCommand::KMUrlOpenCommand(
const KURL &url,
KMReaderWin *readerWin )
613 :mUrl( url ), mReaderWin( readerWin )
617 KMCommand::Result KMUrlOpenCommand::execute()
619 if ( !mUrl.isEmpty() )
620 mReaderWin->slotUrlOpen( mUrl, KParts::URLArgs() );
626 KMUrlSaveCommand::KMUrlSaveCommand(
const KURL &url, TQWidget *parent )
627 : KMCommand( parent ), mUrl( url )
631 KMCommand::Result KMUrlSaveCommand::execute()
633 if ( mUrl.isEmpty() )
635 KURL saveUrl = KFileDialog::getSaveURL(mUrl.fileName(), TQString(),
637 if ( saveUrl.isEmpty() )
639 if ( KIO::NetAccess::exists( saveUrl,
false, parentWidget() ) )
641 if (KMessageBox::warningContinueCancel(0,
642 i18n(
"<qt>File <b>%1</b> exists.<br>Do you want to replace it?</qt>")
643 .arg(saveUrl.prettyURL()), i18n(
"Save to File"), i18n(
"&Replace"))
644 != KMessageBox::Continue)
647 KIO::Job *job = KIO::file_copy(mUrl, saveUrl, -1,
true);
648 connect(job, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(slotUrlSaveResult(KIO::Job*)));
649 setEmitsCompletedItself(
true );
653 void KMUrlSaveCommand::slotUrlSaveResult( KIO::Job *job )
655 if ( job->error() ) {
656 job->showErrorDialog();
658 emit completed(
this );
662 emit completed(
this );
667 KMEditMsgCommand::KMEditMsgCommand( TQWidget *parent,
KMMessage *msg )
668 :KMCommand( parent, msg )
672 KMCommand::Result KMEditMsgCommand::execute()
675 if ( !msg || !msg->parent() ||
676 ( !kmkernel->folderIsDraftOrOutbox( msg->parent() ) &&
677 !kmkernel->folderIsTemplates( msg->parent() ) ) )
685 parent->
take( parent->
find( msg ) );
687 KMail::Composer * win = KMail::makeComposer();
689 win->setMsg(msg,
false,
true);
690 win->setFolder( parent );
696 KMUseTemplateCommand::KMUseTemplateCommand( TQWidget *parent,
KMMessage *msg )
697 :KMCommand( parent, msg )
701 KMCommand::Result KMUseTemplateCommand::execute()
704 if ( !msg || !msg->parent() ||
705 !kmkernel->folderIsTemplates( msg->parent() ) )
716 KMail::Composer *win = KMail::makeComposer();
718 win->setMsg( newMsg,
false,
true );
724 KMShowMsgSrcCommand::KMShowMsgSrcCommand( TQWidget *parent,
726 :KMCommand( parent, msg ), mFixedFont( fixedFont )
732 KMCommand::Result KMShowMsgSrcCommand::execute()
735 if ( !msg || !msg->
codec() ) {
742 MailSourceViewer *viewer =
new MailSourceViewer();
743 viewer->setCaption( i18n(
"Message as Plain Text") );
744 viewer->setText(str);
746 viewer->setFont(KGlobalSettings::fixedFont());
751 if (TQApplication::desktop()->isVirtualDesktop()) {
752 int scnum = TQApplication::desktop()->screenNumber(TQCursor::pos());
753 viewer->resize(TQApplication::desktop()->screenGeometry(scnum).width()/2,
754 2*TQApplication::desktop()->screenGeometry(scnum).height()/3);
756 viewer->resize(TQApplication::desktop()->geometry().width()/2,
757 2*TQApplication::desktop()->geometry().height()/3);
764 static KURL subjectToUrl(
const TQString & subject )
775 const TQString filter = i18n(
"*.mbox|email messages (*.mbox)\n*|all files (*)" );
776 TQString cleanSubject = subject.stripWhiteSpace()
777 .replace( TQDir::separator(),
'_' )
778 .replace(
": ",
"_" )
781 .replace(
'~',
'_' );
782 return KFileDialog::getSaveURL( cleanSubject, filter );
785 KMSaveMsgCommand::KMSaveMsgCommand( TQWidget *parent,
KMMessage * msg )
786 : KMCommand( parent ),
788 mStandAloneMessage( 0 ),
790 mTotalSize( msg ? msg->msgSize() : 0 )
793 setDeletesItself(
true );
798 if ( msg->getMsgSerNum() != 0 ) {
799 mMsgList.append( msg->getMsgSerNum() );
800 if ( msg->parent() ) {
801 msg->parent()->open(
"kmsavemsgcommand" );
804 mStandAloneMessage = msg;
806 mUrl = subjectToUrl( msg->cleanSubject() );
809 KMSaveMsgCommand::KMSaveMsgCommand( TQWidget *parent,
810 const TQPtrList<KMMsgBase> &msgList )
811 : KMCommand( parent ),
813 mStandAloneMessage( 0 ),
817 if (!msgList.getFirst())
819 setDeletesItself(
true );
820 KMMsgBase *msgBase = msgList.getFirst();
825 TQPtrListIterator<KMMsgBase> it(msgList);
826 while ( it.current() ) {
827 mMsgList.append( (*it)->getMsgSerNum() );
828 mTotalSize += (*it)->msgSize();
829 if ((*it)->parent() != 0)
830 (*it)->parent()->open(
"kmcommand");
834 mUrl = subjectToUrl( msgBase->cleanSubject() );
837 KURL KMSaveMsgCommand::url()
842 KMCommand::Result KMSaveMsgCommand::execute()
844 mJob = KIO::put( mUrl, S_IRUSR|S_IWUSR,
false,
false );
845 mJob->slotTotalSize( mTotalSize );
846 mJob->setAsyncDataEnabled(
true );
847 mJob->setReportDataSent(
true );
848 connect(mJob, TQT_SIGNAL(dataReq(KIO::Job*, TQByteArray &)),
849 TQT_SLOT(slotSaveDataReq()));
850 connect(mJob, TQT_SIGNAL(result(KIO::Job*)),
851 TQT_SLOT(slotSaveResult(KIO::Job*)));
852 setEmitsCompletedItself(
true );
856 void KMSaveMsgCommand::slotSaveDataReq()
858 int remainingBytes = mData.size() - mOffset;
859 if ( remainingBytes > 0 ) {
861 if ( remainingBytes > MAX_CHUNK_SIZE )
862 remainingBytes = MAX_CHUNK_SIZE;
865 data.duplicate( mData.data() + mOffset, remainingBytes );
866 mJob->sendAsyncData( data );
867 mOffset += remainingBytes;
871 if ( mMsgListIndex < mMsgList.size() ) {
880 const bool alreadyGot = p->
isMessage( idx );
887 mUngetMsgs.append( msg );
890 TQByteArray data = TQByteArray();
891 mJob->sendAsyncData( data );
895 slotMessageRetrievedForSaving( msg );
899 FolderJob *job = msg->parent()->createJob( msg );
900 job->setCancellable(
false );
901 connect(job, TQT_SIGNAL( messageRetrieved(
KMMessage* ) ),
902 this, TQT_SLOT( slotMessageRetrievedForSaving(
KMMessage* ) ) );
907 mJob->slotError( KIO::ERR_ABORTED,
908 i18n(
"The message was removed while saving it. "
909 "It has not been saved.") );
912 if ( mStandAloneMessage ) {
914 slotMessageRetrievedForSaving( mStandAloneMessage );
915 mStandAloneMessage = 0;
918 TQByteArray data = TQByteArray();
919 mJob->sendAsyncData( data );
924 void KMSaveMsgCommand::slotMessageRetrievedForSaving(
KMMessage *msg)
927 mData = KMFolderMbox::escapeFrom( msg->
asDwString() );
936 if( mData.size() > (
unsigned int) MAX_CHUNK_SIZE )
937 size = MAX_CHUNK_SIZE;
941 data.duplicate( mData, size );
942 mJob->sendAsyncData( data );
947 if ( msg && msg->parent() && msg->getMsgSerNum() &&
948 mUngetMsgs.contains( msg ) ) {
952 assert( p == msg->parent() ); assert( idx >= 0 );
954 p->
close(
"kmcommand");
958 void KMSaveMsgCommand::slotSaveResult(KIO::Job *job)
962 if (job->error() == KIO::ERR_FILE_ALREADY_EXIST)
964 if (KMessageBox::warningContinueCancel(0,
965 i18n(
"File %1 exists.\nDo you want to replace it?")
966 .arg(mUrl.prettyURL()), i18n(
"Save to File"), i18n(
"&Replace"))
967 == KMessageBox::Continue) {
970 mJob = KIO::put( mUrl, S_IRUSR|S_IWUSR,
true,
false );
971 mJob->slotTotalSize( mTotalSize );
972 mJob->setAsyncDataEnabled(
true );
973 mJob->setReportDataSent(
true );
974 connect(mJob, TQT_SIGNAL(dataReq(KIO::Job*, TQByteArray &)),
975 TQT_SLOT(slotSaveDataReq()));
976 connect(mJob, TQT_SIGNAL(result(KIO::Job*)),
977 TQT_SLOT(slotSaveResult(KIO::Job*)));
982 job->showErrorDialog();
984 emit completed(
this );
989 emit completed(
this );
996 KMOpenMsgCommand::KMOpenMsgCommand( TQWidget *parent,
const KURL & url,
997 const TQString & encoding )
998 : KMCommand( parent ),
1000 mEncoding( encoding )
1002 setDeletesItself(
true );
1005 KMCommand::Result KMOpenMsgCommand::execute()
1007 if ( mUrl.isEmpty() ) {
1008 mUrl = KFileDialog::getOpenURL(
":OpenMessage",
"message/rfc822 application/mbox",
1009 parentWidget(), i18n(
"Open Message") );
1011 if ( mUrl.isEmpty() ) {
1012 setDeletesItself(
false );
1015 mJob = KIO::get( mUrl,
false,
false );
1016 mJob->setReportDataSent(
true );
1017 connect( mJob, TQT_SIGNAL( data( KIO::Job *,
const TQByteArray & ) ),
1018 this, TQT_SLOT( slotDataArrived( KIO::Job*,
const TQByteArray & ) ) );
1019 connect( mJob, TQT_SIGNAL( result( KIO::Job * ) ),
1020 TQT_SLOT( slotResult( KIO::Job * ) ) );
1021 setEmitsCompletedItself(
true );
1025 void KMOpenMsgCommand::slotDataArrived( KIO::Job *,
const TQByteArray & data )
1027 if ( data.isEmpty() )
1030 mMsgString.append( data.data(), data.size() );
1033 void KMOpenMsgCommand::slotResult( KIO::Job *job )
1035 if ( job->error() ) {
1037 job->showErrorDialog();
1038 setResult( Failed );
1039 emit completed(
this );
1042 int startOfMessage = 0;
1043 if ( mMsgString.compare( 0, 5,
"From ", 5 ) == 0 ) {
1044 startOfMessage = mMsgString.find(
'\n' );
1045 if ( startOfMessage == -1 ) {
1046 KMessageBox::sorry( parentWidget(),
1047 i18n(
"The file does not contain a message." ) );
1048 setResult( Failed );
1049 emit completed(
this );
1059 startOfMessage += 1;
1062 bool multipleMessages =
true;
1063 int endOfMessage = mMsgString.find(
"\nFrom " );
1064 if ( endOfMessage == -1 ) {
1065 endOfMessage = mMsgString.length();
1066 multipleMessages =
false;
1068 DwMessage *dwMsg =
new DwMessage;
1069 dwMsg->FromString( mMsgString.substr( startOfMessage,
1070 endOfMessage - startOfMessage ) );
1073 if ( dwMsg->Headers().NumFields() == 0 ) {
1074 KMessageBox::sorry( parentWidget(),
1075 i18n(
"The file does not contain a message." ) );
1076 delete dwMsg; dwMsg = 0;
1077 setResult( Failed );
1078 emit completed(
this );
1088 KMReaderMainWin *win =
new KMReaderMainWin();
1089 win->showMsg( mEncoding, msg );
1091 if ( multipleMessages )
1092 KMessageBox::information( win,
1093 i18n(
"The file contains multiple messages. "
1094 "Only the first message is shown." ) );
1096 emit completed(
this );
1105 KMReplyToCommand::KMReplyToCommand( TQWidget *parent,
KMMessage *msg,
1106 const TQString &selection )
1107 : KMCommand( parent, msg ), mSelection( selection )
1111 KMCommand::Result KMReplyToCommand::execute()
1115 if ( !msg || !msg->
codec() ) {
1119 KMail::Composer * win = KMail::makeComposer( reply );
1120 win->setCharset( msg->
codec()->mimeName(), true );
1121 win->setReplyFocus();
1128 KMNoQuoteReplyToCommand::KMNoQuoteReplyToCommand( TQWidget *parent,
1130 : KMCommand( parent, msg )
1134 KMCommand::Result KMNoQuoteReplyToCommand::execute()
1138 if ( !msg || !msg->
codec() ) {
1142 KMail::Composer * win = KMail::makeComposer( reply );
1143 win->setCharset(msg->
codec()->mimeName(),
true);
1144 win->setReplyFocus(
false);
1151 KMReplyListCommand::KMReplyListCommand( TQWidget *parent,
1152 KMMessage *msg,
const TQString &selection )
1153 : KMCommand( parent, msg ), mSelection( selection )
1157 KMCommand::Result KMReplyListCommand::execute()
1161 if ( !msg || !msg->
codec() ) {
1165 KMail::Composer * win = KMail::makeComposer( reply );
1166 win->setCharset(msg->
codec()->mimeName(),
true);
1167 win->setReplyFocus(
false);
1174 KMReplyToAllCommand::KMReplyToAllCommand( TQWidget *parent,
1175 KMMessage *msg,
const TQString &selection )
1176 :KMCommand( parent, msg ), mSelection( selection )
1180 KMCommand::Result KMReplyToAllCommand::execute()
1184 if ( !msg || !msg->
codec() ) {
1188 KMail::Composer * win = KMail::makeComposer( reply );
1189 win->setCharset( msg->
codec()->mimeName(), true );
1190 win->setReplyFocus();
1197 KMReplyAuthorCommand::KMReplyAuthorCommand( TQWidget *parent,
KMMessage *msg,
1198 const TQString &selection )
1199 : KMCommand( parent, msg ), mSelection( selection )
1203 KMCommand::Result KMReplyAuthorCommand::execute()
1207 if ( !msg || !msg->
codec() ) {
1211 KMail::Composer * win = KMail::makeComposer( reply );
1212 win->setCharset( msg->
codec()->mimeName(), true );
1213 win->setReplyFocus();
1220 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
1221 const TQPtrList<KMMsgBase> &msgList, uint identity )
1222 : KMCommand( parent, msgList ),
1223 mIdentity( identity )
1227 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
1229 : KMCommand( parent, msg ),
1230 mIdentity( identity )
1234 KMCommand::Result KMForwardInlineCommand::execute()
1236 TQPtrList<KMMessage> msgList = retrievedMsgs();
1238 if (msgList.count() >= 2) {
1241 TQPtrList<KMMessage> linklist;
1242 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1245 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1248 linklist.append( msg );
1258 for (
KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
1260 parser.setSelection( msg->
body() );
1261 parser.process( msg, 0,
true );
1263 fwdMsg->
link( msg, KMMsgStatusForwarded );
1267 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1268 win->setCharset(
"");
1274 if ( !msg || !msg->
codec() )
1280 uint
id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1284 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1285 win->setCharset( fwdMsg->
codec()->mimeName(), true );
1293 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
1294 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
1295 : KMCommand( parent, msgList ), mIdentity( identity ),
1296 mWin( TQGuardedPtr<KMail::Composer>( win ))
1300 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
1301 KMMessage * msg, uint identity, KMail::Composer *win )
1302 : KMCommand( parent, msg ), mIdentity( identity ),
1303 mWin( TQGuardedPtr< KMail::Composer >( win ))
1307 KMCommand::Result KMForwardAttachedCommand::execute()
1309 TQPtrList<KMMessage> msgList = retrievedMsgs();
1312 if (msgList.count() >= 2) {
1317 else if (msgList.count() == 1) {
1320 fwdMsg->setSubject( msg->forwardSubject() );
1327 mWin = KMail::makeComposer(fwdMsg, mIdentity);
1330 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
1335 KMMessagePart *msgPart =
new KMMessagePart;
1336 msgPart->setTypeStr(
"message");
1337 msgPart->setSubtypeStr(
"rfc822");
1338 msgPart->setCharset(msg->
charset());
1339 msgPart->setName(
"forwarded message");
1340 msgPart->setContentDescription(msg->
from()+
": "+msg->
subject());
1341 msgPart->setContentDisposition(
"inline" );
1344 msgPart->setCharset(
"");
1346 fwdMsg->
link(msg, KMMsgStatusForwarded);
1347 mWin->addAttach(msgPart);
1356 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
1357 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
1358 : KMCommand( parent, msgList ), mIdentity( identity ),
1359 mWin( TQGuardedPtr<KMail::Composer>( win ))
1363 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
1364 KMMessage * msg, uint identity, KMail::Composer *win )
1365 : KMCommand( parent, msg ), mIdentity( identity ),
1366 mWin( TQGuardedPtr< KMail::Composer >( win ))
1370 KMCommand::Result KMForwardDigestCommand::execute()
1372 TQPtrList<KMMessage> msgList = retrievedMsgs();
1374 if ( msgList.count() < 2 )
1379 KMMessagePart *msgPart =
new KMMessagePart;
1380 TQString msgPartText;
1387 fwdMsg->mMsg->Headers().ContentType().CreateBoundary( 1 );
1388 TQCString boundary( fwdMsg->mMsg->Headers().ContentType().Boundary().c_str() );
1389 msgPartText = i18n(
"\nThis is a MIME digest forward. The content of the"
1390 " message is contained in the attachment(s).\n\n\n");
1392 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1395 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1397 msgPartText +=
"--";
1398 msgPartText += TQString::fromLatin1( boundary );
1399 msgPartText +=
"\nContent-Type: MESSAGE/RFC822";
1400 msgPartText += TQString(
"; CHARSET=%1" ).arg( TQString(msg->
charset()) );
1401 msgPartText +=
'\n';
1403 dwh.MessageId().CreateDefault();
1404 msgPartText += TQString(
"Content-ID: %1\n" ).arg( dwh.MessageId().AsString().c_str() );
1405 msgPartText += TQString(
"Content-Description: %1" ).arg( msg->
subject() );
1406 if ( !msg->
subject().contains(
"(fwd)" ) )
1407 msgPartText +=
" (fwd)";
1408 msgPartText +=
"\n\n";
1414 msgPartText +=
'\n';
1415 msgPartText += msg->
body();
1416 msgPartText +=
'\n';
1418 fwdMsg->
link( msg, KMMsgStatusForwarded );
1424 msgPartText +=
"--";
1425 msgPartText += TQString::fromLatin1( boundary );
1426 msgPartText +=
"--\n";
1428 msgPart->setTypeStr(
"MULTIPART" );
1429 tmp.sprintf(
"Digest; boundary=\"%s\"", boundary.data() );
1430 msgPart->setSubtypeStr( tmp );
1431 msgPart->setName(
"unnamed" );
1432 msgPart->setCte( DwMime::kCte7bit );
1433 msgPart->setContentDescription( TQString(
"Digest of %1 messages." ).arg( msgCnt ) );
1435 msgPart->setBodyEncoded( TQCString( msgPartText.ascii() ) );
1437 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1438 win->addAttach( msgPart );
1443 KMRedirectCommand::KMRedirectCommand( TQWidget *parent,
1445 : KMCommand( parent, msg )
1449 KMCommand::Result KMRedirectCommand::execute()
1452 if ( !msg || !msg->
codec() )
1456 kmkernel->msgSender()->sendImmediate() );
1457 if (dlg.exec()==TQDialog::Rejected)
return Failed;
1462 const KMail::MessageSender::SendMethod method = dlg.sendImmediate()
1463 ? KMail::MessageSender::SendImmediate
1464 : KMail::MessageSender::SendLater;
1465 if ( !kmkernel->msgSender()->send( newMsg, method ) ) {
1466 kdDebug(5006) <<
"KMRedirectCommand: could not redirect message (sending failed)" << endl;
1473 KMCustomReplyToCommand::KMCustomReplyToCommand( TQWidget *parent,
KMMessage *msg,
1474 const TQString &selection,
1475 const TQString &tmpl )
1476 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
1480 KMCommand::Result KMCustomReplyToCommand::execute()
1484 if ( !msg || !msg->
codec() ) {
1488 false,
true, mTemplate );
1489 KMail::Composer * win = KMail::makeComposer( reply );
1490 win->setCharset( msg->
codec()->mimeName(), true );
1491 win->setReplyFocus();
1498 KMCustomReplyAllToCommand::KMCustomReplyAllToCommand( TQWidget *parent,
KMMessage *msg,
1499 const TQString &selection,
1500 const TQString &tmpl )
1501 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
1505 KMCommand::Result KMCustomReplyAllToCommand::execute()
1509 if ( !msg || !msg->
codec() ) {
1513 false,
true, mTemplate );
1514 KMail::Composer * win = KMail::makeComposer( reply );
1515 win->setCharset( msg->
codec()->mimeName(), true );
1516 win->setReplyFocus();
1523 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
1524 const TQPtrList<KMMsgBase> &msgList, uint identity,
const TQString &tmpl )
1525 : KMCommand( parent, msgList ),
1526 mIdentity( identity ), mTemplate( tmpl )
1530 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
1531 KMMessage *msg, uint identity,
const TQString &tmpl )
1532 : KMCommand( parent, msg ),
1533 mIdentity( identity ), mTemplate( tmpl )
1537 KMCommand::Result KMCustomForwardCommand::execute()
1539 TQPtrList<KMMessage> msgList = retrievedMsgs();
1541 if (msgList.count() >= 2) {
1544 TQPtrList<KMMessage> linklist;
1545 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1548 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1551 linklist.append( msg );
1561 for (
KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
1563 parser.setSelection( msg->
body() );
1564 parser.process( msg, 0,
true );
1566 fwdMsg->
link( msg, KMMsgStatusForwarded );
1570 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1571 win->setCharset(
"");
1577 if ( !msg || !msg->
codec() )
1583 uint
id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1587 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1588 win->setCharset( fwdMsg->
codec()->mimeName(), true );
1596 KMPrintCommand::KMPrintCommand( TQWidget *parent,
KMMessage *msg,
1598 const KMail::HeaderStrategy *headerStrategy,
1599 bool htmlOverride,
bool htmlLoadExtOverride,
1600 bool useFixedFont,
const TQString & encoding )
1601 : KMCommand( parent, msg ),
1602 mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ),
1603 mHtmlOverride( htmlOverride ),
1604 mHtmlLoadExtOverride( htmlLoadExtOverride ),
1605 mUseFixedFont( useFixedFont ), mEncoding( encoding )
1607 if ( GlobalSettings::useDefaultFonts() )
1608 mOverrideFont = KGlobalSettings::generalFont();
1610 KConfigGroup fonts( KMKernel::config(),
"Fonts" );
1611 TQString tmp = fonts.readEntry(
"print-font", KGlobalSettings::generalFont().toString() );
1612 mOverrideFont.fromString( tmp );
1617 void KMPrintCommand::setOverrideFont(
const TQFont& font )
1619 mOverrideFont = font;
1622 KMCommand::Result KMPrintCommand::execute()
1625 printWin.setPrinting(
true );
1626 printWin.readConfig();
1627 if ( mHeaderStyle != 0 && mHeaderStrategy != 0 )
1628 printWin.setHeaderStyleAndStrategy( mHeaderStyle, mHeaderStrategy );
1629 printWin.setHtmlOverride( mHtmlOverride );
1630 printWin.setHtmlLoadExtOverride( mHtmlLoadExtOverride );
1631 printWin.setUseFixedFont( mUseFixedFont );
1632 printWin.setOverrideEncoding( mEncoding );
1633 printWin.cssHelper()->setPrintFont( mOverrideFont );
1634 printWin.setDecryptMessageOverwrite(
true );
1635 printWin.setMsg( retrievedMessage(),
true );
1636 printWin.printMsg();
1642 KMSeStatusCommand::KMSeStatusCommand( KMMsgStatus status,
1643 const TQValueList<TQ_UINT32> &serNums,
bool toggle )
1644 : mStatus( status ), mSerNums( serNums ), mToggle( toggle )
1648 KMCommand::Result KMSeStatusCommand::execute()
1650 TQValueListIterator<TQ_UINT32> it;
1653 bool parenStatus =
false;
1662 if (msg && (msg->status()&mStatus))
1665 parenStatus =
false;
1668 TQMap< KMFolder*, TQValueList<int> > folderMap;
1669 for ( it = mSerNums.begin(); it != mSerNums.end(); ++it ) {
1677 if (msg->status()&mStatus)
1681 if (myStatus != parenStatus)
1687 folderMap[folder].append(idx);
1690 TQMapIterator< KMFolder*, TQValueList<int> > it2 = folderMap.begin();
1691 while ( it2 != folderMap.end() ) {
1693 f->
setStatus( (*it2), mStatus, mToggle );
1702 KMFilterCommand::KMFilterCommand(
const TQCString &field,
const TQString &value )
1703 : mField( field ), mValue( value )
1707 KMCommand::Result KMFilterCommand::execute()
1709 kmkernel->filterMgr()->createFilter( mField, mValue );
1715 KMFilterActionCommand::KMFilterActionCommand( TQWidget *parent,
1716 const TQPtrList<KMMsgBase> &msgList,
1718 : KMCommand( parent, msgList ), mFilter( filter )
1720 TQPtrListIterator<KMMsgBase> it(msgList);
1721 while ( it.current() ) {
1722 serNumList.append( (*it)->getMsgSerNum() );
1727 KMCommand::Result KMFilterActionCommand::execute()
1732 int msgCountToFilter = serNumList.count();
1733 ProgressItem* progressItem =
1734 ProgressManager::createProgressItem (
"filter"+ProgressManager::getUniqueID(),
1735 i18n(
"Filtering messages" ) );
1736 progressItem->setTotalItems( msgCountToFilter );
1737 TQValueList<TQ_UINT32>::const_iterator it;
1738 for ( it = serNumList.begin(); it != serNumList.end(); it++ ) {
1739 TQ_UINT32 serNum = *it;
1740 int diff = msgCountToFilter - ++msgCount;
1741 if ( diff < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
1742 progressItem->updateProgress();
1743 TQString statusMsg = i18n(
"Filtering message %1 of %2");
1744 statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
1745 KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
1746 KApplication::kApplication()->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput, 50 );
1749 int filterResult = kmkernel->filterMgr()->process( serNum, mFilter );
1750 if (filterResult == 2) {
1752 perror(
"Critical error");
1753 kmkernel->emergencyExit( i18n(
"Not enough free disk space?" ));
1755 progressItem->incCompletedItems();
1758 progressItem->setComplete();
1764 KMMetaFilterActionCommand::KMMetaFilterActionCommand( KMFilter *filter,
1766 KMMainWidget *main )
1768 mFilter( filter ), mHeaders( headers ), mMainWidget( main )
1772 void KMMetaFilterActionCommand::start()
1774 if (ActionScheduler::isEnabled() ) {
1776 KMFilterMgr::FilterSet
set = KMFilterMgr::All;
1777 TQValueList<KMFilter*> filters;
1778 filters.append( mFilter );
1779 ActionScheduler *scheduler =
new ActionScheduler(
set, filters, mHeaders );
1780 scheduler->setAlwaysMatch(
true );
1781 scheduler->setAutoDestruct(
true );
1783 int contentX, contentY;
1784 HeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY );
1785 TQPtrList<KMMsgBase> msgList = *mHeaders->selectedMsgs(
true);
1786 mHeaders->finalizeMove( nextItem, contentX, contentY );
1788 for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
1789 scheduler->execFilters( msg );
1791 KMCommand *filterCommand =
1792 new KMFilterActionCommand( mMainWidget,
1793 *mHeaders->selectedMsgs(), mFilter );
1794 filterCommand->start();
1795 int contentX, contentY;
1796 HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
1797 mHeaders->finalizeMove( item, contentX, contentY );
1801 FolderShortcutCommand::FolderShortcutCommand( KMMainWidget *mainwidget,
1803 : mMainWidget( mainwidget ), mFolder( folder ), mAction( 0 )
1808 FolderShortcutCommand::~FolderShortcutCommand()
1810 if ( mAction ) mAction->unplugAll();
1814 void FolderShortcutCommand::start()
1816 mMainWidget->slotSelectFolder( mFolder );
1819 void FolderShortcutCommand::setAction( KAction* action )
1824 KMMailingListFilterCommand::KMMailingListFilterCommand( TQWidget *parent,
1826 : KMCommand( parent, msg )
1830 KMCommand::Result KMMailingListFilterCommand::execute()
1838 if ( !MailingList::name( msg, name, value ).isEmpty() ) {
1839 kmkernel->filterMgr()->createFilter( name, value );
1847 void KMMenuCommand::folderToPopupMenu(
bool move,
1848 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
1850 while ( menu->count() )
1852 TQPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
1856 menu->removeItemAt( 0 );
1859 if (!kmkernel->imapFolderMgr()->dir().first() &&
1860 !kmkernel->dimapFolderMgr()->dir().first())
1862 makeFolderMenu( &kmkernel->folderMgr()->dir(), move,
1863 receiver, aMenuToFolder, menu );
1866 TQPopupMenu* subMenu =
new TQPopupMenu(menu);
1867 makeFolderMenu( &kmkernel->folderMgr()->dir(),
1868 move, receiver, aMenuToFolder, subMenu );
1869 menu->insertItem( i18n(
"Local Folders" ), subMenu );
1870 KMFolderDir* fdir = &kmkernel->imapFolderMgr()->dir();
1871 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
1874 subMenu =
new TQPopupMenu(menu);
1875 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
1876 menu->insertItem( node->label(), subMenu );
1878 fdir = &kmkernel->dimapFolderMgr()->dir();
1879 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
1882 subMenu =
new TQPopupMenu(menu);
1883 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
1884 menu->insertItem( node->label(), subMenu );
1889 void KMMenuCommand::makeFolderMenu(KMFolderNode* node,
bool move,
1890 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
1895 disconnect(menu, TQT_SIGNAL(activated(
int)), receiver,
1896 TQT_SLOT(moveSelectedToFolder(
int)));
1897 connect(menu, TQT_SIGNAL(activated(
int)), receiver,
1898 TQT_SLOT(moveSelectedToFolder(
int)));
1900 disconnect(menu, TQT_SIGNAL(activated(
int)), receiver,
1901 TQT_SLOT(copySelectedToFolder(
int)));
1902 connect(menu, TQT_SIGNAL(activated(
int)), receiver,
1903 TQT_SLOT(copySelectedToFolder(
int)));
1908 if (node->isDir()) {
1911 folder =
static_cast<KMFolder*
>(node);
1912 folderDir = folder->
child();
1919 menuId = menu->insertItem(i18n(
"Move to This Folder"));
1921 menuId = menu->insertItem(i18n(
"Copy to This Folder"));
1922 aMenuToFolder->insert( menuId, folder );
1923 menu->setItemEnabled( menuId, !folder->
isReadOnly() );
1924 menu->insertSeparator();
1930 for (KMFolderNode *it = folderDir->first(); it; it = folderDir->next() ) {
1934 TQString label = child->
label();
1935 label.replace(
"&",
"&&");
1936 if (child->
child() && child->
child()->first()) {
1938 TQPopupMenu *subMenu =
new TQPopupMenu(menu,
"subMenu");
1939 makeFolderMenu( child, move, receiver,
1940 aMenuToFolder, subMenu );
1941 menu->insertItem( label, subMenu );
1944 int menuId = menu->insertItem( label );
1945 aMenuToFolder->insert( menuId, child );
1946 menu->setItemEnabled( menuId, !child->
isReadOnly() );
1953 KMCopyCommand::KMCopyCommand(
KMFolder* destFolder,
1954 const TQPtrList<KMMsgBase> &msgList )
1955 :mDestFolder( destFolder ), mMsgList( msgList )
1957 setDeletesItself(
true );
1961 :mDestFolder( destFolder )
1963 setDeletesItself(
true );
1967 KMCommand::Result KMCopyCommand::execute()
1973 TQPtrList<KMMessage> list;
1974 TQPtrList<KMMessage> localList;
1976 if (mDestFolder && mDestFolder->open(
"kmcommand") != 0)
1982 setEmitsCompletedItself(
true );
1985 for (msgBase = mMsgList.first(); msgBase; msgBase = mMsgList.next() )
1987 KMFolder *srcFolder = msgBase->parent();
1988 if (( isMessage = msgBase->isMessage() ))
1992 idx = srcFolder->
find(msgBase);
1994 msg = srcFolder->
getMsg(idx);
1997 KMessageBox::error( parentWidget(), i18n(
"Corrupt IMAP cache detected in folder %1. "
1998 "Copying of messages aborted.").arg( srcFolder->
prettyURL() ) );
2004 if (srcFolder && mDestFolder &&
2005 (srcFolder->
folderType()== KMFolderTypeImap) &&
2006 (mDestFolder->folderType() == KMFolderTypeImap) &&
2007 (static_cast<KMFolderImap*>(srcFolder->storage())->account() ==
2008 static_cast<KMFolderImap*
>(mDestFolder->storage())->account()))
2013 newMsg =
new KMMessage(
new DwMessage( *msg->asDwMessage() ) );
2023 newMsg->setParent(msg->parent());
2024 FolderJob *job = srcFolder->
createJob(newMsg);
2025 job->setCancellable(
false );
2026 mPendingJobs << job;
2027 connect(job, TQT_SIGNAL(messageRetrieved(
KMMessage*)),
2028 mDestFolder, TQT_SLOT(reallyAddCopyOfMsg(
KMMessage*)));
2029 connect( job, TQT_SIGNAL(result(KMail::FolderJob*)),
2030 this, TQT_SLOT(slotJobFinished(KMail::FolderJob*)) );
2034 localList.append(newMsg);
2038 if (srcFolder && !isMessage && list.isEmpty())
2046 bool deleteNow =
false;
2047 if (!localList.isEmpty())
2049 TQValueList<int> index;
2050 mDestFolder->addMsg( localList, index );
2051 for ( TQValueListIterator<int> it = index.begin(); it != index.end(); ++it ) {
2052 mDestFolder->unGetMsg( *it );
2054 if ( mDestFolder->folderType() == KMFolderTypeImap ) {
2055 if ( mPendingJobs.isEmpty() ) {
2057 KMFolderImap *imapDestFolder =
static_cast<KMFolderImap*
>(mDestFolder->storage());
2058 connect( imapDestFolder, TQT_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
2059 this, TQT_SLOT( slotFolderComplete( KMFolderImap*,
bool ) ) );
2062 deleteNow = list.isEmpty() && mPendingJobs.isEmpty();
2068 if (!list.isEmpty())
2071 KMFolderImap *imapDestFolder =
static_cast<KMFolderImap*
>(mDestFolder->storage());
2072 connect( imapDestFolder, TQT_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
2073 this, TQT_SLOT( slotFolderComplete( KMFolderImap*,
bool ) ) );
2074 imapDestFolder->copyMsg(list);
2075 imapDestFolder->getFolder();
2082 mDestFolder->close(
"kmcommand");
2084 emit completed(
this );
2091 void KMCopyCommand::slotJobFinished(KMail::FolderJob * job)
2093 mPendingJobs.remove( job );
2094 if ( job->error() ) {
2095 kdDebug(5006) << k_funcinfo <<
"folder job failed: " << job->error() << endl;
2097 for ( TQValueList<KMail::FolderJob*>::Iterator it = mPendingJobs.begin(); it != mPendingJobs.end(); ++it ) {
2098 disconnect( (*it), TQT_SIGNAL(result(KMail::FolderJob*)),
2099 this, TQT_SLOT(slotJobFinished(KMail::FolderJob*)) );
2102 mPendingJobs.clear();
2103 setResult( Failed );
2106 if ( mPendingJobs.isEmpty() )
2108 mDestFolder->close(
"kmcommand");
2109 emit completed(
this );
2114 void KMCopyCommand::slotFolderComplete( KMFolderImap*,
bool success )
2116 kdDebug(5006) << k_funcinfo << success << endl;
2118 setResult( Failed );
2119 mDestFolder->close(
"kmcommand" );
2120 emit completed(
this );
2125 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2126 const TQPtrList<KMMsgBase> &msgList)
2127 : mDestFolder( destFolder ), mProgressItem( 0 )
2129 TQPtrList<KMMsgBase> tmp = msgList;
2130 for ( KMMsgBase *msgBase = tmp.first(); msgBase; msgBase = tmp.next() )
2131 mSerNumList.append( msgBase->getMsgSerNum() );
2134 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2136 : mDestFolder( destFolder ), mProgressItem( 0 )
2138 mSerNumList.append( msg->getMsgSerNum() );
2141 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2142 KMMsgBase *msgBase )
2143 : mDestFolder( destFolder ), mProgressItem( 0 )
2145 mSerNumList.append( msgBase->getMsgSerNum() );
2148 KMMoveCommand::KMMoveCommand( TQ_UINT32 )
2149 : mProgressItem( 0 )
2153 KMCommand::Result KMMoveCommand::execute()
2155 setEmitsCompletedItself(
true );
2156 setDeletesItself(
true );
2157 typedef TQMap< KMFolder*, TQPtrList<KMMessage>* > FolderToMessageListMap;
2158 FolderToMessageListMap folderDeleteList;
2160 if (mDestFolder && mDestFolder->open(
"kmcommand") != 0) {
2161 completeMove( Failed );
2167 Q_ASSERT( !mProgressItem );
2169 ProgressManager::createProgressItem (
2170 "move"+ProgressManager::getUniqueID(),
2171 mDestFolder ? i18n(
"Moving messages" ) : i18n(
"Deleting messages" ) );
2172 connect( mProgressItem, TQT_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
2173 this, TQT_SLOT( slotMoveCanceled() ) );
2178 TQPtrList<KMMessage> list;
2180 mCompleteWithAddedMsg =
false;
2183 connect (mDestFolder, TQT_SIGNAL(msgAdded(
KMFolder*, TQ_UINT32)),
2184 this, TQT_SLOT(slotMsgAddedToDestFolder(
KMFolder*, TQ_UINT32)));
2185 mLostBoys = mSerNumList;
2187 mProgressItem->setTotalItems( mSerNumList.count() );
2189 for ( TQValueList<TQ_UINT32>::ConstIterator it = mSerNumList.constBegin(); it != mSerNumList.constEnd(); ++it ) {
2191 kdDebug(5006) << k_funcinfo <<
"serial number == 0!" << endl;
2197 if (srcFolder == mDestFolder)
2202 srcFolder->
open(
"kmmovecommand" );
2203 mOpenedFolders.append( srcFolder );
2205 msg = srcFolder->
getMsg(idx);
2207 kdDebug(5006) << k_funcinfo <<
"No message found for serial number " << *it << endl;
2210 bool undo = msg->enableUndo();
2213 srcFolder->
folderType() == KMFolderTypeImap )
2217 static_cast<KMFolderImap*
>(srcFolder->storage())->ignoreJobsForMessage( msg );
2221 if (mDestFolder->folderType() == KMFolderTypeImap) {
2225 KMFolderImap *imapFolder =
static_cast<KMFolderImap*
> ( mDestFolder->storage() );
2226 disconnect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2227 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2229 connect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2230 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2234 if ( srcFolder->
folderType() == KMFolderTypeImap )
2237 mCompleteWithAddedMsg =
true;
2239 rc = mDestFolder->moveMsg(msg, &index);
2240 if (rc == 0 && index != -1) {
2241 KMMsgBase *mb = mDestFolder->unGetMsg( mDestFolder->count() - 1 );
2245 undoId = kmkernel->undoStack()->newUndoAction( srcFolder, mDestFolder );
2246 kmkernel->undoStack()->addMsgToAction( undoId, mb->getMsgSerNum() );
2248 }
else if (rc != 0) {
2251 completeMove( Failed );
2258 if (srcFolder->
folderType() == KMFolderTypeImap) {
2259 if (!folderDeleteList[srcFolder])
2260 folderDeleteList[srcFolder] =
new TQPtrList<KMMessage>;
2261 folderDeleteList[srcFolder]->append( msg );
2263 srcFolder->removeMsg(idx);
2268 if (!list.isEmpty() && mDestFolder) {
2270 mDestFolder->moveMsg(list, &index);
2272 FolderToMessageListMap::Iterator it;
2273 for ( it = folderDeleteList.begin(); it != folderDeleteList.end(); ++it ) {
2274 it.key()->removeMsg(*it.data());
2277 if ( !mCompleteWithAddedMsg ) {
2286 void KMMoveCommand::slotImapFolderCompleted(KMFolderImap* imapFolder,
bool success)
2288 disconnect (imapFolder, TQT_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2289 this, TQT_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2297 if ( !mLostBoys.isEmpty() ) {
2298 kdDebug(5006) <<
"### Not all moved messages reported back that they were " << endl
2299 <<
"### added to the target folder. Did uidValidity change? " << endl;
2304 completeMove( Failed );
2308 void KMMoveCommand::slotMsgAddedToDestFolder(
KMFolder *folder, TQ_UINT32 serNum)
2310 if ( folder != mDestFolder || mLostBoys.
find( serNum ) == mLostBoys.end() ) {
2315 mLostBoys.remove(serNum);
2316 if ( mLostBoys.isEmpty() ) {
2318 disconnect (mDestFolder, TQT_SIGNAL(msgAdded(
KMFolder*, TQ_UINT32)),
2319 this, TQT_SLOT(slotMsgAddedToDestFolder(
KMFolder*, TQ_UINT32)));
2320 if (mDestFolder && mDestFolder->folderType() != KMFolderTypeImap) {
2321 mDestFolder->sync();
2323 if ( mCompleteWithAddedMsg ) {
2327 if ( mProgressItem ) {
2328 mProgressItem->incCompletedItems();
2329 mProgressItem->updateProgress();
2334 void KMMoveCommand::completeMove( Result result )
2337 mDestFolder->close(
"kmcommand");
2338 while ( !mOpenedFolders.empty() ) {
2339 KMFolder *folder = mOpenedFolders.back();
2340 mOpenedFolders.pop_back();
2341 folder->
close(
"kmcommand");
2343 if ( mProgressItem ) {
2344 mProgressItem->setComplete();
2347 setResult( result );
2348 emit completed(
this );
2352 void KMMoveCommand::slotMoveCanceled()
2354 completeMove( Canceled );
2358 KMDeleteMsgCommand::KMDeleteMsgCommand(
KMFolder* srcFolder,
2359 const TQPtrList<KMMsgBase> &msgList )
2360 :KMMoveCommand( findTrashFolder( srcFolder ), msgList)
2362 srcFolder->
open(
"kmcommand");
2363 mOpenedFolders.push_back( srcFolder );
2367 :KMMoveCommand( findTrashFolder( srcFolder ), msg)
2369 srcFolder->
open(
"kmcommand");
2370 mOpenedFolders.push_back( srcFolder );
2373 KMDeleteMsgCommand::KMDeleteMsgCommand( TQ_UINT32 sernum )
2374 :KMMoveCommand( sernum )
2385 KMMsgBase *msg = srcFolder->
getMsgBase( idx );
2386 srcFolder->
open(
"kmcommand");
2387 mOpenedFolders.push_back( srcFolder );
2390 setDestFolder( findTrashFolder( srcFolder ) );
2397 trash = kmkernel->trashFolder();
2398 if( trash != folder )
2404 KMUrlClickedCommand::KMUrlClickedCommand(
const KURL &url, uint identity,
2405 KMReaderWin *readerWin,
bool htmlPref, KMMainWidget *mainWidget )
2406 :mUrl( url ), mIdentity( identity ), mReaderWin( readerWin ),
2407 mHtmlPref( htmlPref ), mMainWidget( mainWidget )
2411 KMCommand::Result KMUrlClickedCommand::execute()
2415 if (mUrl.protocol() ==
"mailto")
2421 TQString query=mUrl.query();
2422 while (!query.isEmpty()) {
2424 int secondQuery = query.find(
'?',1);
2425 if (secondQuery != -1)
2426 queryPart = query.left(secondQuery);
2429 query = query.mid(queryPart.length());
2431 if (queryPart.left(9) ==
"?subject=")
2432 msg->setSubject( KURL::decode_string(queryPart.mid(9)) );
2433 else if (queryPart.left(6) ==
"?body=")
2436 msg->
setBody( KURL::decode_string(queryPart.mid(6)).latin1() );
2437 else if (queryPart.left(4) ==
"?cc=")
2438 msg->setCc( KURL::decode_string(queryPart.mid(4)) );
2441 KMail::Composer * win = KMail::makeComposer( msg, mIdentity );
2442 win->setCharset(
"",
true);
2445 else if ( mUrl.protocol() ==
"im" )
2447 kmkernel->imProxy()->chatWithContact( mUrl.path() );
2449 else if ((mUrl.protocol() ==
"http") || (mUrl.protocol() ==
"https") ||
2450 (mUrl.protocol() ==
"ftp") || (mUrl.protocol() ==
"file") ||
2451 (mUrl.protocol() ==
"ftps") || (mUrl.protocol() ==
"sftp" ) ||
2452 (mUrl.protocol() ==
"help") || (mUrl.protocol() ==
"vnc") ||
2453 (mUrl.protocol() ==
"smb") || (mUrl.protocol() ==
"fish") ||
2454 (mUrl.protocol() ==
"news"))
2456 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n(
"Opening URL..."));
2457 KMimeType::Ptr mime = KMimeType::findByURL( mUrl );
2458 if (mime->name() ==
"application/x-desktop" ||
2459 mime->name() ==
"application/x-executable" ||
2460 mime->name() ==
"application/x-msdos-program" ||
2461 mime->name() ==
"application/x-shellscript" )
2463 if (KMessageBox::warningYesNo( 0, i18n(
"<qt>Do you really want to execute <b>%1</b>?</qt>" )
2464 .arg( mUrl.prettyURL() ), TQString(), i18n(
"Execute"), KStdGuiItem::cancel() ) != KMessageBox::Yes)
2467 KRun * runner =
new KRun( mUrl );
2468 runner->setRunExecutables(
false );
2476 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent,
KMMessage *msg )
2477 : KMCommand( parent, msg ), mImplicitAttachments( true ), mEncoded( false )
2481 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent,
const TQPtrList<KMMsgBase>& msgs )
2482 : KMCommand( parent, msgs ), mImplicitAttachments( true ), mEncoded( false )
2486 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent, TQPtrList<partNode>& attachments,
2488 : KMCommand( parent ), mImplicitAttachments( false ), mEncoded( encoded )
2490 for ( TQPtrListIterator<partNode> it( attachments ); it.current(); ++it ) {
2491 mAttachmentMap.insert( it.current(), msg );
2495 KMCommand::Result KMSaveAttachmentsCommand::execute()
2497 setEmitsCompletedItself(
true );
2498 if ( mImplicitAttachments ) {
2499 TQPtrList<KMMessage> msgList = retrievedMsgs();
2501 for ( TQPtrListIterator<KMMessage> itr( msgList );
2502 ( msg = itr.current() );
2504 partNode *rootNode = partNode::fromMessage( msg );
2505 for ( partNode *child = rootNode; child;
2506 child = child->firstChild() ) {
2507 for ( partNode *node = child; node; node = node->nextSibling() ) {
2508 if ( node->type() != DwMime::kTypeMultipart )
2509 mAttachmentMap.insert( node, msg );
2514 setDeletesItself(
true );
2516 KMLoadPartsCommand *command =
new KMLoadPartsCommand( mAttachmentMap );
2517 connect( command, TQT_SIGNAL( partsRetrieved() ),
2518 this, TQT_SLOT( slotSaveAll() ) );
2524 void KMSaveAttachmentsCommand::slotSaveAll()
2529 if ( mImplicitAttachments ) {
2530 for ( PartNodeMessageMap::iterator it = mAttachmentMap.begin();
2531 it != mAttachmentMap.end(); ) {
2535 if ( it.key()->msgPart().fileName().stripWhiteSpace().isEmpty() &&
2536 ( it.key()->msgPart().name().stripWhiteSpace().isEmpty() ||
2537 !it.key()->parentNode() ) ) {
2538 PartNodeMessageMap::iterator delIt = it;
2540 mAttachmentMap.remove( delIt );
2545 if ( mAttachmentMap.isEmpty() ) {
2546 KMessageBox::information( 0, i18n(
"Found no attachments to save.") );
2548 emit completed(
this );
2555 if ( mAttachmentMap.count() > 1 ) {
2557 dirUrl = KDirSelectDialog::selectDirectory( TQString(),
false,
2559 i18n(
"Save Attachments To") );
2560 if ( !dirUrl.isValid() ) {
2561 setResult( Canceled );
2562 emit completed(
this );
2568 dirUrl.adjustPath( 1 );
2572 partNode *node = mAttachmentMap.begin().key();
2575 node->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
2577 s = node->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
2579 s = i18n(
"filename for an unnamed attachment",
"attachment.1");
2580 url = KFileDialog::getSaveURL( s, TQString(), parentWidget(),
2582 if ( url.isEmpty() ) {
2583 setResult( Canceled );
2584 emit completed(
this );
2590 TQMap< TQString, int > renameNumbering;
2592 Result globalResult = OK;
2593 int unnamedAtmCount = 0;
2594 for ( PartNodeMessageMap::const_iterator it = mAttachmentMap.begin();
2595 it != mAttachmentMap.end();
2598 if ( !dirUrl.isEmpty() ) {
2601 it.key()->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
2603 s = it.key()->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
2604 if ( s.isEmpty() ) {
2606 s = i18n(
"filename for the %1-th unnamed attachment",
2608 .arg( unnamedAtmCount );
2610 curUrl.setFileName( s );
2615 if ( !curUrl.isEmpty() ) {
2619 TQString origFile = curUrl.fileName();
2620 TQString file = origFile;
2622 while ( renameNumbering.contains(file) ) {
2624 int num = renameNumbering[file] + 1;
2625 int dotIdx = file.findRev(
'.');
2626 file = file.insert( (dotIdx>=0) ? dotIdx : file.length(), TQString(
"_") + TQString::number(num) );
2628 curUrl.setFileName(file);
2631 if ( !renameNumbering.contains(origFile))
2632 renameNumbering[origFile] = 1;
2634 renameNumbering[origFile]++;
2636 if ( file != origFile ) {
2637 if ( !renameNumbering.contains(file))
2638 renameNumbering[file] = 1;
2640 renameNumbering[file]++;
2644 if ( KIO::NetAccess::exists( curUrl,
false, parentWidget() ) ) {
2645 if ( KMessageBox::warningContinueCancel( parentWidget(),
2646 i18n(
"A file named %1 already exists. Do you want to overwrite it?" )
2647 .arg( curUrl.fileName() ),
2648 i18n(
"File Already Exists" ), i18n(
"&Overwrite") ) == KMessageBox::Cancel) {
2653 const Result result = saveItem( it.key(), curUrl );
2655 globalResult = result;
2658 setResult( globalResult );
2659 emit completed(
this );
2663 KMCommand::Result KMSaveAttachmentsCommand::saveItem( partNode *node,
2666 bool bSaveEncrypted =
false;
2667 bool bEncryptedParts = node->encryptionState() != KMMsgNotEncrypted;
2668 if( bEncryptedParts )
2669 if( KMessageBox::questionYesNo( parentWidget(),
2670 i18n(
"The part %1 of the message is encrypted. Do you want to keep the encryption when saving?" ).
2671 arg( url.fileName() ),
2672 i18n(
"KMail Question" ), i18n(
"Keep Encryption"), i18n(
"Do Not Keep") ) ==
2674 bSaveEncrypted =
true;
2676 bool bSaveWithSig =
true;
2677 if( node->signatureState() != KMMsgNotSigned )
2678 if( KMessageBox::questionYesNo( parentWidget(),
2679 i18n(
"The part %1 of the message is signed. Do you want to keep the signature when saving?" ).
2680 arg( url.fileName() ),
2681 i18n(
"KMail Question" ), i18n(
"Keep Signature"), i18n(
"Do Not Keep") ) !=
2683 bSaveWithSig =
false;
2694 if( bSaveEncrypted || !bEncryptedParts) {
2695 partNode *dataNode = node;
2696 TQCString rawReplyString;
2697 bool gotRawReplyString =
false;
2698 if( !bSaveWithSig ) {
2699 if( DwMime::kTypeMultipart == node->type() &&
2700 DwMime::kSubtypeSigned == node->subType() ){
2702 if( node->findType( DwMime::kTypeApplication,
2703 DwMime::kSubtypePgpSignature,
2705 dataNode = node->findTypeNot( DwMime::kTypeApplication,
2706 DwMime::kSubtypePgpSignature,
2708 }
else if( node->findType( DwMime::kTypeApplication,
2709 DwMime::kSubtypePkcs7Mime,
2711 dataNode = node->findTypeNot( DwMime::kTypeApplication,
2712 DwMime::kSubtypePkcs7Mime,
2715 dataNode = node->findTypeNot( DwMime::kTypeMultipart,
2716 DwMime::kSubtypeUnknown,
2720 ObjectTreeParser otp( 0, 0,
false,
false,
false );
2723 dataNode->setProcessed(
false,
true );
2724 otp.parseObjectTree( dataNode );
2726 rawReplyString = otp.rawReplyString();
2727 gotRawReplyString =
true;
2730 TQByteArray cstr = gotRawReplyString
2732 : dataNode->msgPart().bodyDecodedBinary();
2734 size_t size = cstr.size();
2735 if ( dataNode->msgPart().type() == DwMime::kTypeText ) {
2739 data.resize( size );
2745 tf.setAutoDelete(
true );
2746 if ( url.isLocalFile() )
2749 file.setName( url.path() );
2750 if ( !file.open( IO_WriteOnly ) )
2752 KMessageBox::error( parentWidget(),
2753 i18n(
"%2 is detailed error description",
2754 "Could not write the file %1:\n%2" )
2756 .arg( TQString::fromLocal8Bit( strerror( errno ) ) ),
2757 i18n(
"KMail Error" ) );
2762 if ( GlobalSettings::self()->disregardUmask() )
2763 fchmod( file.handle(), S_IRUSR | S_IWUSR );
2765 ds.setDevice( &file );
2769 ds.setDevice( tf.file() );
2772 ds.writeRawBytes( data.data(), data.size() );
2773 if ( !url.isLocalFile() )
2776 if ( !KIO::NetAccess::upload( tf.name(), url, parentWidget() ) )
2778 KMessageBox::error( parentWidget(),
2779 i18n(
"Could not write the file %1." )
2781 i18n(
"KMail Error" ) );
2789 KMLoadPartsCommand::KMLoadPartsCommand( TQPtrList<partNode>& parts,
KMMessage *msg )
2790 : mNeedsRetrieval( 0 )
2792 for ( TQPtrListIterator<partNode> it( parts ); it.current(); ++it ) {
2793 mPartMap.insert( it.current(), msg );
2797 KMLoadPartsCommand::KMLoadPartsCommand( partNode *node,
KMMessage *msg )
2798 : mNeedsRetrieval( 0 )
2800 mPartMap.insert( node, msg );
2803 KMLoadPartsCommand::KMLoadPartsCommand( PartNodeMessageMap& partMap )
2804 : mNeedsRetrieval( 0 ), mPartMap( partMap )
2808 void KMLoadPartsCommand::slotStart()
2810 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
2811 it != mPartMap.end();
2813 if ( !it.key()->msgPart().isComplete() &&
2814 !it.key()->msgPart().partSpecifier().isEmpty() ) {
2817 KMFolder* curFolder = it.data()->parent();
2820 curFolder->
createJob( it.data(), FolderJob::tGetMessage,
2821 0, it.key()->msgPart().partSpecifier() );
2822 job->setCancellable(
false );
2823 connect( job, TQT_SIGNAL(messageUpdated(
KMMessage*, TQString)),
2824 this, TQT_SLOT(slotPartRetrieved(
KMMessage*, TQString)) );
2827 kdWarning(5006) <<
"KMLoadPartsCommand - msg has no parent" << endl;
2830 if ( mNeedsRetrieval == 0 )
2834 void KMLoadPartsCommand::slotPartRetrieved(
KMMessage *msg,
2835 TQString partSpecifier )
2841 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
2842 it != mPartMap.end();
2844 if ( it.key()->dwPart()->partId() == part->partId() )
2845 it.key()->setDwPart( part );
2848 kdWarning(5006) <<
"KMLoadPartsCommand::slotPartRetrieved - could not find bodypart!" << endl;
2850 if ( mNeedsRetrieval == 0 )
2854 KMCommand::Result KMLoadPartsCommand::execute()
2856 emit partsRetrieved();
2858 emit completed(
this );
2863 KMResendMessageCommand::KMResendMessageCommand( TQWidget *parent,
2865 :KMCommand( parent, msg )
2869 KMCommand::Result KMResendMessageCommand::execute()
2872 if ( !msg || !msg->
codec() ) {
2877 TQStringList whiteList;
2878 whiteList <<
"To" <<
"Cc" <<
"Bcc" <<
"Subject";
2882 newMsg->setParent( 0 );
2888 KMail::Composer * win = KMail::makeComposer();
2889 win->setMsg(newMsg,
false,
true);
2895 KMMailingListCommand::KMMailingListCommand( TQWidget *parent,
KMFolder *folder )
2896 : KMCommand( parent ), mFolder( folder )
2900 KMCommand::Result KMMailingListCommand::execute()
2902 KURL::List lst = urls();
2903 TQString handler = ( mFolder->mailingList().handler() == MailingList::KMail )
2904 ?
"mailto" :
"https";
2906 KMCommand *command = 0;
2907 for ( KURL::List::Iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
2908 if ( handler == (*itr).protocol() ) {
2909 command =
new KMUrlClickedCommand( *itr, mFolder->identity(), 0, false );
2912 if ( !command && !lst.empty() ) {
2914 new KMUrlClickedCommand( lst.first(), mFolder->identity(), 0, false );
2917 connect( command, TQT_SIGNAL( completed( KMCommand * ) ),
2918 this, TQT_SLOT( commandCompleted( KMCommand * ) ) );
2919 setDeletesItself(
true );
2920 setEmitsCompletedItself(
true );
2927 void KMMailingListCommand::commandCompleted( KMCommand *command )
2929 setResult( command->result() );
2930 emit completed(
this );
2934 KMMailingListPostCommand::KMMailingListPostCommand( TQWidget *parent,
KMFolder *folder )
2935 : KMMailingListCommand( parent, folder )
2938 KURL::List KMMailingListPostCommand::urls()
const
2940 return mFolder->mailingList().postURLS();
2943 KMMailingListSubscribeCommand::KMMailingListSubscribeCommand( TQWidget *parent,
KMFolder *folder )
2944 : KMMailingListCommand( parent, folder )
2947 KURL::List KMMailingListSubscribeCommand::urls()
const
2949 return mFolder->mailingList().subscribeURLS();
2952 KMMailingListUnsubscribeCommand::KMMailingListUnsubscribeCommand( TQWidget *parent,
KMFolder *folder )
2953 : KMMailingListCommand( parent, folder )
2956 KURL::List KMMailingListUnsubscribeCommand::urls()
const
2958 return mFolder->mailingList().unsubscribeURLS();
2961 KMMailingListArchivesCommand::KMMailingListArchivesCommand( TQWidget *parent,
KMFolder *folder )
2962 : KMMailingListCommand( parent, folder )
2965 KURL::List KMMailingListArchivesCommand::urls()
const
2967 return mFolder->mailingList().archiveURLS();
2970 KMMailingListHelpCommand::KMMailingListHelpCommand( TQWidget *parent,
KMFolder *folder )
2971 : KMMailingListCommand( parent, folder )
2974 KURL::List KMMailingListHelpCommand::urls()
const
2976 return mFolder->mailingList().helpURLS();
2979 KMIMChatCommand::KMIMChatCommand(
const KURL &url,
KMMessage *msg )
2980 :mUrl( url ), mMessage( msg )
2984 KMCommand::Result KMIMChatCommand::execute()
2986 kdDebug( 5006 ) << k_funcinfo <<
" URL is: " << mUrl << endl;
2989 KABC::AddressBook *addressBook = KABC::StdAddressBook::self(
true );
2990 KABC::AddresseeList addressees = addressBook->findByEmail( KPIM::getEmailAddress( addr ) ) ;
2993 if( addressees.count() == 1 ) {
2994 kmkernel->imProxy()->chatWithContact( addressees[0].uid() );
2999 kdDebug( 5006 ) <<
"Didn't find exactly one addressee, couldn't tell who to chat to for that email address. Count = " << addressees.count() << endl;
3002 if ( addressees.isEmpty() )
3003 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." );
3006 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." );
3007 TQStringList nameList;
3008 KABC::AddresseeList::const_iterator it = addressees.begin();
3009 KABC::AddresseeList::const_iterator end = addressees.end();
3010 for ( ; it != end; ++it )
3012 nameList.append( (*it).realName() );
3014 TQString names = nameList.join( TQString::fromLatin1(
",\n" ) );
3015 apology = apology.arg( names );
3018 KMessageBox::sorry( parentWidget(), apology );
3023 KMHandleAttachmentCommand::KMHandleAttachmentCommand( partNode* node,
3024 KMMessage* msg,
int atmId,
const TQString& atmName,
3025 AttachmentAction action, KService::Ptr offer, TQWidget* parent )
3026 : KMCommand( parent ), mNode( node ), mMsg( msg ), mAtmId( atmId ), mAtmName( atmName ),
3027 mAction( action ), mOffer( offer ), mJob( 0 )
3031 void KMHandleAttachmentCommand::slotStart()
3033 if ( !mNode->msgPart().isComplete() )
3036 kdDebug(5006) <<
"load part" << endl;
3037 KMLoadPartsCommand *command =
new KMLoadPartsCommand( mNode, mMsg );
3038 connect( command, TQT_SIGNAL( partsRetrieved() ),
3039 this, TQT_SLOT( slotPartComplete() ) );
3047 void KMHandleAttachmentCommand::slotPartComplete()
3052 KMCommand::Result KMHandleAttachmentCommand::execute()
3071 case ChiasmusEncrypt:
3072 atmEncryptWithChiasmus();
3076 kdDebug(5006) <<
"unknown action " << mAction << endl;
3080 emit completed(
this );
3085 TQString KMHandleAttachmentCommand::createAtmFileLink()
const
3087 TQFileInfo atmFileInfo( mAtmName );
3089 if ( atmFileInfo.size() == 0 )
3091 kdDebug(5006) << k_funcinfo <<
"rewriting attachment" << endl;
3093 TQByteArray data = mNode->msgPart().bodyDecodedBinary();
3094 size_t size = data.size();
3095 if ( mNode->msgPart().type() == DwMime::kTypeText && size) {
3099 KPIM::kBytesToFile( data.data(), size, mAtmName,
false,
false, false );
3102 KTempFile *linkFile =
new KTempFile( locateLocal(
"tmp", atmFileInfo.fileName() +
"_["),
3103 "]."+ atmFileInfo.extension() );
3105 linkFile->setAutoDelete(
true);
3106 TQString linkName = linkFile->name();
3109 if ( ::link(TQFile::encodeName( mAtmName ), TQFile::encodeName( linkName )) == 0 ) {
3115 KService::Ptr KMHandleAttachmentCommand::getServiceOffer()
3117 KMMessagePart& msgPart = mNode->msgPart();
3118 const TQString contentTypeStr =
3119 ( msgPart.typeStr() +
'/' + msgPart.subtypeStr() ).lower();
3121 if ( contentTypeStr ==
"text/x-vcard" ) {
3126 KMimeType::Ptr mimetype;
3128 mimetype = KMimeType::mimeType( contentTypeStr );
3129 if ( mimetype->name() ==
"application/octet-stream" ) {
3131 mimetype = KMimeType::findByPath( mAtmName, 0,
true );
3133 if ( ( mimetype->name() ==
"application/octet-stream" )
3134 && msgPart.isComplete() ) {
3137 mimetype = KMimeType::findByFileContent( mAtmName );
3139 return KServiceTypeProfile::preferredService( mimetype->name(),
"Application" );
3142 void KMHandleAttachmentCommand::atmOpen()
3145 mOffer = getServiceOffer();
3147 kdDebug(5006) << k_funcinfo <<
"got no offer" << endl;
3153 bool autoDelete =
true;
3154 TQString fname = createAtmFileLink();
3156 if ( fname.isNull() ) {
3161 url.setPath( fname );
3163 if ( (KRun::run( *mOffer, lst, autoDelete ) <= 0) && autoDelete ) {
3164 TQFile::remove(url.path());
3168 void KMHandleAttachmentCommand::atmOpenWith()
3172 bool autoDelete =
true;
3173 TQString fname = createAtmFileLink();
3175 if ( fname.isNull() ) {
3180 url.setPath( fname );
3182 if ( (! KRun::displayOpenWithDialog(lst, autoDelete)) && autoDelete ) {
3183 TQFile::remove( url.path() );
3187 void KMHandleAttachmentCommand::atmView()
3190 emit showAttachment( mAtmId, mAtmName );
3193 void KMHandleAttachmentCommand::atmSave()
3195 TQPtrList<partNode> parts;
3196 parts.append( mNode );
3198 KMSaveAttachmentsCommand *command =
3199 new KMSaveAttachmentsCommand( parentWidget(), parts, mMsg,
false );
3203 void KMHandleAttachmentCommand::atmProperties()
3206 KMMessagePart& msgPart = mNode->msgPart();
3207 dlg.setMsgPart( &msgPart );
3211 void KMHandleAttachmentCommand::atmEncryptWithChiasmus()
3213 const partNode * node = mNode;
3219 if ( !mAtmName.endsWith(
".xia",
false ) )
3222 const Kleo::CryptoBackend::Protocol * chiasmus =
3223 Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" );
3224 Q_ASSERT( chiasmus );
3228 const STD_NAMESPACE_PREFIX auto_ptr<Kleo::SpecialJob> listjob( chiasmus->specialJob(
"x-obtain-keys", TQMap<TQString,TQVariant>() ) );
3229 if ( !listjob.get() ) {
3230 const TQString msg = i18n(
"Chiasmus backend does not offer the "
3231 "\"x-obtain-keys\" function. Please report this bug." );
3232 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3236 if ( listjob->exec() ) {
3237 listjob->showErrorDialog( parentWidget(), i18n(
"Chiasmus Backend Error" ) );
3241 const TQVariant result = listjob->property(
"result" );
3242 if ( result.type() != TQVariant::StringList ) {
3243 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
3244 "The \"x-obtain-keys\" function did not return a "
3245 "string list. Please report this bug." );
3246 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3250 const TQStringList keys = result.toStringList();
3251 if ( keys.empty() ) {
3252 const TQString msg = i18n(
"No keys have been found. Please check that a "
3253 "valid key path has been set in the Chiasmus "
3255 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3259 ChiasmusKeySelector selectorDlg( parentWidget(), i18n(
"Chiasmus Decryption Key Selection" ),
3260 keys, GlobalSettings::chiasmusDecryptionKey(),
3261 GlobalSettings::chiasmusDecryptionOptions() );
3262 if ( selectorDlg.exec() != TQDialog::Accepted )
3265 GlobalSettings::setChiasmusDecryptionOptions( selectorDlg.options() );
3266 GlobalSettings::setChiasmusDecryptionKey( selectorDlg.key() );
3267 assert( !GlobalSettings::chiasmusDecryptionKey().isEmpty() );
3269 Kleo::SpecialJob * job = chiasmus->specialJob(
"x-decrypt", TQMap<TQString,TQVariant>() );
3271 const TQString msg = i18n(
"Chiasmus backend does not offer the "
3272 "\"x-decrypt\" function. Please report this bug." );
3273 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3277 const TQByteArray input = node->msgPart().bodyDecodedBinary();
3279 if ( !job->setProperty(
"key", GlobalSettings::chiasmusDecryptionKey() ) ||
3280 !job->setProperty(
"options", GlobalSettings::chiasmusDecryptionOptions() ) ||
3281 !job->setProperty(
"input", input ) ) {
3282 const TQString msg = i18n(
"The \"x-decrypt\" function does not accept "
3283 "the expected parameters. Please report this bug." );
3284 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3288 setDeletesItself(
true );
3289 if ( job->start() ) {
3290 job->showErrorDialog( parentWidget(), i18n(
"Chiasmus Decryption Error" ) );
3295 connect( job, TQT_SIGNAL(result(
const GpgME::Error&,
const TQVariant&)),
3296 this, TQT_SLOT(slotAtmDecryptWithChiasmusResult(
const GpgME::Error&,
const TQVariant&)) );
3299 static const TQString chomp(
const TQString & base,
const TQString & suffix,
bool cs ) {
3300 return base.endsWith( suffix, cs ) ? base.left( base.length() - suffix.length() ) : base ;
3303 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusResult(
const GpgME::Error & err,
const TQVariant & result )
3305 LaterDeleterWithCommandCompletion d(
this );
3308 Q_ASSERT( mJob == sender() );
3309 if ( mJob != sender() )
3311 Kleo::Job * job = mJob;
3313 if ( err.isCanceled() )
3316 job->showErrorDialog( parentWidget(), i18n(
"Chiasmus Decryption Error" ) );
3320 if ( result.type() != TQVariant::ByteArray ) {
3321 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
3322 "The \"x-decrypt\" function did not return a "
3323 "byte array. Please report this bug." );
3324 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3328 const KURL url = KFileDialog::getSaveURL( chomp( mAtmName,
".xia",
false ), TQString(), parentWidget() );
3329 if ( url.isEmpty() )
3332 bool overwrite = KMail::Util::checkOverwrite( url, parentWidget() );
3336 d.setDisabled(
true );
3337 KIO::Job * uploadJob = KIO::storedPut( result.toByteArray(), url, -1, overwrite,
false );
3338 uploadJob->setWindow( parentWidget() );
3339 connect( uploadJob, TQT_SIGNAL(result(KIO::Job*)),
3340 this, TQT_SLOT(slotAtmDecryptWithChiasmusUploadResult(KIO::Job*)) );
3343 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusUploadResult( KIO::Job * job )
3346 job->showErrorDialog();
3347 LaterDeleterWithCommandCompletion d(
this );
3352 AttachmentModifyCommand::AttachmentModifyCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3353 KMCommand( parent, msg ),
3354 mPartIndex( node->nodeId() ),
3359 AttachmentModifyCommand::AttachmentModifyCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3360 : KMCommand( parent, msg ),
3361 mPartIndex( nodeId ),
3366 AttachmentModifyCommand::~ AttachmentModifyCommand()
3370 KMCommand::Result AttachmentModifyCommand::execute()
3375 mSernum = msg->getMsgSerNum();
3377 mFolder = msg->parent();
3378 if ( !mFolder || !mFolder->storage() )
3381 Result res = doAttachmentModify();
3385 setEmitsCompletedItself(
true );
3386 setDeletesItself(
true );
3390 void AttachmentModifyCommand::storeChangedMessage(
KMMessage * msg)
3392 if ( !mFolder || !mFolder->storage() ) {
3393 kdWarning(5006) << k_funcinfo <<
"We lost the folder!" << endl;
3394 setResult( Failed );
3395 emit completed(
this );
3398 int res = mFolder->addMsg( msg ) != 0;
3399 if ( mFolder->folderType() == KMFolderTypeImap ) {
3400 KMFolderImap *f =
static_cast<KMFolderImap*
>( mFolder->storage() );
3401 connect( f, TQT_SIGNAL(folderComplete(KMFolderImap*,
bool)),
3402 TQT_SLOT(messageStoreResult(KMFolderImap*,
bool)) );
3404 messageStoreResult( 0, res == 0 );
3408 void AttachmentModifyCommand::messageStoreResult(KMFolderImap* folder,
bool success )
3412 KMCommand *delCmd =
new KMDeleteMsgCommand( mSernum );
3413 connect( delCmd, TQT_SIGNAL(completed(KMCommand*)), TQT_SLOT(messageDeleteResult(KMCommand*)) );
3417 kdWarning(5006) << k_funcinfo <<
"Adding modified message failed." << endl;
3418 setResult( Failed );
3419 emit completed(
this );
3423 void AttachmentModifyCommand::messageDeleteResult(KMCommand * cmd)
3425 setResult( cmd->result() );
3426 emit completed(
this );
3430 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3433 kdDebug(5006) << k_funcinfo << endl;
3436 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3439 kdDebug(5006) << k_funcinfo << endl;
3442 KMDeleteAttachmentCommand::~KMDeleteAttachmentCommand()
3444 kdDebug(5006) << k_funcinfo << endl;
3447 KMCommand::Result KMDeleteAttachmentCommand::doAttachmentModify()
3457 storeChangedMessage( newMsg );
3462 KMEditAttachmentCommand::KMEditAttachmentCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3465 kdDebug(5006) << k_funcinfo << endl;
3466 mTempFile.setAutoDelete(
true );
3469 KMEditAttachmentCommand::KMEditAttachmentCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3472 kdDebug(5006) << k_funcinfo << endl;
3473 mTempFile.setAutoDelete(
true );
3476 KMEditAttachmentCommand::~ KMEditAttachmentCommand()
3480 KMCommand::Result KMEditAttachmentCommand::doAttachmentModify()
3487 DwBodyPart *dwpart = msg->findPart( mPartIndex );
3491 if ( !part.isComplete() )
3494 if( !dynamic_cast<DwBody*>( dwpart->Parent() ) )
3497 mTempFile.file()->writeBlock( part.bodyDecodedBinary() );
3498 mTempFile.file()->flush();
3502 part.typeStr() +
"/" + part.subtypeStr(),
3503 false,
this, parentWidget() );
3505 if ( !watcher->start() )
3507 setEmitsCompletedItself(
true );
3508 setDeletesItself(
true );
3514 kdDebug(5006) << k_funcinfo << endl;
3516 if ( !watcher->fileChanged() ) {
3517 kdDebug(5006) << k_funcinfo <<
"File has not been changed" << endl;
3518 setResult( Canceled );
3519 emit completed(
this );
3523 mTempFile.file()->reset();
3524 TQByteArray data = mTempFile.file()->readAll();
3529 DwBodyPart *dwpart = msg->findPart( mPartIndex );
3532 DwBody *parentNode =
dynamic_cast<DwBody*
>( dwpart->Parent() );
3533 assert( parentNode );
3534 parentNode->RemoveBodyPart( dwpart );
3537 att.duplicate( part );
3538 att.setBodyEncodedBinary( data );
3541 parentNode->AddBodyPart( newDwPart );
3542 msg->getTopLevelPart()->Assemble();
3548 storeChangedMessage( newMsg );
3552 CreateTodoCommand::CreateTodoCommand(TQWidget * parent,
KMMessage * msg)
3553 : KMCommand( parent, msg )
3557 KMCommand::Result CreateTodoCommand::execute()
3560 if ( !msg || !msg->
codec() ) {
3564 KMail::KorgHelper::ensureRunning();
3566 TQString txt = i18n(
"From: %1\nTo: %2\nSubject: %3").arg( msg->
from() )
3567 .arg( msg->
to() ).arg( msg->
subject() );
3570 tf.setAutoDelete(
true );
3571 TQString uri =
"kmail:" + TQString::number( msg->getMsgSerNum() ) +
"/" + msg->
msgId();
3575 KCalendarIface_stub *iface =
new KCalendarIface_stub( kapp->dcopClient(),
"korganizer",
"CalendarIface" );
3576 iface->openTodoEditor( i18n(
"Mail: %1").arg( msg->
subject() ), txt, uri,
3577 tf.name(), TQStringList(),
"message/rfc822", true );
3583 #include "kmcommands.moc"