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 <tdeapplication.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 <tdefiledialog.h>
65 #include <tdeabc/stdaddressbook.h>
66 #include <tdeabc/addresseelist.h>
67 #include <kdirselectdialog.h>
68 #include <tdelocale.h>
69 #include <tdemessagebox.h>
70 #include <tdeparts/browserextension.h>
71 #include <kprogress.h>
73 #include <kbookmarkmanager.h>
74 #include <kstandarddirs.h>
75 #include <tdetempfile.h>
76 #include <tdeimproxy.h>
77 #include <kuserprofile.h>
79 #include <tdeio/job.h>
80 #include <tdeio/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 <libtdepim/tdefileio.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, TQ_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, TQ_SIGNAL( messagesTransfered( KMCommand::Result ) ),
229 this, TQ_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, TQ_SIGNAL( messagesTransfered( KMCommand::Result ) ),
265 this, TQ_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() )
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, TQ_SIGNAL(messageRetrieved(
KMMessage*)),
343 this, TQ_SLOT(slotMsgTransfered(
KMMessage*)));
345 connect(job, TQ_SIGNAL(finished()),
346 this, TQ_SLOT(slotJobFinished()));
347 connect(job, TQ_SIGNAL(progress(
unsigned long,
unsigned long)),
348 this, TQ_SLOT(slotProgress(
unsigned long,
unsigned long)));
354 mRetrievedMsgs.append(thisMsg);
360 delete mProgressDialog;
362 emit messagesTransfered( OK );
365 if ( mProgressDialog ) {
366 connect(mProgressDialog, TQ_SIGNAL(cancelClicked()),
367 this, TQ_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 ( TDEIO::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 TDEIO::Job *job = TDEIO::file_copy(mUrl, saveUrl, -1,
true);
648 connect(job, TQ_SIGNAL(result(TDEIO::Job*)), TQ_SLOT(slotUrlSaveResult(TDEIO::Job*)));
649 setEmitsCompletedItself(
true );
653 void KMUrlSaveCommand::slotUrlSaveResult( TDEIO::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(TDEGlobalSettings::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 = TDEIO::put( mUrl, S_IRUSR|S_IWUSR,
false,
false );
845 mJob->slotTotalSize( mTotalSize );
846 mJob->setAsyncDataEnabled(
true );
847 mJob->setReportDataSent(
true );
848 connect(mJob, TQ_SIGNAL(dataReq(TDEIO::Job*, TQByteArray &)),
849 TQ_SLOT(slotSaveDataReq()));
850 connect(mJob, TQ_SIGNAL(result(TDEIO::Job*)),
851 TQ_SLOT(slotSaveResult(TDEIO::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, TQ_SIGNAL( messageRetrieved(
KMMessage* ) ),
902 this, TQ_SLOT( slotMessageRetrievedForSaving(
KMMessage* ) ) );
907 mJob->slotError( TDEIO::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(TDEIO::Job *job)
962 if (job->error() == TDEIO::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 = TDEIO::put( mUrl, S_IRUSR|S_IWUSR,
true,
false );
971 mJob->slotTotalSize( mTotalSize );
972 mJob->setAsyncDataEnabled(
true );
973 mJob->setReportDataSent(
true );
974 connect(mJob, TQ_SIGNAL(dataReq(TDEIO::Job*, TQByteArray &)),
975 TQ_SLOT(slotSaveDataReq()));
976 connect(mJob, TQ_SIGNAL(result(TDEIO::Job*)),
977 TQ_SLOT(slotSaveResult(TDEIO::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 = TDEIO::get( mUrl,
false,
false );
1016 mJob->setReportDataSent(
true );
1017 connect( mJob, TQ_SIGNAL( data( TDEIO::Job *,
const TQByteArray & ) ),
1018 this, TQ_SLOT( slotDataArrived( TDEIO::Job*,
const TQByteArray & ) ) );
1019 connect( mJob, TQ_SIGNAL( result( TDEIO::Job * ) ),
1020 TQ_SLOT( slotResult( TDEIO::Job * ) ) );
1021 setEmitsCompletedItself(
true );
1025 void KMOpenMsgCommand::slotDataArrived( TDEIO::Job *,
const TQByteArray & data )
1027 if ( data.isEmpty() )
1030 mMsgString.append( data.data(), data.size() );
1033 void KMOpenMsgCommand::slotResult( TDEIO::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() ) {
1120 TQString accountName;
1121 KMFolder* parentFolder = msg->parent();
1123 KMFolderDir* parentFolderDir = parentFolder->parent();
1124 while (parentFolderDir) {
1125 TQString prettyURL = parentFolderDir->
prettyURL();
1126 if (prettyURL !=
"") {
1127 accountName = prettyURL;
1129 parentFolderDir = parentFolderDir->parent();
1133 KMMessage *reply = msg->
createReply( KMail::ReplySmart, mSelection,
false,
true, TQString(), accountName );
1134 KMail::Composer * win = KMail::makeComposer( reply );
1135 win->setCharset( msg->
codec()->mimeName(),
true );
1136 win->setReplyFocus();
1143 KMNoQuoteReplyToCommand::KMNoQuoteReplyToCommand( TQWidget *parent,
1145 : KMCommand( parent, msg )
1149 KMCommand::Result KMNoQuoteReplyToCommand::execute()
1153 if ( !msg || !msg->
codec() ) {
1157 KMail::Composer * win = KMail::makeComposer( reply );
1158 win->setCharset(msg->
codec()->mimeName(),
true);
1159 win->setReplyFocus(
false);
1166 KMReplyListCommand::KMReplyListCommand( TQWidget *parent,
1167 KMMessage *msg,
const TQString &selection )
1168 : KMCommand( parent, msg ), mSelection( selection )
1172 KMCommand::Result KMReplyListCommand::execute()
1176 if ( !msg || !msg->
codec() ) {
1180 KMail::Composer * win = KMail::makeComposer( reply );
1181 win->setCharset(msg->
codec()->mimeName(),
true);
1182 win->setReplyFocus(
false);
1189 KMReplyToAllCommand::KMReplyToAllCommand( TQWidget *parent,
1190 KMMessage *msg,
const TQString &selection )
1191 :KMCommand( parent, msg ), mSelection( selection )
1195 KMCommand::Result KMReplyToAllCommand::execute()
1199 if ( !msg || !msg->
codec() ) {
1203 KMail::Composer * win = KMail::makeComposer( reply );
1204 win->setCharset( msg->
codec()->mimeName(),
true );
1205 win->setReplyFocus();
1212 KMReplyAuthorCommand::KMReplyAuthorCommand( TQWidget *parent,
KMMessage *msg,
1213 const TQString &selection )
1214 : KMCommand( parent, msg ), mSelection( selection )
1218 KMCommand::Result KMReplyAuthorCommand::execute()
1222 if ( !msg || !msg->
codec() ) {
1226 KMail::Composer * win = KMail::makeComposer( reply );
1227 win->setCharset( msg->
codec()->mimeName(),
true );
1228 win->setReplyFocus();
1235 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
1236 const TQPtrList<KMMsgBase> &msgList, uint identity )
1237 : KMCommand( parent, msgList ),
1238 mIdentity( identity )
1242 KMForwardInlineCommand::KMForwardInlineCommand( TQWidget *parent,
1244 : KMCommand( parent, msg ),
1245 mIdentity( identity )
1249 KMCommand::Result KMForwardInlineCommand::execute()
1251 TQPtrList<KMMessage> msgList = retrievedMsgs();
1253 if (msgList.count() >= 2) {
1256 TQPtrList<KMMessage> linklist;
1257 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1260 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1263 linklist.append( msg );
1273 for (
KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
1275 parser.setSelection( msg->
body() );
1276 parser.process( msg, 0,
true );
1278 fwdMsg->
link( msg, KMMsgStatusForwarded );
1282 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1283 win->setCharset(
"");
1289 if ( !msg || !msg->
codec() )
1295 uint
id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1299 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1300 win->setCharset( fwdMsg->
codec()->mimeName(),
true );
1308 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
1309 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
1310 : KMCommand( parent, msgList ), mIdentity( identity ),
1311 mWin( TQGuardedPtr<
KMail::Composer>( win ))
1315 KMForwardAttachedCommand::KMForwardAttachedCommand( TQWidget *parent,
1316 KMMessage * msg, uint identity, KMail::Composer *win )
1317 : KMCommand( parent, msg ), mIdentity( identity ),
1318 mWin( TQGuardedPtr<
KMail::Composer >( win ))
1322 KMCommand::Result KMForwardAttachedCommand::execute()
1324 TQPtrList<KMMessage> msgList = retrievedMsgs();
1327 if (msgList.count() >= 2) {
1332 else if (msgList.count() == 1) {
1335 fwdMsg->setSubject( msg->forwardSubject() );
1342 mWin = KMail::makeComposer(fwdMsg, mIdentity);
1345 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next()) {
1350 KMMessagePart *msgPart =
new KMMessagePart;
1351 msgPart->setTypeStr(
"message");
1352 msgPart->setSubtypeStr(
"rfc822");
1353 msgPart->setName(
"forwarded message");
1354 msgPart->setContentDescription(msg->
from()+
": "+msg->
subject());
1355 msgPart->setContentDisposition(
"inline" );
1358 fwdMsg->
link(msg, KMMsgStatusForwarded);
1359 mWin->addAttach(msgPart);
1368 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
1369 const TQPtrList<KMMsgBase> &msgList, uint identity, KMail::Composer *win )
1370 : KMCommand( parent, msgList ), mIdentity( identity ),
1371 mWin( TQGuardedPtr<
KMail::Composer>( win ))
1375 KMForwardDigestCommand::KMForwardDigestCommand( TQWidget *parent,
1376 KMMessage * msg, uint identity, KMail::Composer *win )
1377 : KMCommand( parent, msg ), mIdentity( identity ),
1378 mWin( TQGuardedPtr<
KMail::Composer >( win ))
1382 KMCommand::Result KMForwardDigestCommand::execute()
1384 TQPtrList<KMMessage> msgList = retrievedMsgs();
1386 if ( msgList.count() < 2 )
1391 KMMessagePart *msgPart =
new KMMessagePart;
1392 TQString msgPartText;
1399 fwdMsg->mMsg->Headers().ContentType().CreateBoundary( 1 );
1400 TQCString boundary( fwdMsg->mMsg->Headers().ContentType().Boundary().c_str() );
1401 msgPartText = i18n(
"\nThis is a MIME digest forward. The content of the"
1402 " message is contained in the attachment(s).\n\n\n");
1404 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1407 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1409 msgPartText +=
"--";
1410 msgPartText += TQString::fromLatin1( boundary );
1411 msgPartText +=
"\nContent-Type: MESSAGE/RFC822";
1412 msgPartText += TQString(
"; CHARSET=%1" ).arg( TQString(msg->
charset()) );
1413 msgPartText +=
'\n';
1415 dwh.MessageId().CreateDefault();
1416 msgPartText += TQString(
"Content-ID: %1\n" ).arg( dwh.MessageId().AsString().c_str() );
1417 msgPartText += TQString(
"Content-Description: %1" ).arg( msg->
subject() );
1418 if ( !msg->
subject().contains(
"(fwd)" ) )
1419 msgPartText +=
" (fwd)";
1420 msgPartText +=
"\n\n";
1426 msgPartText +=
'\n';
1427 msgPartText += msg->
body();
1428 msgPartText +=
'\n';
1430 fwdMsg->
link( msg, KMMsgStatusForwarded );
1436 msgPartText +=
"--";
1437 msgPartText += TQString::fromLatin1( boundary );
1438 msgPartText +=
"--\n";
1440 msgPart->setTypeStr(
"MULTIPART" );
1441 tmp.sprintf(
"Digest; boundary=\"%s\"", boundary.data() );
1442 msgPart->setSubtypeStr( tmp );
1443 msgPart->setName(
"unnamed" );
1444 msgPart->setCte( DwMime::kCte7bit );
1445 msgPart->setContentDescription( TQString(
"Digest of %1 messages." ).arg( msgCnt ) );
1447 msgPart->setBodyEncoded( TQCString( msgPartText.ascii() ) );
1449 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1450 win->addAttach( msgPart );
1455 KMRedirectCommand::KMRedirectCommand( TQWidget *parent,
1457 : KMCommand( parent, msg )
1461 KMCommand::Result KMRedirectCommand::execute()
1464 if ( !msg || !msg->
codec() )
1468 kmkernel->msgSender()->sendImmediate() );
1469 if (dlg.exec()==TQDialog::Rejected)
return Failed;
1474 const KMail::MessageSender::SendMethod method = dlg.sendImmediate()
1475 ? KMail::MessageSender::SendImmediate
1476 : KMail::MessageSender::SendLater;
1477 if ( !kmkernel->msgSender()->send( newMsg, method ) ) {
1478 kdDebug(5006) <<
"KMRedirectCommand: could not redirect message (sending failed)" << endl;
1485 KMCustomReplyToCommand::KMCustomReplyToCommand( TQWidget *parent,
KMMessage *msg,
1486 const TQString &selection,
1487 const TQString &tmpl )
1488 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
1492 KMCommand::Result KMCustomReplyToCommand::execute()
1496 if ( !msg || !msg->
codec() ) {
1500 false,
true, mTemplate );
1501 KMail::Composer * win = KMail::makeComposer( reply );
1502 win->setCharset( msg->
codec()->mimeName(),
true );
1503 win->setReplyFocus();
1510 KMCustomReplyAllToCommand::KMCustomReplyAllToCommand( TQWidget *parent,
KMMessage *msg,
1511 const TQString &selection,
1512 const TQString &tmpl )
1513 : KMCommand( parent, msg ), mSelection( selection ), mTemplate( tmpl )
1517 KMCommand::Result KMCustomReplyAllToCommand::execute()
1521 if ( !msg || !msg->
codec() ) {
1525 false,
true, mTemplate );
1526 KMail::Composer * win = KMail::makeComposer( reply );
1527 win->setCharset( msg->
codec()->mimeName(),
true );
1528 win->setReplyFocus();
1535 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
1536 const TQPtrList<KMMsgBase> &msgList, uint identity,
const TQString &tmpl )
1537 : KMCommand( parent, msgList ),
1538 mIdentity( identity ), mTemplate( tmpl )
1542 KMCustomForwardCommand::KMCustomForwardCommand( TQWidget *parent,
1543 KMMessage *msg, uint identity,
const TQString &tmpl )
1544 : KMCommand( parent, msg ),
1545 mIdentity( identity ), mTemplate( tmpl )
1549 KMCommand::Result KMCustomForwardCommand::execute()
1551 TQPtrList<KMMessage> msgList = retrievedMsgs();
1553 if (msgList.count() >= 2) {
1556 TQPtrList<KMMessage> linklist;
1557 for (
KMMessage *msg = msgList.first(); msg; msg = msgList.next() ) {
1560 id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1563 linklist.append( msg );
1573 for (
KMMessage *msg = linklist.first(); msg; msg = linklist.next() ) {
1575 parser.setSelection( msg->
body() );
1576 parser.process( msg, 0,
true );
1578 fwdMsg->
link( msg, KMMsgStatusForwarded );
1582 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1583 win->setCharset(
"");
1589 if ( !msg || !msg->
codec() )
1595 uint
id = msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt();
1599 KMail::Composer * win = KMail::makeComposer( fwdMsg,
id );
1600 win->setCharset( fwdMsg->
codec()->mimeName(),
true );
1608 KMPrintCommand::KMPrintCommand( TQWidget *parent,
KMMessage *msg,
1610 const KMail::HeaderStrategy *headerStrategy,
1611 bool htmlOverride,
bool htmlLoadExtOverride,
1612 bool useFixedFont,
const TQString & encoding )
1613 : KMCommand( parent, msg ),
1614 mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ),
1615 mHtmlOverride( htmlOverride ),
1616 mHtmlLoadExtOverride( htmlLoadExtOverride ),
1617 mUseFixedFont( useFixedFont ), mEncoding( encoding )
1619 if ( GlobalSettings::useDefaultFonts() )
1620 mOverrideFont = TDEGlobalSettings::generalFont();
1622 TDEConfigGroup fonts( KMKernel::config(),
"Fonts" );
1623 TQString tmp = fonts.readEntry(
"print-font", TDEGlobalSettings::generalFont().toString() );
1624 mOverrideFont.fromString( tmp );
1629 void KMPrintCommand::setOverrideFont(
const TQFont& font )
1631 mOverrideFont = font;
1634 KMCommand::Result KMPrintCommand::execute()
1637 printWin.setPrinting(
true );
1638 printWin.readConfig();
1639 if ( mHeaderStyle != 0 && mHeaderStrategy != 0 )
1640 printWin.setHeaderStyleAndStrategy( mHeaderStyle, mHeaderStrategy );
1641 printWin.setHtmlOverride( mHtmlOverride );
1642 printWin.setHtmlLoadExtOverride( mHtmlLoadExtOverride );
1643 printWin.setUseFixedFont( mUseFixedFont );
1644 printWin.setOverrideEncoding( mEncoding );
1645 printWin.cssHelper()->setPrintFont( mOverrideFont );
1646 printWin.setDecryptMessageOverwrite(
true );
1647 printWin.setMsg( retrievedMessage(),
true );
1648 printWin.printMsg();
1654 KMSeStatusCommand::KMSeStatusCommand( KMMsgStatus status,
1655 const TQValueList<TQ_UINT32> &serNums,
bool toggle )
1656 : mStatus( status ), mSerNums( serNums ), mToggle( toggle )
1660 KMCommand::Result KMSeStatusCommand::execute()
1662 TQValueListIterator<TQ_UINT32> it;
1665 bool parenStatus =
false;
1674 if (msg && (msg->status()&mStatus))
1677 parenStatus =
false;
1680 TQMap< KMFolder*, TQValueList<int> > folderMap;
1681 for ( it = mSerNums.begin(); it != mSerNums.end(); ++it ) {
1689 if (msg->status()&mStatus)
1693 if (myStatus != parenStatus)
1699 folderMap[folder].append(idx);
1702 TQMapIterator< KMFolder*, TQValueList<int> > it2 = folderMap.begin();
1703 while ( it2 != folderMap.end() ) {
1705 f->
setStatus( (*it2), mStatus, mToggle );
1714 KMFilterCommand::KMFilterCommand(
const TQCString &field,
const TQString &value )
1715 : mField( field ), mValue( value )
1719 KMCommand::Result KMFilterCommand::execute()
1721 kmkernel->filterMgr()->createFilter( mField, mValue );
1727 KMFilterActionCommand::KMFilterActionCommand( TQWidget *parent,
1728 const TQPtrList<KMMsgBase> &msgList,
1730 : KMCommand( parent, msgList ), mFilter( filter )
1732 TQPtrListIterator<KMMsgBase> it(msgList);
1733 while ( it.current() ) {
1734 serNumList.append( (*it)->getMsgSerNum() );
1739 KMCommand::Result KMFilterActionCommand::execute()
1744 int msgCountToFilter = serNumList.count();
1745 ProgressItem* progressItem =
1746 ProgressManager::createProgressItem (
"filter"+ProgressManager::getUniqueID(),
1747 i18n(
"Filtering messages" ) );
1748 progressItem->setTotalItems( msgCountToFilter );
1749 TQValueList<TQ_UINT32>::const_iterator it;
1750 for ( it = serNumList.begin(); it != serNumList.end(); it++ ) {
1751 TQ_UINT32 serNum = *it;
1752 int diff = msgCountToFilter - ++msgCount;
1753 if ( diff < 10 || !( msgCount % 20 ) || msgCount <= 10 ) {
1754 progressItem->updateProgress();
1755 TQString statusMsg = i18n(
"Filtering message %1 of %2");
1756 statusMsg = statusMsg.arg( msgCount ).arg( msgCountToFilter );
1757 KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
1758 TDEApplication::kApplication()->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput, 50 );
1761 int filterResult = kmkernel->filterMgr()->process( serNum, mFilter );
1762 if (filterResult == 2) {
1764 perror(
"Critical error");
1765 kmkernel->emergencyExit( i18n(
"Not enough free disk space?" ));
1767 progressItem->incCompletedItems();
1770 progressItem->setComplete();
1776 KMMetaFilterActionCommand::KMMetaFilterActionCommand( KMFilter *filter,
1778 KMMainWidget *main )
1780 mFilter( filter ), mHeaders( headers ), mMainWidget( main )
1784 void KMMetaFilterActionCommand::start()
1786 if (ActionScheduler::isEnabled() ) {
1788 KMFilterMgr::FilterSet set = KMFilterMgr::All;
1789 TQValueList<KMFilter*> filters;
1790 filters.append( mFilter );
1791 ActionScheduler *scheduler =
new ActionScheduler( set, filters, mHeaders );
1792 scheduler->setAlwaysMatch(
true );
1793 scheduler->setAutoDestruct(
true );
1795 int contentX, contentY;
1796 HeaderItem *nextItem = mHeaders->prepareMove( &contentX, &contentY );
1797 TQPtrList<KMMsgBase> msgList = *mHeaders->selectedMsgs(
true);
1798 mHeaders->finalizeMove( nextItem, contentX, contentY );
1800 for (KMMsgBase *msg = msgList.first(); msg; msg = msgList.next())
1801 scheduler->execFilters( msg );
1803 KMCommand *filterCommand =
1804 new KMFilterActionCommand( mMainWidget,
1805 *mHeaders->selectedMsgs(), mFilter );
1806 filterCommand->start();
1807 int contentX, contentY;
1808 HeaderItem *item = mHeaders->prepareMove( &contentX, &contentY );
1809 mHeaders->finalizeMove( item, contentX, contentY );
1813 FolderShortcutCommand::FolderShortcutCommand( KMMainWidget *mainwidget,
1815 : mMainWidget( mainwidget ), mFolder( folder ), mAction( 0 )
1820 FolderShortcutCommand::~FolderShortcutCommand()
1822 if ( mAction ) mAction->unplugAll();
1826 void FolderShortcutCommand::start()
1828 mMainWidget->slotSelectFolder( mFolder );
1831 void FolderShortcutCommand::setAction( TDEAction* action )
1836 KMMailingListFilterCommand::KMMailingListFilterCommand( TQWidget *parent,
1838 : KMCommand( parent, msg )
1842 KMCommand::Result KMMailingListFilterCommand::execute()
1850 if ( !MailingList::name( msg, name, value ).isEmpty() ) {
1851 kmkernel->filterMgr()->createFilter( name, value );
1859 void KMMenuCommand::folderToPopupMenu(
bool move,
1860 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
1862 while ( menu->count() )
1864 TQPopupMenu *popup = menu->findItem( menu->idAt( 0 ) )->popup();
1868 menu->removeItemAt( 0 );
1871 if (!kmkernel->imapFolderMgr()->dir().first() &&
1872 !kmkernel->dimapFolderMgr()->dir().first())
1874 makeFolderMenu( &kmkernel->folderMgr()->dir(), move,
1875 receiver, aMenuToFolder, menu );
1878 TQPopupMenu* subMenu =
new TQPopupMenu(menu);
1879 makeFolderMenu( &kmkernel->folderMgr()->dir(),
1880 move, receiver, aMenuToFolder, subMenu );
1881 menu->insertItem( i18n(
"Local Folders" ), subMenu );
1882 KMFolderDir* fdir = &kmkernel->imapFolderMgr()->dir();
1883 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
1886 subMenu =
new TQPopupMenu(menu);
1887 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
1888 menu->insertItem( node->label(), subMenu );
1890 fdir = &kmkernel->dimapFolderMgr()->dir();
1891 for (KMFolderNode *node = fdir->first(); node; node = fdir->next()) {
1894 subMenu =
new TQPopupMenu(menu);
1895 makeFolderMenu( node, move, receiver, aMenuToFolder, subMenu );
1896 menu->insertItem( node->label(), subMenu );
1901 void KMMenuCommand::makeFolderMenu(KMFolderNode* node,
bool move,
1902 TQObject *receiver, KMMenuToFolder *aMenuToFolder, TQPopupMenu *menu )
1907 disconnect(menu, TQ_SIGNAL(activated(
int)), receiver,
1908 TQ_SLOT(moveSelectedToFolder(
int)));
1909 connect(menu, TQ_SIGNAL(activated(
int)), receiver,
1910 TQ_SLOT(moveSelectedToFolder(
int)));
1912 disconnect(menu, TQ_SIGNAL(activated(
int)), receiver,
1913 TQ_SLOT(copySelectedToFolder(
int)));
1914 connect(menu, TQ_SIGNAL(activated(
int)), receiver,
1915 TQ_SLOT(copySelectedToFolder(
int)));
1920 if (node->isDir()) {
1923 folder =
static_cast<KMFolder*
>(node);
1924 folderDir = folder->
child();
1931 menuId = menu->insertItem(i18n(
"Move to This Folder"));
1933 menuId = menu->insertItem(i18n(
"Copy to This Folder"));
1934 aMenuToFolder->insert( menuId, folder );
1935 menu->setItemEnabled( menuId, !folder->
isReadOnly() );
1936 menu->insertSeparator();
1942 for (KMFolderNode *it = folderDir->first(); it; it = folderDir->next() ) {
1946 TQString label = child->
label();
1947 label.replace(
"&",
"&&");
1948 if (child->
child() && child->
child()->first()) {
1950 TQPopupMenu *subMenu =
new TQPopupMenu(menu,
"subMenu");
1951 makeFolderMenu( child, move, receiver,
1952 aMenuToFolder, subMenu );
1953 menu->insertItem( label, subMenu );
1956 int menuId = menu->insertItem( label );
1957 aMenuToFolder->insert( menuId, child );
1958 menu->setItemEnabled( menuId, !child->
isReadOnly() );
1965 KMCopyCommand::KMCopyCommand(
KMFolder* destFolder,
1966 const TQPtrList<KMMsgBase> &msgList )
1967 :mDestFolder( destFolder ), mMsgList( msgList )
1969 setDeletesItself(
true );
1973 :mDestFolder( destFolder )
1975 setDeletesItself(
true );
1979 KMCommand::Result KMCopyCommand::execute()
1985 TQPtrList<KMMessage> list;
1986 TQPtrList<KMMessage> localList;
1988 if (mDestFolder && mDestFolder->open(
"kmcommand") != 0)
1994 setEmitsCompletedItself(
true );
1997 for (msgBase = mMsgList.first(); msgBase; msgBase = mMsgList.next() )
1999 KMFolder *srcFolder = msgBase->parent();
2000 if (( isMessage = msgBase->isMessage() ))
2004 idx = srcFolder->
find(msgBase);
2006 msg = srcFolder->
getMsg(idx);
2009 KMessageBox::error( parentWidget(), i18n(
"Corrupt IMAP cache detected in folder %1. "
2010 "Copying of messages aborted.").arg( srcFolder->
prettyURL() ) );
2016 if (srcFolder && mDestFolder &&
2017 (srcFolder->
folderType()== KMFolderTypeImap) &&
2018 (mDestFolder->folderType() == KMFolderTypeImap) &&
2019 (
static_cast<KMFolderImap*
>(srcFolder->storage())->account() ==
2020 static_cast<KMFolderImap*
>(mDestFolder->storage())->account()))
2025 newMsg =
new KMMessage(
new DwMessage( *msg->asDwMessage() ) );
2035 newMsg->setParent(msg->parent());
2036 FolderJob *job = srcFolder->
createJob(newMsg);
2037 job->setCancellable(
false );
2038 mPendingJobs << job;
2039 connect(job, TQ_SIGNAL(messageRetrieved(
KMMessage*)),
2040 mDestFolder, TQ_SLOT(reallyAddCopyOfMsg(
KMMessage*)));
2041 connect( job, TQ_SIGNAL(result(KMail::FolderJob*)),
2042 this, TQ_SLOT(slotJobFinished(KMail::FolderJob*)) );
2046 localList.append(newMsg);
2050 if (srcFolder && !isMessage && list.isEmpty())
2058 bool deleteNow =
false;
2059 if (!localList.isEmpty())
2061 TQValueList<int> index;
2062 mDestFolder->addMsg( localList, index );
2063 for ( TQValueListIterator<int> it = index.begin(); it != index.end(); ++it ) {
2064 mDestFolder->unGetMsg( *it );
2066 if ( mDestFolder->folderType() == KMFolderTypeImap ) {
2067 if ( mPendingJobs.isEmpty() ) {
2069 KMFolderImap *imapDestFolder =
static_cast<KMFolderImap*
>(mDestFolder->storage());
2070 connect( imapDestFolder, TQ_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
2071 this, TQ_SLOT( slotFolderComplete( KMFolderImap*,
bool ) ) );
2074 deleteNow = list.isEmpty() && mPendingJobs.isEmpty();
2080 if (!list.isEmpty())
2083 KMFolderImap *imapDestFolder =
static_cast<KMFolderImap*
>(mDestFolder->storage());
2084 connect( imapDestFolder, TQ_SIGNAL( folderComplete( KMFolderImap*,
bool ) ),
2085 this, TQ_SLOT( slotFolderComplete( KMFolderImap*,
bool ) ) );
2086 imapDestFolder->copyMsg(list);
2087 imapDestFolder->getFolder();
2094 mDestFolder->close(
"kmcommand");
2096 emit completed(
this );
2103 void KMCopyCommand::slotJobFinished(KMail::FolderJob * job)
2105 mPendingJobs.remove( job );
2106 if ( job->error() ) {
2107 kdDebug(5006) << k_funcinfo <<
"folder job failed: " << job->error() << endl;
2109 for ( TQValueList<KMail::FolderJob*>::Iterator it = mPendingJobs.begin(); it != mPendingJobs.end(); ++it ) {
2110 disconnect( (*it), TQ_SIGNAL(result(KMail::FolderJob*)),
2111 this, TQ_SLOT(slotJobFinished(KMail::FolderJob*)) );
2114 mPendingJobs.clear();
2115 setResult( Failed );
2118 if ( mPendingJobs.isEmpty() )
2120 mDestFolder->close(
"kmcommand");
2121 emit completed(
this );
2126 void KMCopyCommand::slotFolderComplete( KMFolderImap*,
bool success )
2128 kdDebug(5006) << k_funcinfo << success << endl;
2130 setResult( Failed );
2131 mDestFolder->close(
"kmcommand" );
2132 emit completed(
this );
2137 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2138 const TQPtrList<KMMsgBase> &msgList)
2139 : mDestFolder( destFolder ), mProgressItem( 0 )
2141 TQPtrList<KMMsgBase> tmp = msgList;
2142 for ( KMMsgBase *msgBase = tmp.first(); msgBase; msgBase = tmp.next() )
2143 mSerNumList.append( msgBase->getMsgSerNum() );
2146 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2148 : mDestFolder( destFolder ), mProgressItem( 0 )
2150 mSerNumList.append( msg->getMsgSerNum() );
2153 KMMoveCommand::KMMoveCommand(
KMFolder* destFolder,
2154 KMMsgBase *msgBase )
2155 : mDestFolder( destFolder ), mProgressItem( 0 )
2157 mSerNumList.append( msgBase->getMsgSerNum() );
2160 KMMoveCommand::KMMoveCommand( TQ_UINT32 )
2161 : mProgressItem( 0 )
2165 KMCommand::Result KMMoveCommand::execute()
2167 setEmitsCompletedItself(
true );
2168 setDeletesItself(
true );
2169 typedef TQMap< KMFolder*, TQPtrList<KMMessage>* > FolderToMessageListMap;
2170 FolderToMessageListMap folderDeleteList;
2172 if (mDestFolder && mDestFolder->open(
"kmcommand") != 0) {
2173 completeMove( Failed );
2179 Q_ASSERT( !mProgressItem );
2181 ProgressManager::createProgressItem (
2182 "move"+ProgressManager::getUniqueID(),
2183 mDestFolder ? i18n(
"Moving messages" ) : i18n(
"Deleting messages" ) );
2184 connect( mProgressItem, TQ_SIGNAL( progressItemCanceled( KPIM::ProgressItem* ) ),
2185 this, TQ_SLOT( slotMoveCanceled() ) );
2190 TQPtrList<KMMessage> list;
2192 mCompleteWithAddedMsg =
false;
2195 connect (mDestFolder, TQ_SIGNAL(msgAdded(
KMFolder*, TQ_UINT32)),
2196 this, TQ_SLOT(slotMsgAddedToDestFolder(
KMFolder*, TQ_UINT32)));
2197 mLostBoys = mSerNumList;
2199 mProgressItem->setTotalItems( mSerNumList.count() );
2201 for ( TQValueList<TQ_UINT32>::ConstIterator it = mSerNumList.constBegin(); it != mSerNumList.constEnd(); ++it ) {
2203 kdDebug(5006) << k_funcinfo <<
"serial number == 0!" << endl;
2209 if (srcFolder == mDestFolder)
2214 srcFolder->
open(
"kmmovecommand" );
2215 mOpenedFolders.append( srcFolder );
2217 msg = srcFolder->
getMsg(idx);
2219 kdDebug(5006) << k_funcinfo <<
"No message found for serial number " << *it << endl;
2222 bool undo = msg->enableUndo();
2225 srcFolder->
folderType() == KMFolderTypeImap )
2229 static_cast<KMFolderImap*
>(srcFolder->storage())->ignoreJobsForMessage( msg );
2233 if (mDestFolder->folderType() == KMFolderTypeImap) {
2237 KMFolderImap *imapFolder =
static_cast<KMFolderImap*
> ( mDestFolder->storage() );
2238 disconnect (imapFolder, TQ_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2239 this, TQ_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2241 connect (imapFolder, TQ_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2242 this, TQ_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2246 if ( srcFolder->
folderType() == KMFolderTypeImap )
2249 mCompleteWithAddedMsg =
true;
2251 rc = mDestFolder->moveMsg(msg, &index);
2252 if (rc == 0 && index != -1) {
2253 KMMsgBase *mb = mDestFolder->unGetMsg( mDestFolder->count() - 1 );
2257 undoId = kmkernel->undoStack()->newUndoAction( srcFolder, mDestFolder );
2258 kmkernel->undoStack()->addMsgToAction( undoId, mb->getMsgSerNum() );
2260 }
else if (rc != 0) {
2263 completeMove( Failed );
2270 if (srcFolder->
folderType() == KMFolderTypeImap) {
2271 if (!folderDeleteList[srcFolder])
2272 folderDeleteList[srcFolder] =
new TQPtrList<KMMessage>;
2273 folderDeleteList[srcFolder]->append( msg );
2275 srcFolder->removeMsg(idx);
2280 if (!list.isEmpty() && mDestFolder) {
2282 mDestFolder->moveMsg(list, &index);
2284 FolderToMessageListMap::Iterator it;
2285 for ( it = folderDeleteList.begin(); it != folderDeleteList.end(); ++it ) {
2286 it.key()->removeMsg(*it.data());
2289 if ( !mCompleteWithAddedMsg ) {
2298 void KMMoveCommand::slotImapFolderCompleted(KMFolderImap* imapFolder,
bool success)
2300 disconnect (imapFolder, TQ_SIGNAL(folderComplete( KMFolderImap*,
bool )),
2301 this, TQ_SLOT(slotImapFolderCompleted( KMFolderImap*,
bool )));
2309 if ( !mLostBoys.isEmpty() ) {
2310 kdDebug(5006) <<
"### Not all moved messages reported back that they were " << endl
2311 <<
"### added to the target folder. Did uidValidity change? " << endl;
2316 completeMove( Failed );
2320 void KMMoveCommand::slotMsgAddedToDestFolder(
KMFolder *folder, TQ_UINT32 serNum)
2322 if ( folder != mDestFolder || mLostBoys.find( serNum ) == mLostBoys.end() ) {
2327 mLostBoys.remove(serNum);
2328 if ( mLostBoys.isEmpty() ) {
2330 disconnect (mDestFolder, TQ_SIGNAL(msgAdded(
KMFolder*, TQ_UINT32)),
2331 this, TQ_SLOT(slotMsgAddedToDestFolder(
KMFolder*, TQ_UINT32)));
2332 if (mDestFolder && mDestFolder->folderType() != KMFolderTypeImap) {
2333 mDestFolder->sync();
2335 if ( mCompleteWithAddedMsg ) {
2339 if ( mProgressItem ) {
2340 mProgressItem->incCompletedItems();
2341 mProgressItem->updateProgress();
2346 void KMMoveCommand::completeMove( Result result )
2349 mDestFolder->close(
"kmcommand");
2350 while ( !mOpenedFolders.empty() ) {
2351 KMFolder *folder = mOpenedFolders.back();
2352 mOpenedFolders.pop_back();
2353 folder->
close(
"kmcommand");
2355 if ( mProgressItem ) {
2356 mProgressItem->setComplete();
2359 setResult( result );
2360 emit completed(
this );
2364 void KMMoveCommand::slotMoveCanceled()
2366 completeMove( Canceled );
2370 KMDeleteMsgCommand::KMDeleteMsgCommand(
KMFolder* srcFolder,
2371 const TQPtrList<KMMsgBase> &msgList )
2372 :KMMoveCommand( findTrashFolder( srcFolder ), msgList)
2374 srcFolder->
open(
"kmcommand");
2375 mOpenedFolders.push_back( srcFolder );
2379 :KMMoveCommand( findTrashFolder( srcFolder ), msg)
2381 srcFolder->
open(
"kmcommand");
2382 mOpenedFolders.push_back( srcFolder );
2385 KMDeleteMsgCommand::KMDeleteMsgCommand( TQ_UINT32 sernum )
2386 :KMMoveCommand( sernum )
2397 KMMsgBase *msg = srcFolder->
getMsgBase( idx );
2398 srcFolder->
open(
"kmcommand");
2399 mOpenedFolders.push_back( srcFolder );
2402 setDestFolder( findTrashFolder( srcFolder ) );
2409 trash = kmkernel->trashFolder();
2410 if( trash != folder )
2416 KMUrlClickedCommand::KMUrlClickedCommand(
const KURL &url, uint identity,
2417 KMReaderWin *readerWin,
bool htmlPref, KMMainWidget *mainWidget )
2418 :mUrl( url ), mIdentity( identity ), mReaderWin( readerWin ),
2419 mHtmlPref( htmlPref ), mMainWidget( mainWidget )
2423 KMCommand::Result KMUrlClickedCommand::execute()
2427 if (mUrl.protocol() ==
"mailto")
2433 TQString query=mUrl.query();
2434 while (!query.isEmpty()) {
2436 int secondQuery = query.find(
'?',1);
2437 if (secondQuery != -1)
2438 queryPart = query.left(secondQuery);
2441 query = query.mid(queryPart.length());
2443 if (queryPart.left(9) ==
"?subject=")
2444 msg->setSubject( KURL::decode_string(queryPart.mid(9)) );
2445 else if (queryPart.left(6) ==
"?body=")
2448 msg->
setBody( KURL::decode_string(queryPart.mid(6)).latin1() );
2449 else if (queryPart.left(4) ==
"?cc=")
2450 msg->setCc( KURL::decode_string(queryPart.mid(4)) );
2453 KMail::Composer * win = KMail::makeComposer( msg, mIdentity );
2454 win->setCharset(
"",
true);
2457 else if ( mUrl.protocol() ==
"im" )
2459 kmkernel->imProxy()->chatWithContact( mUrl.path() );
2461 else if ((mUrl.protocol() ==
"http") || (mUrl.protocol() ==
"https") ||
2462 (mUrl.protocol() ==
"ftp") || (mUrl.protocol() ==
"file") ||
2463 (mUrl.protocol() ==
"ftps") || (mUrl.protocol() ==
"sftp" ) ||
2464 (mUrl.protocol() ==
"help") || (mUrl.protocol() ==
"vnc") ||
2465 (mUrl.protocol() ==
"smb") || (mUrl.protocol() ==
"fish") ||
2466 (mUrl.protocol() ==
"news"))
2468 KPIM::BroadcastStatus::instance()->setStatusMsg( i18n(
"Opening URL..."));
2469 KMimeType::Ptr mime = KMimeType::findByURL( mUrl );
2470 if (mime->name() ==
"application/x-desktop" ||
2471 mime->name() ==
"application/x-executable" ||
2472 mime->name() ==
"application/x-msdos-program" ||
2473 mime->name() ==
"application/x-shellscript" )
2475 if (KMessageBox::warningYesNo( 0, i18n(
"<qt>Do you really want to execute <b>%1</b>?</qt>" )
2476 .arg( mUrl.prettyURL() ), TQString(), i18n(
"Execute"), KStdGuiItem::cancel() ) != KMessageBox::Yes)
2479 KRun * runner =
new KRun( mUrl );
2480 runner->setRunExecutables(
false );
2488 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent,
KMMessage *msg )
2489 : KMCommand( parent, msg ), mImplicitAttachments( true ), mEncoded( false )
2493 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent,
const TQPtrList<KMMsgBase>& msgs )
2494 : KMCommand( parent, msgs ), mImplicitAttachments( true ), mEncoded( false )
2498 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( TQWidget *parent, TQPtrList<partNode>& attachments,
2500 : KMCommand( parent ), mImplicitAttachments( false ), mEncoded( encoded )
2502 for ( TQPtrListIterator<partNode> it( attachments ); it.current(); ++it ) {
2503 mAttachmentMap.insert( it.current(), msg );
2507 KMCommand::Result KMSaveAttachmentsCommand::execute()
2509 setEmitsCompletedItself(
true );
2510 if ( mImplicitAttachments ) {
2511 TQPtrList<KMMessage> msgList = retrievedMsgs();
2513 for ( TQPtrListIterator<KMMessage> itr( msgList );
2514 ( msg = itr.current() );
2516 partNode *rootNode = partNode::fromMessage( msg );
2517 for ( partNode *child = rootNode; child;
2518 child = child->firstChild() ) {
2519 for ( partNode *node = child; node; node = node->nextSibling() ) {
2520 if ( node->type() != DwMime::kTypeMultipart )
2521 mAttachmentMap.insert( node, msg );
2526 setDeletesItself(
true );
2528 KMLoadPartsCommand *command =
new KMLoadPartsCommand( mAttachmentMap );
2529 connect( command, TQ_SIGNAL( partsRetrieved() ),
2530 this, TQ_SLOT( slotSaveAll() ) );
2536 void KMSaveAttachmentsCommand::slotSaveAll()
2541 if ( mImplicitAttachments ) {
2542 for ( PartNodeMessageMap::iterator it = mAttachmentMap.begin();
2543 it != mAttachmentMap.end(); ) {
2547 if ( it.key()->msgPart().fileName().stripWhiteSpace().isEmpty() &&
2548 ( it.key()->msgPart().name().stripWhiteSpace().isEmpty() ||
2549 !it.key()->parentNode() ) ) {
2550 PartNodeMessageMap::iterator delIt = it;
2552 mAttachmentMap.remove( delIt );
2557 if ( mAttachmentMap.isEmpty() ) {
2558 KMessageBox::information( 0, i18n(
"Found no attachments to save.") );
2560 emit completed(
this );
2567 if ( mAttachmentMap.count() > 1 ) {
2569 dirUrl = KDirSelectDialog::selectDirectory( TQString(),
false,
2571 i18n(
"Save Attachments To") );
2572 if ( !dirUrl.isValid() ) {
2573 setResult( Canceled );
2574 emit completed(
this );
2580 dirUrl.adjustPath( 1 );
2584 partNode *node = mAttachmentMap.begin().key();
2587 node->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
2589 s = node->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
2591 s = i18n(
"filename for an unnamed attachment",
"attachment.1");
2592 url = KFileDialog::getSaveURL( s, TQString(), parentWidget(),
2594 if ( url.isEmpty() ) {
2595 setResult( Canceled );
2596 emit completed(
this );
2602 TQMap< TQString, int > renameNumbering;
2604 Result globalResult = OK;
2605 int unnamedAtmCount = 0;
2606 for ( PartNodeMessageMap::const_iterator it = mAttachmentMap.begin();
2607 it != mAttachmentMap.end();
2610 if ( !dirUrl.isEmpty() ) {
2613 it.key()->msgPart().fileName().stripWhiteSpace().replace(
':',
'_' );
2615 s = it.key()->msgPart().name().stripWhiteSpace().replace(
':',
'_' );
2616 if ( s.isEmpty() ) {
2618 s = i18n(
"filename for the %1-th unnamed attachment",
2620 .arg( unnamedAtmCount );
2622 curUrl.setFileName( s );
2627 if ( !curUrl.isEmpty() ) {
2631 TQString origFile = curUrl.fileName();
2632 TQString file = origFile;
2634 while ( renameNumbering.contains(file) ) {
2636 int num = renameNumbering[file] + 1;
2637 int dotIdx = file.findRev(
'.');
2638 file = file.insert( (dotIdx>=0) ? dotIdx : file.length(), TQString(
"_") + TQString::number(num) );
2640 curUrl.setFileName(file);
2643 if ( !renameNumbering.contains(origFile))
2644 renameNumbering[origFile] = 1;
2646 renameNumbering[origFile]++;
2648 if ( file != origFile ) {
2649 if ( !renameNumbering.contains(file))
2650 renameNumbering[file] = 1;
2652 renameNumbering[file]++;
2656 if ( TDEIO::NetAccess::exists( curUrl,
false, parentWidget() ) ) {
2657 if ( KMessageBox::warningContinueCancel( parentWidget(),
2658 i18n(
"A file named %1 already exists. Do you want to overwrite it?" )
2659 .arg( curUrl.fileName() ),
2660 i18n(
"File Already Exists" ), i18n(
"&Overwrite") ) == KMessageBox::Cancel) {
2665 const Result result = saveItem( it.key(), curUrl );
2667 globalResult = result;
2670 setResult( globalResult );
2671 emit completed(
this );
2675 KMCommand::Result KMSaveAttachmentsCommand::saveItem( partNode *node,
2678 bool bSaveEncrypted =
false;
2679 bool bEncryptedParts = node->encryptionState() != KMMsgNotEncrypted;
2680 if( bEncryptedParts )
2681 if( KMessageBox::questionYesNo( parentWidget(),
2682 i18n(
"The part %1 of the message is encrypted. Do you want to keep the encryption when saving?" ).
2683 arg( url.fileName() ),
2684 i18n(
"KMail Question" ), i18n(
"Keep Encryption"), i18n(
"Do Not Keep") ) ==
2686 bSaveEncrypted =
true;
2688 bool bSaveWithSig =
true;
2689 if( node->signatureState() != KMMsgNotSigned )
2690 if( KMessageBox::questionYesNo( parentWidget(),
2691 i18n(
"The part %1 of the message is signed. Do you want to keep the signature when saving?" ).
2692 arg( url.fileName() ),
2693 i18n(
"KMail Question" ), i18n(
"Keep Signature"), i18n(
"Do Not Keep") ) !=
2695 bSaveWithSig =
false;
2706 if( bSaveEncrypted || !bEncryptedParts) {
2707 partNode *dataNode = node;
2708 TQCString rawReplyString;
2709 bool gotRawReplyString =
false;
2710 if( !bSaveWithSig ) {
2711 if( DwMime::kTypeMultipart == node->type() &&
2712 DwMime::kSubtypeSigned == node->subType() ){
2714 if( node->findType( DwMime::kTypeApplication,
2715 DwMime::kSubtypePgpSignature,
2717 dataNode = node->findTypeNot( DwMime::kTypeApplication,
2718 DwMime::kSubtypePgpSignature,
2720 }
else if( node->findType( DwMime::kTypeApplication,
2721 DwMime::kSubtypePkcs7Mime,
2723 dataNode = node->findTypeNot( DwMime::kTypeApplication,
2724 DwMime::kSubtypePkcs7Mime,
2727 dataNode = node->findTypeNot( DwMime::kTypeMultipart,
2728 DwMime::kSubtypeUnknown,
2732 ObjectTreeParser otp( 0, 0,
false,
false,
false );
2735 dataNode->setProcessed(
false,
true );
2736 otp.parseObjectTree( dataNode );
2738 rawReplyString = otp.rawReplyString();
2739 gotRawReplyString =
true;
2742 TQByteArray cstr = gotRawReplyString
2744 : dataNode->msgPart().bodyDecodedBinary();
2746 size_t size = cstr.size();
2747 if ( dataNode->msgPart().type() == DwMime::kTypeText ) {
2751 data.resize( size );
2757 tf.setAutoDelete(
true );
2758 if ( url.isLocalFile() )
2761 file.setName( url.path() );
2762 if ( !file.open( IO_WriteOnly ) )
2764 KMessageBox::error( parentWidget(),
2765 i18n(
"%2 is detailed error description",
2766 "Could not write the file %1:\n%2" )
2768 .arg( TQString::fromLocal8Bit( strerror( errno ) ) ),
2769 i18n(
"KMail Error" ) );
2774 if ( GlobalSettings::self()->disregardUmask() )
2775 fchmod( file.handle(), S_IRUSR | S_IWUSR );
2777 ds.setDevice( &file );
2781 ds.setDevice( tf.file() );
2784 ds.writeRawBytes( data.data(), data.size() );
2785 if ( !url.isLocalFile() )
2788 if ( !TDEIO::NetAccess::upload( tf.name(), url, parentWidget() ) )
2790 KMessageBox::error( parentWidget(),
2791 i18n(
"Could not write the file %1." )
2793 i18n(
"KMail Error" ) );
2801 KMLoadPartsCommand::KMLoadPartsCommand( TQPtrList<partNode>& parts,
KMMessage *msg )
2802 : mNeedsRetrieval( 0 )
2804 for ( TQPtrListIterator<partNode> it( parts ); it.current(); ++it ) {
2805 mPartMap.insert( it.current(), msg );
2809 KMLoadPartsCommand::KMLoadPartsCommand( partNode *node,
KMMessage *msg )
2810 : mNeedsRetrieval( 0 )
2812 mPartMap.insert( node, msg );
2815 KMLoadPartsCommand::KMLoadPartsCommand( PartNodeMessageMap& partMap )
2816 : mNeedsRetrieval( 0 ), mPartMap( partMap )
2820 void KMLoadPartsCommand::slotStart()
2822 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
2823 it != mPartMap.end();
2825 if ( !it.key()->msgPart().isComplete() &&
2826 !it.key()->msgPart().partSpecifier().isEmpty() ) {
2829 KMFolder* curFolder = it.data()->parent();
2832 curFolder->
createJob( it.data(), FolderJob::tGetMessage,
2833 0, it.key()->msgPart().partSpecifier() );
2834 job->setCancellable(
false );
2835 connect( job, TQ_SIGNAL(messageUpdated(
KMMessage*, TQString)),
2836 this, TQ_SLOT(slotPartRetrieved(
KMMessage*, TQString)) );
2839 kdWarning(5006) <<
"KMLoadPartsCommand - msg has no parent" << endl;
2842 if ( mNeedsRetrieval == 0 )
2846 void KMLoadPartsCommand::slotPartRetrieved(
KMMessage *msg,
2847 TQString partSpecifier )
2853 for ( PartNodeMessageMap::const_iterator it = mPartMap.begin();
2854 it != mPartMap.end();
2856 if ( it.key()->dwPart()->partId() == part->partId() )
2857 it.key()->setDwPart( part );
2860 kdWarning(5006) <<
"KMLoadPartsCommand::slotPartRetrieved - could not find bodypart!" << endl;
2862 if ( mNeedsRetrieval == 0 )
2866 KMCommand::Result KMLoadPartsCommand::execute()
2868 emit partsRetrieved();
2870 emit completed(
this );
2875 KMResendMessageCommand::KMResendMessageCommand( TQWidget *parent,
2877 :KMCommand( parent, msg )
2881 KMCommand::Result KMResendMessageCommand::execute()
2884 if ( !msg || !msg->
codec() ) {
2889 TQStringList whiteList;
2890 whiteList <<
"To" <<
"Cc" <<
"Bcc" <<
"Subject";
2893 if( newMsg->type() == DwMime::kTypeText) {
2896 newMsg->setParent( 0 );
2902 KMail::Composer * win = KMail::makeComposer();
2903 win->setMsg(newMsg,
false,
true);
2909 KMMailingListCommand::KMMailingListCommand( TQWidget *parent,
KMFolder *folder )
2910 : KMCommand( parent ), mFolder( folder )
2914 KMCommand::Result KMMailingListCommand::execute()
2916 KURL::List lst = urls();
2917 TQString handler = ( mFolder->mailingList().handler() == MailingList::KMail )
2918 ?
"mailto" :
"https";
2920 KMCommand *command = 0;
2921 for ( KURL::List::Iterator itr = lst.begin(); itr != lst.end(); ++itr ) {
2922 if ( handler == (*itr).protocol() ) {
2923 command =
new KMUrlClickedCommand( *itr, mFolder->identity(), 0,
false );
2926 if ( !command && !lst.empty() ) {
2928 new KMUrlClickedCommand( lst.first(), mFolder->identity(), 0,
false );
2931 connect( command, TQ_SIGNAL( completed( KMCommand * ) ),
2932 this, TQ_SLOT( commandCompleted( KMCommand * ) ) );
2933 setDeletesItself(
true );
2934 setEmitsCompletedItself(
true );
2941 void KMMailingListCommand::commandCompleted( KMCommand *command )
2943 setResult( command->result() );
2944 emit completed(
this );
2948 KMMailingListPostCommand::KMMailingListPostCommand( TQWidget *parent,
KMFolder *folder )
2949 : KMMailingListCommand( parent, folder )
2952 KURL::List KMMailingListPostCommand::urls()
const
2954 return mFolder->mailingList().postURLS();
2957 KMMailingListSubscribeCommand::KMMailingListSubscribeCommand( TQWidget *parent,
KMFolder *folder )
2958 : KMMailingListCommand( parent, folder )
2961 KURL::List KMMailingListSubscribeCommand::urls()
const
2963 return mFolder->mailingList().subscribeURLS();
2966 KMMailingListUnsubscribeCommand::KMMailingListUnsubscribeCommand( TQWidget *parent,
KMFolder *folder )
2967 : KMMailingListCommand( parent, folder )
2970 KURL::List KMMailingListUnsubscribeCommand::urls()
const
2972 return mFolder->mailingList().unsubscribeURLS();
2975 KMMailingListArchivesCommand::KMMailingListArchivesCommand( TQWidget *parent,
KMFolder *folder )
2976 : KMMailingListCommand( parent, folder )
2979 KURL::List KMMailingListArchivesCommand::urls()
const
2981 return mFolder->mailingList().archiveURLS();
2984 KMMailingListHelpCommand::KMMailingListHelpCommand( TQWidget *parent,
KMFolder *folder )
2985 : KMMailingListCommand( parent, folder )
2988 KURL::List KMMailingListHelpCommand::urls()
const
2990 return mFolder->mailingList().helpURLS();
2993 KMIMChatCommand::KMIMChatCommand(
const KURL &url,
KMMessage *msg )
2994 :mUrl( url ), mMessage( msg )
2998 KMCommand::Result KMIMChatCommand::execute()
3000 kdDebug( 5006 ) << k_funcinfo <<
" URL is: " << mUrl << endl;
3003 TDEABC::AddressBook *addressBook = TDEABC::StdAddressBook::self(
true );
3004 TDEABC::AddresseeList addressees = addressBook->findByEmail( KPIM::getEmailAddress( addr ) ) ;
3007 if( addressees.count() == 1 ) {
3008 kmkernel->imProxy()->chatWithContact( addressees[0].uid() );
3013 kdDebug( 5006 ) <<
"Didn't find exactly one addressee, couldn't tell who to chat to for that email address. Count = " << addressees.count() << endl;
3016 if ( addressees.isEmpty() )
3017 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." );
3020 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." );
3021 TQStringList nameList;
3022 TDEABC::AddresseeList::const_iterator it = addressees.begin();
3023 TDEABC::AddresseeList::const_iterator end = addressees.end();
3024 for ( ; it != end; ++it )
3026 nameList.append( (*it).realName() );
3028 TQString names = nameList.join( TQString::fromLatin1(
",\n" ) );
3029 apology = apology.arg( names );
3032 KMessageBox::sorry( parentWidget(), apology );
3037 KMHandleAttachmentCommand::KMHandleAttachmentCommand( partNode* node,
3038 KMMessage* msg,
int atmId,
const TQString& atmName,
3039 AttachmentAction action, KService::Ptr offer, TQWidget* parent )
3040 : KMCommand( parent ), mNode( node ), mMsg( msg ), mAtmId( atmId ), mAtmName( atmName ),
3041 mAction( action ), mOffer( offer ), mJob( 0 )
3045 void KMHandleAttachmentCommand::slotStart()
3047 if ( !mNode->msgPart().isComplete() )
3050 kdDebug(5006) <<
"load part" << endl;
3051 KMLoadPartsCommand *command =
new KMLoadPartsCommand( mNode, mMsg );
3052 connect( command, TQ_SIGNAL( partsRetrieved() ),
3053 this, TQ_SLOT( slotPartComplete() ) );
3061 void KMHandleAttachmentCommand::slotPartComplete()
3066 KMCommand::Result KMHandleAttachmentCommand::execute()
3085 case ChiasmusEncrypt:
3086 atmEncryptWithChiasmus();
3090 kdDebug(5006) <<
"unknown action " << mAction << endl;
3094 emit completed(
this );
3099 TQString KMHandleAttachmentCommand::createAtmFileLink()
const
3101 TQFileInfo atmFileInfo( mAtmName );
3103 if ( atmFileInfo.size() == 0 )
3105 kdDebug(5006) << k_funcinfo <<
"rewriting attachment" << endl;
3107 TQByteArray data = mNode->msgPart().bodyDecodedBinary();
3108 size_t size = data.size();
3109 if ( mNode->msgPart().type() == DwMime::kTypeText && size) {
3113 KPIM::kBytesToFile( data.data(), size, mAtmName,
false,
false,
false );
3116 KTempFile *linkFile =
new KTempFile( locateLocal(
"tmp", atmFileInfo.fileName() +
"_["),
3117 "]."+ atmFileInfo.extension() );
3119 linkFile->setAutoDelete(
true);
3120 TQString linkName = linkFile->name();
3123 if ( ::link(TQFile::encodeName( mAtmName ), TQFile::encodeName( linkName )) == 0 ) {
3129 KService::Ptr KMHandleAttachmentCommand::getServiceOffer()
3131 KMMessagePart& msgPart = mNode->msgPart();
3132 const TQString contentTypeStr =
3133 ( msgPart.typeStr() +
'/' + msgPart.subtypeStr() ).lower();
3135 if ( contentTypeStr ==
"text/x-vcard" ) {
3140 KMimeType::Ptr mimetype;
3142 mimetype = KMimeType::mimeType( contentTypeStr );
3143 if ( mimetype->name() ==
"application/octet-stream" ) {
3145 mimetype = KMimeType::findByPath( mAtmName, 0,
true );
3147 if ( ( mimetype->name() ==
"application/octet-stream" )
3148 && msgPart.isComplete() ) {
3151 mimetype = KMimeType::findByFileContent( mAtmName );
3153 return KServiceTypeProfile::preferredService( mimetype->name(),
"Application" );
3156 void KMHandleAttachmentCommand::atmOpen()
3159 mOffer = getServiceOffer();
3161 kdDebug(5006) << k_funcinfo <<
"got no offer" << endl;
3167 bool autoDelete =
true;
3168 TQString fname = createAtmFileLink();
3170 if ( fname.isNull() ) {
3175 url.setPath( fname );
3177 if ( (KRun::run( *mOffer, lst, autoDelete ) <= 0) && autoDelete ) {
3178 TQFile::remove(url.path());
3182 void KMHandleAttachmentCommand::atmOpenWith()
3186 bool autoDelete =
true;
3187 TQString fname = createAtmFileLink();
3189 if ( fname.isNull() ) {
3194 url.setPath( fname );
3196 if ( (! KRun::displayOpenWithDialog(lst, autoDelete)) && autoDelete ) {
3197 TQFile::remove( url.path() );
3201 void KMHandleAttachmentCommand::atmView()
3204 emit showAttachment( mAtmId, mAtmName );
3207 void KMHandleAttachmentCommand::atmSave()
3209 TQPtrList<partNode> parts;
3210 parts.append( mNode );
3212 KMSaveAttachmentsCommand *command =
3213 new KMSaveAttachmentsCommand( parentWidget(), parts, mMsg,
false );
3217 void KMHandleAttachmentCommand::atmProperties()
3220 KMMessagePart& msgPart = mNode->msgPart();
3221 dlg.setMsgPart( &msgPart );
3225 void KMHandleAttachmentCommand::atmEncryptWithChiasmus()
3227 const partNode * node = mNode;
3233 if ( !mAtmName.endsWith(
".xia",
false ) )
3236 const Kleo::CryptoBackend::Protocol * chiasmus =
3237 Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" );
3238 Q_ASSERT( chiasmus );
3242 const STD_NAMESPACE_PREFIX unique_ptr<Kleo::SpecialJob> listjob( chiasmus->specialJob(
"x-obtain-keys", TQStringVariantMap() ) );
3244 const TQString msg = i18n(
"Chiasmus backend does not offer the "
3245 "\"x-obtain-keys\" function. Please report this bug." );
3246 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3250 if ( listjob->exec() ) {
3251 listjob->showErrorDialog( parentWidget(), i18n(
"Chiasmus Backend Error" ) );
3255 const TQVariant result = listjob->property(
"result" );
3256 if ( result.type() != TQVariant::StringList ) {
3257 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
3258 "The \"x-obtain-keys\" function did not return a "
3259 "string list. Please report this bug." );
3260 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3264 const TQStringList keys = result.toStringList();
3265 if ( keys.empty() ) {
3266 const TQString msg = i18n(
"No keys have been found. Please check that a "
3267 "valid key path has been set in the Chiasmus "
3269 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3273 ChiasmusKeySelector selectorDlg( parentWidget(), i18n(
"Chiasmus Decryption Key Selection" ),
3274 keys, GlobalSettings::chiasmusDecryptionKey(),
3275 GlobalSettings::chiasmusDecryptionOptions() );
3276 if ( selectorDlg.exec() != TQDialog::Accepted )
3279 GlobalSettings::setChiasmusDecryptionOptions( selectorDlg.options() );
3280 GlobalSettings::setChiasmusDecryptionKey( selectorDlg.key() );
3281 assert( !GlobalSettings::chiasmusDecryptionKey().isEmpty() );
3283 Kleo::SpecialJob * job = chiasmus->specialJob(
"x-decrypt", TQStringVariantMap() );
3285 const TQString msg = i18n(
"Chiasmus backend does not offer the "
3286 "\"x-decrypt\" function. Please report this bug." );
3287 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3291 const TQByteArray input = node->msgPart().bodyDecodedBinary();
3293 if ( !job->setProperty(
"key", GlobalSettings::chiasmusDecryptionKey() ) ||
3294 !job->setProperty(
"options", GlobalSettings::chiasmusDecryptionOptions() ) ||
3295 !job->setProperty(
"input", input ) ) {
3296 const TQString msg = i18n(
"The \"x-decrypt\" function does not accept "
3297 "the expected parameters. Please report this bug." );
3298 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3302 setDeletesItself(
true );
3303 if ( job->start() ) {
3304 job->showErrorDialog( parentWidget(), i18n(
"Chiasmus Decryption Error" ) );
3309 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQVariant&)),
3310 this, TQ_SLOT(slotAtmDecryptWithChiasmusResult(
const GpgME::Error&,
const TQVariant&)) );
3313 static const TQString chomp(
const TQString & base,
const TQString & suffix,
bool cs ) {
3314 return base.endsWith( suffix, cs ) ? base.left( base.length() - suffix.length() ) : base ;
3317 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusResult(
const GpgME::Error & err,
const TQVariant & result )
3319 LaterDeleterWithCommandCompletion d(
this );
3322 Q_ASSERT( mJob == sender() );
3323 if ( mJob != sender() )
3325 Kleo::Job * job = mJob;
3327 if ( err.isCanceled() )
3330 job->showErrorDialog( parentWidget(), i18n(
"Chiasmus Decryption Error" ) );
3334 if ( result.type() != TQVariant::ByteArray ) {
3335 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
3336 "The \"x-decrypt\" function did not return a "
3337 "byte array. Please report this bug." );
3338 KMessageBox::error( parentWidget(), msg, i18n(
"Chiasmus Backend Error" ) );
3342 const KURL url = KFileDialog::getSaveURL( chomp( mAtmName,
".xia",
false ), TQString(), parentWidget() );
3343 if ( url.isEmpty() )
3346 bool overwrite = KMail::Util::checkOverwrite( url, parentWidget() );
3350 d.setDisabled(
true );
3351 TDEIO::Job * uploadJob = TDEIO::storedPut( result.toByteArray(), url, -1, overwrite,
false );
3352 uploadJob->setWindow( parentWidget() );
3353 connect( uploadJob, TQ_SIGNAL(result(TDEIO::Job*)),
3354 this, TQ_SLOT(slotAtmDecryptWithChiasmusUploadResult(TDEIO::Job*)) );
3357 void KMHandleAttachmentCommand::slotAtmDecryptWithChiasmusUploadResult( TDEIO::Job * job )
3360 job->showErrorDialog();
3361 LaterDeleterWithCommandCompletion d(
this );
3366 AttachmentModifyCommand::AttachmentModifyCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3367 KMCommand( parent, msg ),
3368 mPartIndex( node->nodeId() ),
3373 AttachmentModifyCommand::AttachmentModifyCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3374 : KMCommand( parent, msg ),
3375 mPartIndex( nodeId ),
3380 AttachmentModifyCommand::~ AttachmentModifyCommand()
3384 KMCommand::Result AttachmentModifyCommand::execute()
3389 mSernum = msg->getMsgSerNum();
3391 mFolder = msg->parent();
3392 if ( !mFolder || !mFolder->storage() )
3395 Result res = doAttachmentModify();
3399 setEmitsCompletedItself(
true );
3400 setDeletesItself(
true );
3404 void AttachmentModifyCommand::storeChangedMessage(
KMMessage * msg)
3406 if ( !mFolder || !mFolder->storage() ) {
3407 kdWarning(5006) << k_funcinfo <<
"We lost the folder!" << endl;
3408 setResult( Failed );
3409 emit completed(
this );
3412 int res = mFolder->addMsg( msg ) != 0;
3413 if ( mFolder->folderType() == KMFolderTypeImap ) {
3414 KMFolderImap *f =
static_cast<KMFolderImap*
>( mFolder->storage() );
3415 connect( f, TQ_SIGNAL(folderComplete(KMFolderImap*,
bool)),
3416 TQ_SLOT(messageStoreResult(KMFolderImap*,
bool)) );
3418 messageStoreResult( 0, res == 0 );
3422 void AttachmentModifyCommand::messageStoreResult(KMFolderImap* folder,
bool success )
3426 KMCommand *delCmd =
new KMDeleteMsgCommand( mSernum );
3427 connect( delCmd, TQ_SIGNAL(completed(KMCommand*)), TQ_SLOT(messageDeleteResult(KMCommand*)) );
3431 kdWarning(5006) << k_funcinfo <<
"Adding modified message failed." << endl;
3432 setResult( Failed );
3433 emit completed(
this );
3437 void AttachmentModifyCommand::messageDeleteResult(KMCommand * cmd)
3439 setResult( cmd->result() );
3440 emit completed(
this );
3444 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3447 kdDebug(5006) << k_funcinfo << endl;
3450 KMDeleteAttachmentCommand::KMDeleteAttachmentCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3453 kdDebug(5006) << k_funcinfo << endl;
3456 KMDeleteAttachmentCommand::~KMDeleteAttachmentCommand()
3458 kdDebug(5006) << k_funcinfo << endl;
3461 KMCommand::Result KMDeleteAttachmentCommand::doAttachmentModify()
3471 storeChangedMessage( newMsg );
3476 KMEditAttachmentCommand::KMEditAttachmentCommand(partNode * node,
KMMessage * msg, TQWidget * parent) :
3479 kdDebug(5006) << k_funcinfo << endl;
3480 mTempFile.setAutoDelete(
true );
3483 KMEditAttachmentCommand::KMEditAttachmentCommand(
int nodeId,
KMMessage *msg, TQWidget *parent )
3486 kdDebug(5006) << k_funcinfo << endl;
3487 mTempFile.setAutoDelete(
true );
3490 KMEditAttachmentCommand::~ KMEditAttachmentCommand()
3494 KMCommand::Result KMEditAttachmentCommand::doAttachmentModify()
3501 DwBodyPart *dwpart = msg->findPart( mPartIndex );
3505 if ( !part.isComplete() )
3508 if( !
dynamic_cast<DwBody*
>( dwpart->Parent() ) )
3511 mTempFile.file()->writeBlock( part.bodyDecodedBinary() );
3512 mTempFile.file()->flush();
3516 part.typeStr() +
"/" + part.subtypeStr(),
3517 false,
this, parentWidget() );
3519 if ( !watcher->start() )
3521 setEmitsCompletedItself(
true );
3522 setDeletesItself(
true );
3528 kdDebug(5006) << k_funcinfo << endl;
3530 if ( !watcher->fileChanged() ) {
3531 kdDebug(5006) << k_funcinfo <<
"File has not been changed" << endl;
3532 setResult( Canceled );
3533 emit completed(
this );
3537 mTempFile.file()->reset();
3538 TQByteArray data = mTempFile.file()->readAll();
3543 DwBodyPart *dwpart = msg->findPart( mPartIndex );
3546 DwBody *parentNode =
dynamic_cast<DwBody*
>( dwpart->Parent() );
3547 assert( parentNode );
3548 parentNode->RemoveBodyPart( dwpart );
3551 att.duplicate( part );
3552 att.setBodyEncodedBinary( data );
3555 parentNode->AddBodyPart( newDwPart );
3556 msg->getTopLevelPart()->Assemble();
3562 storeChangedMessage( newMsg );
3566 CreateTodoCommand::CreateTodoCommand(TQWidget * parent,
KMMessage * msg)
3567 : KMCommand( parent, msg )
3571 KMCommand::Result CreateTodoCommand::execute()
3574 if ( !msg || !msg->
codec() ) {
3578 KMail::KorgHelper::ensureRunning();
3580 TQString txt = i18n(
"From: %1\nTo: %2\nSubject: %3").arg( msg->
from() )
3581 .arg( msg->
to() ).arg( msg->
subject() );
3584 tf.setAutoDelete(
true );
3585 TQString uri =
"kmail:" + TQString::number( msg->getMsgSerNum() ) +
"/" + msg->
msgId();
3589 KCalendarIface_stub *iface =
new KCalendarIface_stub( kapp->dcopClient(),
"korganizer",
"CalendarIface" );
3590 iface->openTodoEditor( i18n(
"Mail: %1").arg( msg->
subject() ), txt, uri,
3591 tf.name(), TQStringList(),
"message/rfc822",
true );
3597 #include "kmcommands.moc"