46 #include <Nepomuk2/Tag>
47 #include <nepomuk2/resource.h>
50 #include "kernel/mailkernel.h"
51 #include "util/mailutil.h"
54 #include <kprogressdialog.h>
55 #include <kpimutils/email.h>
56 #include <kdbusservicestarter.h>
58 #include <kfiledialog.h>
60 #include <kmessagebox.h>
61 #include <kbookmarkmanager.h>
62 #include <kstandarddirs.h>
63 #include <ktemporaryfile.h>
66 #include <kio/jobuidelegate.h>
67 #include <kio/netaccess.h>
69 #include <kmime/kmime_message.h>
71 #include <kpimidentities/identitymanager.h>
72 #include <akonadi/itemmodifyjob.h>
73 #include <akonadi/itemfetchjob.h>
76 #include "foldercollection.h"
78 #include "messagecore/misc/mailinglist.h"
80 #include "mailcommon/filter/filteraction.h"
81 #include "mailcommon/filter/filtermanager.h"
82 #include "mailcommon/filter/mailfilter.h"
83 #include "mailcommon/widgets/redirectdialog.h"
87 #include "messageviewer/utils/kcursorsaver.h"
89 #include "messageviewer/viewer/objecttreeparser.h"
90 #include "messageviewer/viewer/csshelper.h"
91 #include "messageviewer/utils/util.h"
92 #include "messageviewer/viewer/mailsourceviewer.h"
93 #include "messageviewer/viewer/viewer.h"
94 #include "messageviewer/header/headerstrategy.h"
95 #include "messageviewer/header/headerstyle.h"
102 #include "utils/stringutil.h"
103 #include "messageviewer/utils/autoqpointer.h"
104 #include "messageviewer/settings/globalsettings.h"
105 #include "messagecore/settings/globalsettings.h"
107 #include <kpimutils/kfileio.h>
109 #include <akonadi/itemmovejob.h>
110 #include <akonadi/itemcopyjob.h>
111 #include <akonadi/itemdeletejob.h>
112 #include <mailtransport/transportattribute.h>
113 #include <mailtransport/sentbehaviourattribute.h>
115 #include <messagelist/pane.h>
117 #include <mailtransport/transportmanager.h>
118 using MailTransport::TransportManager;
121 #include "messageviewer/viewer/nodehelper.h"
122 #include "messageviewer/viewer/objecttreeemptysource.h"
124 #include "messagecore/utils/stringutil.h"
125 #include "messagecore/helpers/messagehelpers.h"
127 #include "messagecomposer/sender/messagesender.h"
128 #include "messagecomposer/helper/messagehelper.h"
129 #include "messagecomposer/settings/messagecomposersettings.h"
130 #include "messagecomposer/helper/messagefactory.h"
131 using MessageComposer::MessageFactory;
137 #include <kmime/kmime_mdn.h>
138 using namespace KMime;
140 #include "kleo/cryptobackend.h"
141 #include "kleo/cryptobackendfactory.h"
143 #include <gpgme++/error.h>
145 #include <QDBusConnection>
146 #include <QByteArray>
147 #include <QApplication>
150 #include <boost/bind.hpp>
155 using namespace MailCommon;
160 if ( reply.replyAll )
172 KIO::Job* kiojob =
dynamic_cast<KIO::Job*
>(job);
173 if( kiojob && kiojob->ui() )
174 kiojob->ui()->showErrorMessage();
176 kWarning() <<
"There is no GUI delegate set for a kjob, and it failed with error:" << job->errorString();
180 : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
181 mEmitsCompletedItself( false ), mParent( parent )
186 : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
187 mEmitsCompletedItself( false ), mParent( parent )
189 if ( msg.isValid() || msg.hasPayload<KMime::Message::Ptr>() ) {
190 mMsgList.append( msg );
195 : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
196 mEmitsCompletedItself( false ), mParent( parent )
210 kDebug() <<
"mResult is Undefined";
223 return Akonadi::Item();
232 int KMCommand::mCountJobs = 0;
239 if ( mMsgList.isEmpty() ) {
245 const Akonadi::Item mb = mMsgList.first();
246 if ( ( mMsgList.count() == 1 ) && MessageCore::Util::isStandaloneMessage( mb ) ) {
253 foreach (
const Akonadi::Item &item, mMsgList ) {
254 if ( !item.isValid() ) {
261 transferSelectedMsgs();
268 if ( result ==
OK ) {
278 void KMCommand::transferSelectedMsgs()
281 if (KMCommand::mCountJobs > 0) {
286 bool complete =
true;
287 KMCommand::mCountJobs = 0;
290 mCountMsgs = mMsgList.count();
296 if ( mCountMsgs > 0 ) {
297 mProgressDialog =
new KProgressDialog(mParent,
299 i18np(
"Please wait while the message is transferred",
300 "Please wait while the %1 messages are transferred", mMsgList.count()));
301 mProgressDialog.data()->setModal(
true);
302 mProgressDialog.data()->setMinimumDuration(1000);
306 if ( !mFetchScope.isEmpty() ) {
308 KMCommand::mCountJobs++;
309 Akonadi::ItemFetchJob *fetch =
new Akonadi::ItemFetchJob( mMsgList,
this );
310 mFetchScope.fetchAttribute< MessageCore::MDNStateAttribute >();
311 fetch->setFetchScope( mFetchScope );
312 connect( fetch, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(slotMsgTransfered(Akonadi::Item::List)) );
313 connect( fetch, SIGNAL(
result(
KJob*)), SLOT(slotJobFinished()) );
316 if ( !mMsgList.isEmpty() )
321 delete mProgressDialog.data();
322 mProgressDialog.clear();
326 if ( mProgressDialog.data() ) {
327 connect(mProgressDialog.data(), SIGNAL(cancelClicked()),
328 this, SLOT(slotTransferCancelled()));
329 mProgressDialog.data()->progressBar()->setMaximum(totalSize);
334 void KMCommand::slotMsgTransfered(
const Akonadi::Item::List& msgs)
336 if ( mProgressDialog.data() && mProgressDialog.data()->wasCancelled() ) {
344 void KMCommand::slotJobFinished()
347 KMCommand::mCountJobs--;
349 if ( mProgressDialog.data() && mProgressDialog.data()->wasCancelled() )
return;
354 if ( mProgressDialog.data() )
355 mProgressDialog.data()->hide();
356 slotTransferCancelled();
360 if ( mProgressDialog.data() ) {
361 mProgressDialog.data()->setLabelText(i18np(
"Please wait while the message is transferred",
362 "Please wait while the %1 messages are transferred", KMCommand::mCountJobs));
364 if (KMCommand::mCountJobs == 0)
367 delete mProgressDialog.data();
368 mProgressDialog.clear();
373 void KMCommand::slotTransferCancelled()
375 KMCommand::mCountJobs = 0;
383 const Akonadi::Item &msg )
384 :mUrl( url ), mMessage( msg )
390 KMime::Message::Ptr msg(
new KMime::Message );
393 if ( mMessage.isValid() && mMessage.parentCollection().isValid() ) {
398 MessageHelper::initHeader( msg,
KMKernel::self()->identityManager(),
id );
399 msg->contentType()->setCharset(
"utf-8");
400 msg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ),
"utf-8" );
410 const KUrl &url,
const Akonadi::Item &msg,
const QString &selection )
411 :
KMCommand( parent, msg ), mUrl( url ), mSelection( selection )
414 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
420 KMime::Message::Ptr msg = MessageCore::Util::message( item );
423 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
424 factory.setIdentityManager(
KMKernel::self()->identityManager() );
425 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
428 factory.setReplyStrategy( MessageComposer::ReplyNone );
429 factory.setSelection( mSelection );
430 KMime::Message::Ptr rmsg = factory.createReply().msg;
431 rmsg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ),
"utf-8" );
432 bool lastEncrypt =
false;
433 bool lastSign =
false;
445 const KUrl &url,
const Akonadi::Item &msg )
449 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
456 KMime::Message::Ptr msg = MessageCore::Util::message( item );
459 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
460 factory.setIdentityManager(
KMKernel::self()->identityManager() );
461 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
462 KMime::Message::Ptr fmsg = factory.createForward();
463 fmsg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ).toLower(),
"utf-8" );
464 bool lastEncrypt =
false;
465 bool lastSign =
false;
482 const QString filename = KStandardDirs::locateLocal(
"data", QString::fromLatin1(
"konqueror/bookmarks.xml") );
483 KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename, QLatin1String(
"konqueror") );
484 KBookmarkGroup group = bookManager->root();
485 group.addBookmark( mUrl.path(), KUrl( mUrl ) );
486 if( bookManager->save() ) {
487 bookManager->emitChanged( group );
500 if ( mUrl.isEmpty() )
502 const KUrl saveUrl = KFileDialog::getSaveUrl(mUrl.fileName(), QString(),
504 if ( saveUrl.isEmpty() )
506 if ( KIO::NetAccess::exists( saveUrl, KIO::NetAccess::DestinationSide,
parentWidget() ) )
508 if (KMessageBox::warningContinueCancel(0,
509 i18nc(
"@info",
"File <filename>%1</filename> exists.<nl/>Do you want to replace it?",
510 saveUrl.pathOrUrl()), i18n(
"Save to File"), KGuiItem(i18n(
"&Replace")))
511 != KMessageBox::Continue)
514 KIO::Job *job = KIO::file_copy(mUrl, saveUrl, -1, KIO::Overwrite);
515 connect(job, SIGNAL(
result(
KJob*)), SLOT(slotUrlSaveResult(
KJob*)));
520 void KMUrlSaveCommand::slotUrlSaveResult(
KJob *job )
522 if ( job->error() ) {
544 bool lastEncrypt =
false;
545 bool lastSign =
false;
547 win->
setMessage( mMessage, lastSign, lastEncrypt,
false,
false );
556 , mDeleteFromSource( deleteFromSource )
559 fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
560 fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
561 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
572 if (!item.isValid() || !item.parentCollection().isValid() ) {
575 KMime::Message::Ptr msg = MessageCore::Util::message( item );
580 if ( mDeleteFromSource ) {
582 Akonadi::ItemDeleteJob *job =
new Akonadi::ItemDeleteJob( item );
583 connect( job, SIGNAL(
result(
KJob*)),
this, SLOT(slotDeleteItem(
KJob*)) );
586 bool lastEncrypt =
false;
587 bool lastSign =
false;
589 win->
setMessage( msg, lastSign, lastEncrypt,
false,
true );
591 win->
setFolder( item.parentCollection() );
593 const MailTransport::TransportAttribute *transportAttribute = item.attribute<MailTransport::TransportAttribute>();
594 if ( transportAttribute ) {
597 int transportId = msg->headerByType(
"X-KMail-Transport" ) ? msg->headerByType(
"X-KMail-Transport" )->asUnicodeString().toInt() : -1;
598 if(transportId!=-1) {
604 if(msg->headerByType(
"Reply-To" )) {
605 const QString replyTo = msg->headerByType(
"Reply-To" )->asUnicodeString();
609 const MailTransport::SentBehaviourAttribute *sentAttribute = item.attribute<MailTransport::SentBehaviourAttribute>();
610 if ( sentAttribute && ( sentAttribute->sentBehaviour() == MailTransport::SentBehaviourAttribute::MoveToCollection ) )
611 win->
setFcc( QString::number( sentAttribute->moveToCollection().id() ) );
613 if ( mDeleteFromSource )
619 void KMEditItemCommand::slotDeleteItem(
KJob *job )
621 if ( job->error() ) {
637 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
644 || !item.parentCollection().isValid() ||
645 !CommonKernel->folderIsTemplates( item.parentCollection() )
649 KMime::Message::Ptr msg = MessageCore::Util::message( item );
653 KMime::Message::Ptr newMsg(
new KMime::Message);
654 newMsg->setContent( msg->encodedContent() );
657 newMsg->removeHeader(
"Date");
658 newMsg->removeHeader(
"Message-ID");
662 win->
setMessage( newMsg,
false,
false,
false,
true );
670 if ( msgList.empty() )
690 mEncoding( encoding ),
697 if ( mUrl.isEmpty() ) {
698 mUrl = KFileDialog::getOpenUrl( KUrl( QLatin1String(
"kfiledialog:///OpenMessage") ),
699 QLatin1String(
"message/rfc822 application/mbox"),
702 if ( mUrl.isEmpty() ) {
711 mJob = KIO::get( mUrl, KIO::NoReload, KIO::HideProgressInfo );
712 connect( mJob, SIGNAL(data(KIO::Job*,QByteArray)),
713 this, SLOT(slotDataArrived(KIO::Job*,QByteArray)) );
715 SLOT(slotResult(
KJob*)) );
720 void KMOpenMsgCommand::slotDataArrived( KIO::Job *,
const QByteArray & data )
722 if ( data.isEmpty() )
725 mMsgString.append( QString::fromLatin1(data.data()) );
728 void KMOpenMsgCommand::doesNotContainMessage()
731 i18n(
"The file does not contain a message." ) );
744 void KMOpenMsgCommand::slotResult(
KJob *job )
746 if ( job->error() ) {
753 int startOfMessage = 0;
754 if ( mMsgString.startsWith( QLatin1String(
"From " ) ) ) {
755 startOfMessage = mMsgString.indexOf( QLatin1Char(
'\n') );
756 if ( startOfMessage == -1 ) {
757 doesNotContainMessage();
763 bool multipleMessages =
true;
764 int endOfMessage = mMsgString.indexOf( QLatin1String(
"\nFrom ") );
765 if ( endOfMessage == -1 ) {
766 endOfMessage = mMsgString.length();
767 multipleMessages =
false;
769 KMime::Message *msg =
new KMime::Message;
770 msg->setContent( KMime::CRLFtoLF( mMsgString.mid( startOfMessage,endOfMessage - startOfMessage ).toUtf8() ) );
772 if ( !msg->hasContent() ) {
774 doesNotContainMessage();
778 KMime::Message::Ptr mMsg( msg );
781 if ( multipleMessages )
782 KMessageBox::information( win,
783 i18n(
"The file contains multiple messages. "
784 "Only the first message is shown." ) );
793 const QString &selection,
bool noquote,
const QString& templateName )
795 mSelection( selection ),
796 mTemplate( templateName ),
797 m_replyStrategy( replyStrategy ),
804 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
810 MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
813 KMime::Message::Ptr msg = MessageCore::Util::message( item );
817 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
818 factory.setIdentityManager(
KMKernel::self()->identityManager() );
819 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
822 factory.setReplyStrategy( m_replyStrategy );
823 factory.setSelection( mSelection );
824 if ( !mTemplate.isEmpty() )
825 factory.setTemplate( mTemplate );
827 factory.setQuote(
false);
829 bool lastEncrypt =
false;
830 bool lastSign =
false;
833 MessageFactory::MessageReply reply = factory.createReply();
835 mSelection,mTemplate );
846 mIdentity( identity ),
847 mTemplate( templateName )
850 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
854 uint identity,
const QString& templateName )
856 mIdentity( identity ),
857 mTemplate( templateName )
860 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
865 KMime::Message::Ptr msg = MessageCore::Util::message( item );
869 MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
871 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
872 factory.setIdentityManager(
KMKernel::self()->identityManager() );
873 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
874 if ( !mTemplate.isEmpty() )
875 factory.setTemplate( mTemplate );
876 KMime::Message::Ptr fwdMsg = factory.createForward();
878 uint
id = msg->headerByType(
"X-KMail-Identity" ) ? msg->headerByType(
"X-KMail-Identity")->asUnicodeString().trimmed().toUInt() : 0;
879 kDebug() <<
"mail" << msg->encodedContent();
880 bool lastEncrypt =
false;
881 bool lastSign =
false;
897 if (msgList.count() >= 2) {
900 int answer = KMessageBox::questionYesNoCancel(
902 i18n(
"Do you want to forward the selected messages as "
903 "attachments in one message (as a MIME digest) or as "
904 "individual messages?"), QString(),
905 KGuiItem(i18n(
"Send As Digest")),
906 KGuiItem(i18n(
"Send Individually")) );
908 if ( answer == KMessageBox::Yes ) {
909 Akonadi::Item firstItem( msgList.first() );
910 MessageFactory factory( KMime::Message::Ptr(
new KMime::Message ), firstItem.id(), MailCommon::Util::updatedCollection(firstItem.parentCollection()) );
911 factory.setIdentityManager(
KMKernel::self()->identityManager() );
912 factory.setFolderIdentity( MailCommon::Util::folderIdentity( firstItem ) );
914 QPair< KMime::Message::Ptr, KMime::Content* > fwdMsg = factory.createForwardDigestMIME(msgList );
919 }
else if ( answer == KMessageBox::No ) {
923 for ( it = msgList.constBegin(); it != end; ++it ) {
924 if ( createComposer( *it ) ==
Failed )
935 Akonadi::Item item = msgList.first();
936 if ( createComposer( item ) ==
Failed )
944 :
KMCommand( parent, msgList ), mIdentity( identity ),
945 mWin( QPointer<KMail::Composer>( win ))
948 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
953 :
KMCommand( parent, msg ), mIdentity( identity ),
954 mWin( QPointer< KMail::Composer >( win ))
957 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
963 Akonadi::Item firstItem( msgList.first() );
964 MessageFactory factory( KMime::Message::Ptr(
new KMime::Message ), firstItem.id(), MailCommon::Util::updatedCollection(firstItem.parentCollection()) );
965 factory.setIdentityManager(
KMKernel::self()->identityManager() );
966 factory.setFolderIdentity( MailCommon::Util::folderIdentity( firstItem ) );
968 QPair< KMime::Message::Ptr, QList< KMime::Content* > > fwdMsg = factory.createAttachedForward( msgList );
972 foreach( KMime::Content* attach, fwdMsg.second ) {
973 mWin->addAttach( attach );
984 fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
985 fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
987 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
991 const Akonadi::Item &msg )
995 fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
996 fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
998 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1003 const MailCommon::RedirectDialog::SendMode sendMode = MessageComposer::MessageComposerSettings::self()->sendImmediate()
1004 ? MailCommon::RedirectDialog::SendNow
1005 : MailCommon::RedirectDialog::SendLater;
1007 MessageViewer::AutoQPointer<MailCommon::RedirectDialog> dlg(
new MailCommon::RedirectDialog( sendMode,
parentWidget() ) );
1008 dlg->setObjectName( QLatin1String(
"redirect") );
1009 if ( dlg->exec() == QDialog::Rejected || !dlg ) {
1012 if ( !TransportManager::self()->showTransportCreationDialog(
parentWidget(), TransportManager::IfNoTransportExists ) )
1016 const MessageComposer::MessageSender::SendMethod method = (dlg->sendMode() == MailCommon::RedirectDialog::SendNow)
1017 ? MessageComposer::MessageSender::SendImmediate
1018 : MessageComposer::MessageSender::SendLater;
1020 const int identity = dlg->identity();
1021 int transportId = dlg->transportId();
1022 const QString
to = dlg->to();
1024 const KMime::Message::Ptr msg = MessageCore::Util::message( item );
1028 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
1029 factory.setIdentityManager(
KMKernel::self()->identityManager() );
1030 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
1032 if(transportId == -1) {
1033 const MailTransport::TransportAttribute *transportAttribute = item.attribute<MailTransport::TransportAttribute>();
1034 if ( transportAttribute ) {
1035 transportId = transportAttribute->transportId();
1036 const MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportById( transportId );
1043 const MailTransport::SentBehaviourAttribute *sentAttribute = item.attribute<MailTransport::SentBehaviourAttribute>();
1045 if ( sentAttribute && ( sentAttribute->sentBehaviour() == MailTransport::SentBehaviourAttribute::MoveToCollection ) )
1046 fcc = QString::number( sentAttribute->moveToCollection().id() );
1048 const KMime::Message::Ptr newMsg = factory.createRedirect( to, transportId, fcc, identity );
1052 MessageStatus status;
1053 status.setStatusFromFlags( item.flags() );
1054 if ( !status.isRead() )
1055 FilterAction::sendMDN( item, KMime::MDN::Dispatched );
1058 if ( !
kmkernel->msgSender()->send( newMsg, method ) ) {
1059 kDebug() <<
"KMRedirectCommand: could not redirect message (sending failed)";
1069 MessageViewer::HeaderStyle *headerStyle,
1070 MessageViewer::HeaderStrategy *headerStrategy,
1071 bool htmlOverride,
bool htmlLoadExtOverride,
1072 bool useFixedFont,
const QString & encoding )
1074 mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ),
1075 mAttachmentStrategy( 0 ),
1076 mEncoding( encoding ),
1077 mHtmlOverride( htmlOverride ),
1078 mHtmlLoadExtOverride( htmlLoadExtOverride ),
1079 mUseFixedFont( useFixedFont ),
1080 mPrintPreview(false)
1083 if ( MessageCore::GlobalSettings::useDefaultFonts() )
1084 mOverrideFont = KGlobalSettings::generalFont();
1086 mOverrideFont = MessageCore::GlobalSettings::self()->printFont();
1093 mOverrideFont = font;
1098 mAttachmentStrategy = strategy;
1103 mPrintPreview = preview;
1112 if ( mHeaderStyle != 0 && mHeaderStrategy != 0 )
1118 printerWin->
cssHelper()->setPrintFont( mOverrideFont );
1120 if ( mAttachmentStrategy != 0 )
1131 const Akonadi::Item::List &items,
bool invert )
1132 :
KMCommand( 0, items ), mStatus( status ), mInvertMark( invert )
1139 bool parentStatus =
false;
1142 if ( mInvertMark ) {
1144 MessageStatus pStatus;
1145 pStatus.setStatusFromFlags( first.flags() );
1146 if ( pStatus & mStatus )
1147 parentStatus =
true;
1149 parentStatus =
false;
1152 Akonadi::Item::List itemsToModify;
1154 if ( mInvertMark ) {
1156 if ( it.isValid() ) {
1158 MessageStatus itemStatus;
1159 itemStatus.setStatusFromFlags( it.flags() );
1160 if ( itemStatus & mStatus )
1164 if ( myStatus != parentStatus )
1168 Akonadi::Item item( it );
1169 const Akonadi::Item::Flag flag = *(mStatus.statusFlags().begin());
1170 if ( mInvertMark ) {
1171 if ( item.hasFlag( flag ) ) {
1172 item.clearFlag( flag );
1173 itemsToModify.push_back( item );
1175 item.setFlag( flag );
1176 itemsToModify.push_back( item );
1179 if ( !item.hasFlag( flag ) ) {
1180 item.setFlag( flag );
1181 itemsToModify.push_back( item );
1186 if ( itemsToModify.isEmpty() ) {
1189 Akonadi::ItemModifyJob *modifyJob =
new Akonadi::ItemModifyJob( itemsToModify,
this );
1190 modifyJob->disableRevisionCheck();
1191 modifyJob->setIgnorePayload(
true );
1199 if ( job && job->error() ) {
1200 kWarning() <<
" Error trying to set item status:" << job->errorText();
1207 : mTagLabel( tagLabel )
1215 QStringList tagSelectedlst;
1216 Q_FOREACH(
const Akonadi::Item& item, mItem ) {
1217 Nepomuk2::Resource n_resource( item.url() );
1220 n_tag_list = n_resource.tags();
1223 Q_FOREACH(
const QString &tagLabel, mTagLabel ) {
1224 const Nepomuk2::Tag n_tag( tagLabel );
1225 const QString tagUri(n_tag.uri().toString());
1227 n_resource.addTag( n_tag );
1228 if(!tagSelectedlst.contains(tagUri))
1229 tagSelectedlst<<tagUri;
1231 const int tagPosition = n_tag_list.indexOf( tagLabel );
1232 if ( tagPosition == -1 ) {
1233 n_resource.addTag( n_tag );
1234 if(!tagSelectedlst.contains(tagUri))
1235 tagSelectedlst<<tagUri;
1236 }
else if ( mMode ==
Toggle ) {
1237 const int numberOfTag( n_tag_list.count() );
1238 for (
int i = 0; i < numberOfTag; ++i ) {
1239 if ( n_tag_list[i].uri() == tagLabel ) {
1240 n_tag_list.removeAt( i );
1244 n_resource.setTags( n_tag_list );
1250 if(!tagSelectedlst.isEmpty()) {
1251 KConfigGroup tag(
KMKernel::self()->config(),
"MessageListView" );
1252 const QString oldTagList = tag.readEntry(
"TagSelected");
1253 QStringList lst = oldTagList.split(QLatin1String(
","));
1254 Q_FOREACH(
const QString& str,tagSelectedlst ) {
1255 if(!lst.contains(str)) {
1259 tag.writeEntry(
"TagSelected",lst);
1267 const QVector<qlonglong> &msgListId,
1268 const QString &filterId)
1269 :
KMCommand( parent ), mMsgListId(msgListId), mFilterId( filterId )
1275 #ifndef QT_NO_CURSOR
1276 MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
1279 const int msgCountToFilter = mMsgListId.count();
1281 ProgressManager::createProgressItem (
1282 QLatin1String(
"filter")+ProgressManager::getUniqueID(),
1283 i18n(
"Filtering messages" ) );
1286 foreach (
const qlonglong &
id, mMsgListId ) {
1287 int diff = msgCountToFilter - ++msgCount;
1288 if ( diff < 10 || !( msgCount % 10 ) || msgCount <= 10 ) {
1290 const QString statusMsg = i18n(
"Filtering message %1 of %2",
1291 msgCount, msgCountToFilter );
1293 qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 50 );
1297 MailCommon::FilterManager::instance()->filter( Akonadi::Item(
id), mFilterId, QString() );
1310 mFilterId( filterId ), mMainWidget( main )
1317 mMainWidget, mMainWidget->
messageListPane()->selectionAsMessageItemListId() , mFilterId);
1318 filterCommand->
start();
1323 const Akonadi::Item &msg )
1333 KMime::Message::Ptr msg = MessageCore::Util::message( item );
1336 if ( !MailingList::name( msg, name, value ).isEmpty() ) {
1337 FilterIf->openFilterDialog(
false );
1338 FilterIf->createFilter( name, value );
1347 :
KMCommand( 0, msgList ), mDestFolder( destFolder )
1352 :
KMCommand( 0,msg ), mDestFolder( destFolder )
1361 Akonadi::ItemCopyJob *job =
new Akonadi::ItemCopyJob( listItem, Akonadi::Collection(mDestFolder.id()),
this );
1369 if ( job->error() ) {
1379 MessageList::Core::MessageItemSetReference ref)
1380 :
KMCommand( 0, msgList ), mDestFolder( destFolder ), mProgressItem( 0 ), mRef( ref )
1382 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1386 const Akonadi::Item& msg ,
1387 MessageList::Core::MessageItemSetReference ref)
1388 :
KMCommand( 0, msg ), mDestFolder( destFolder ), mProgressItem( 0 ), mRef( ref )
1390 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1395 if ( job->error() ) {
1406 #ifndef QT_NO_CURSOR
1407 MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
1411 if ( mDestFolder.isValid() ) {
1412 Akonadi::ItemMoveJob *job =
new Akonadi::ItemMoveJob(
retrievedMsgs(), mDestFolder,
this );
1417 std::sort( items.begin(), items.end(), boost::bind( &Akonadi::Item::storageCollectionId, _1 ) <
1418 boost::bind( &Akonadi::Item::storageCollectionId, _2 ) );
1419 Akonadi::Collection parent;
1421 foreach (
const Akonadi::Item &item, items ) {
1422 if ( item.storageCollectionId() <= 0 )
1424 if ( parent.id() != item.storageCollectionId() ) {
1425 parent = Akonadi::Collection( item.storageCollectionId() );
1426 undoId =
kmkernel->undoStack()->newUndoAction( parent, mDestFolder );
1428 kmkernel->undoStack()->addMsgToAction( undoId, item );
1432 if ( !retrievedList.isEmpty() ) {
1433 Akonadi::ItemDeleteJob *job =
new Akonadi::ItemDeleteJob( retrievedList,
this );
1439 Q_ASSERT( !mProgressItem );
1441 ProgressManager::createProgressItem (QLatin1String(
"move")+ProgressManager::getUniqueID(),
1442 mDestFolder.isValid() ? i18n(
"Moving messages" ) : i18n(
"Deleting messages" ) );
1451 void KMMoveCommand::completeMove( Result result )
1453 if ( mProgressItem ) {
1481 Akonadi::Collection KMTrashMsgCommand::findTrashFolder(
const Akonadi::Collection& folder )
1483 Akonadi::Collection col = CommonKernel->trashCollectionFromResource( folder );
1484 if ( !col.isValid() ) {
1485 col = CommonKernel->trashCollectionFolder();
1487 if ( folder != col )
1489 return Akonadi::Collection();
1508 if ( item.hasPayload<KMime::Message::Ptr>() ) {
1509 contentsToSave += MessageViewer::Util::extractAttachments( item.payload<KMime::Message::Ptr>().get() );
1511 kWarning() <<
"Retrieved item has no payload? Ignoring for saving the attachments";
1514 if ( MessageViewer::Util::saveAttachments( contentsToSave,
parentWidget() ) )
1520 const Akonadi::Item &msg )
1524 fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1530 KMime::Message::Ptr msg = MessageCore::Util::message( item );
1534 MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
1535 factory.setIdentityManager(
KMKernel::self()->identityManager() );
1536 factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
1537 KMime::Message::Ptr newMsg = factory.createResend();
1538 newMsg->contentType()->setCharset( MessageViewer::NodeHelper::charset( msg.get() ) );
1541 if(msg->headerByType(
"Reply-To" )) {
1542 const QString replyTo = msg->headerByType(
"Reply-To" )->asUnicodeString();
1545 bool lastEncrypt =
false;
1546 bool lastSign =
false;
1548 win->
setMessage( newMsg, lastSign, lastEncrypt,
false,
true );
1564 KMime::Message::Ptr msg(
new KMime::Message );
1567 MessageHelper::initHeader( msg,
KMKernel::self()->identityManager(),
id );
1568 msg->contentType()->setCharset(
"utf-8");
1577 #include "kmcommands.moc"
QWidget * parentWidget() const
void messagesTransfered(KMCommand::Result result)
virtual void setFocusToSubject()=0
Sets the focus to the subject line edit.
void moveDone(KMMoveCommand *)
KMForwardCommand(QWidget *parent, const QList< Akonadi::Item > &msgList, uint identity=0, const QString &templateName=QString())
KMMailtoForwardCommand(QWidget *parent, const KUrl &url, const Akonadi::Item &msg)
bool deletesItself() const
void showMessage(const QString &encoding, const Akonadi::Item &msg, const Akonadi::Collection &parentCollection=Akonadi::Collection())
take ownership of and show
Akonadi::Item retrievedMessage() const
KMOpenMsgCommand(QWidget *parent, const KUrl &url=KUrl(), const QString &encoding=QString(), KMMainWidget *main=0)
This class implements a "reader window", that is a window used for reading or viewing messages...
static BroadcastStatus * instance()
MessageViewer::Viewer * viewer()
KMCommand(QWidget *parent=0)
KMUseTemplateCommand(QWidget *parent, const Akonadi::Item &msg)
Akonadi::Item::Id putRepliesInSameFolder(const Akonadi::Item &item)
Whether or not the mail item has the keep-reply-in-folder attribute set.
CollectionPane * messageListPane() const
Access to the header list pane.
void setOverrideFont(const QFont &)
virtual void setMessage(const KMime::Message::Ptr &newMsg, bool lastSignState=false, bool lastEncryptState=false, bool mayAutoSign=true, bool allowDecryption=false, bool isModified=false)=0
Set the message the composer shall work with.
void setResult(Result result)
Use this to set the result of the command.
void setHeaderStyleAndStrategy(MessageViewer::HeaderStyle *style, MessageViewer::HeaderStrategy *strategy)
Set the header style and strategy.
void incCompletedItems(unsigned int v=1)
KMFilterActionCommand(QWidget *parent, const QVector< qlonglong > &msgListId, const QString &filterId)
void slotMoveResult(KJob *job)
static KMKernel * self()
normal control stuff
Result result() const
Returns the result of the command.
KMime::Types::Mailbox::List mailingListsFromMessage(const Akonadi::Item &item)
Returns any mailing list post addresses set on the parent collection (the mail folder) of the item...
void setOverrideEncoding(const QString &encoding)
Set the override character encoding.
KMSaveAttachmentsCommand(QWidget *parent, const Akonadi::Item &msg)
Use this to save all attachments of the given message.
void setStatusMsg(const QString &message)
virtual void setFcc(const QString &idString)=0
virtual void setPrinting(bool enable)
MessageViewer::CSSHelper * cssHelper() const
void updatePaneTagComboBox()
virtual void addAttachment(const KUrl &url, const QString &comment)=0
KMMailtoReplyCommand(QWidget *parent, const KUrl &url, const Akonadi::Item &msg, const QString &selection)
KMPrintCommand(QWidget *parent, const Akonadi::Item &msg, MessageViewer::HeaderStyle *headerStyle=0, MessageViewer::HeaderStrategy *headerStrategy=0, bool htmlOverride=false, bool htmlLoadExtOverride=false, bool useFixedFont=false, const QString &encoding=QString())
KMMoveCommand(const Akonadi::Collection &destFolder, const QList< Akonadi::Item > &msgList, MessageList::Core::MessageItemSetReference ref)
virtual void addAttach(KMime::Content *msgPart)=0
Add an attachment to the list.
Small helper structure which encapsulates the KMMessage created when creating a reply, and.
virtual void setFolder(const Akonadi::Collection &)=0
If this folder is set, the original message is inserted back after canceling.
void setDecryptMessageOverwrite(bool overwrite=true)
Enforce message decryption.
void setDeletesItself(bool deletesItself)
Specify whether the subclass takes care of the deletion of the object.
Window class for secondary KMail window like the composer window and the separate message window...
static KMail::Composer::TemplateContext replyContext(MessageFactory::MessageReply reply)
Small helper function to get the composer context from a reply.
KMReplyCommand(QWidget *parent, const Akonadi::Item &msg, MessageComposer::ReplyStrategy replyStrategy, const QString &selection=QString(), bool noquote=false, const QString &templateName=QString())
KMShareImageCommand(const KUrl &url, QWidget *parent)
void slotModifyItemDone(KJob *job)
void setAttachmentStrategy(const MessageViewer::AttachmentStrategy *strategy)
void setEmitsCompletedItself(bool emitsCompletedItself)
Specify whether the subclass takes care of emitting the completed() signal.
void setHtmlOverride(bool override)
static void showJobError(KJob *job)
Helper to sanely show an error message for a job.
void setHtmlLoadExtOverride(bool override)
KMTrashMsgCommand(const Akonadi::Collection &srcFolder, const QList< Akonadi::Item > &msgList, MessageList::Core::MessageItemSetReference ref)
KMUrlSaveCommand(const KUrl &url, QWidget *parent)
KMEditMessageCommand(QWidget *parent, const KMime::Message::Ptr &msg)
const QList< Akonadi::Item > retrievedMsgs() const
virtual void setModified(bool modified)=0
KMRedirectCommand(QWidget *parent, const Akonadi::Item &msg)
virtual void setCurrentReplyTo(const QString &replyTo)=0
void slotCopyResult(KJob *job)
void completed(KMCommand *command)
Emitted when the command has completed.
void setAttachmentStrategy(const MessageViewer::AttachmentStrategy *strategy)
KMResendMessageCommand(QWidget *parent, const Akonadi::Item &msg=Akonadi::Item())
KMForwardAttachedCommand(QWidget *parent, const QList< Akonadi::Item > &msgList, uint identity=0, KMail::Composer *win=0)
KMAddBookmarksCommand(const KUrl &url, QWidget *parent)
void setUsesBusyIndicator(bool useBusyIndicator)
KMSetStatusCommand(const MessageStatus &status, const Akonadi::Item::List &items, bool invert=false)
bool emitsCompletedItself() const
KMMailtoComposeCommand(const KUrl &url, const Akonadi::Item &msg=Akonadi::Item())
void setPrintPreview(bool preview)
virtual void setCurrentTransport(int transportId)=0
Akonadi::ItemFetchScope & fetchScope()
Allows to configure how much data should be retrieved of the messages.
KMSetTagCommand(const QList< QString > &tagLabel, const QList< Akonadi::Item > &item, SetTagMode mode=AddIfNotExisting)
void lastEncryptAndSignState(bool &lastEncrypt, bool &lastSign, const KMime::Message::Ptr &msg)
KMCopyCommand(const Akonadi::Collection &destFolder, const QList< Akonadi::Item > &msgList)
virtual void setFocusToEditor()=0
Sets the focus to the edit-widget and the cursor below the "On ... you wrote" line when hasMessage is...
void setTotalItems(unsigned int v)
void addRecentFile(const KUrl &mUrl)
int main(int argc, char *argv[])
void setUseFixedFont(bool useFixedFont)
KMSaveMsgCommand(QWidget *parent, const QList< Akonadi::Item > &msgList)
QList< Akonadi::Item > mRetrievedMsgs
KMEditItemCommand(QWidget *parent, const Akonadi::Item &msg, bool deleteFromSource=true)
KMMailingListFilterCommand(QWidget *parent, const Akonadi::Item &msg)
void readConfig()
Read settings from app's config file.