Build with non-standard boost locations.
[kdepim.git] / messagecomposer / akonadisender.cpp
blob6ffcc9be08798bf4e68eda4b254a05968948e355
1 /*
2 * This file is part of KMail.
3 * Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "akonadisender.h"
22 #include <KMessageBox>
23 #include <KLocale>
24 #include <KDebug>
25 #include <KConfig>
26 #include <KConfigGroup>
28 #include "messagehelper.h"
29 #include "messagecomposersettings.h"
31 #include <kmime/kmime_message.h>
32 #include <boost/shared_ptr.hpp>
34 #include <progressmanager.h>
36 #include <mailtransport/dispatcherinterface.h>
37 #include <mailtransport/messagequeuejob.h>
38 #include <mailtransport/transport.h>
39 #include <mailtransport/transportmanager.h>
40 #include <messagecore/stringutil.h>
42 using namespace KMime;
43 using namespace KMime::Types;
44 using namespace KPIM;
45 using namespace MailTransport;
48 static QStringList addrSpecListToStringList( const AddrSpecList &l, bool allowEmpty = false )
50 QStringList result;
51 for ( AddrSpecList::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it ) {
52 const QString s = (*it).asString();
53 if ( allowEmpty || !s.isEmpty() )
54 result.push_back( s );
56 return result;
60 static void extractSenderToCCAndBcc( const KMime::Message::Ptr &aMsg, QString &sender, QStringList &to, QStringList &cc, QStringList &bcc )
62 sender = aMsg->sender()->asUnicodeString();
63 if( aMsg->headerByType("X-KMail-Recipients") ) {
64 // extended BCC handling to prevent TOs and CCs from seeing
65 // BBC information by looking at source of an OpenPGP encrypted mail
66 to = addrSpecListToStringList( MessageHelper::extractAddrSpecs( aMsg, "X-KMail-Recipients" ) );
67 aMsg->removeHeader( "X-KMail-Recipients" );
68 } else {
69 to = addrSpecListToStringList( MessageHelper::extractAddrSpecs( aMsg, "To" ) );
70 cc = addrSpecListToStringList( MessageHelper::extractAddrSpecs( aMsg, "Cc" ) );
71 bcc = addrSpecListToStringList( MessageHelper::extractAddrSpecs( aMsg, "Bcc" ) );
77 AkonadiSender::AkonadiSender()
78 : mProgressItem( 0 )
82 bool AkonadiSender::doSend( const KMime::Message::Ptr &aMsg, short sendNow )
84 if( sendNow == -1 ) {
85 sendNow = MessageComposer::MessageComposerSettings::self()->sendImmediate(); // -1 == use default setting
87 if ( !sendNow ) {
88 sendOrQueueMessage( aMsg, MessageSender::SendLater );
89 } else {
90 sendOrQueueMessage( aMsg, MessageSender::SendImmediate );
92 return true;
95 bool AkonadiSender::doSendQueued( const QString &customTransport )
97 kDebug() << "Sending queued message with custom transport:" << customTransport;
98 mCustomTransport = customTransport;
100 DispatcherInterface *dispatcher = new DispatcherInterface();
101 if( mCustomTransport.isEmpty() ) {
102 dispatcher->dispatchManually();
103 } else {
104 dispatcher->dispatchManualTransport( TransportManager::self()->transportByName( mCustomTransport )->id() );
106 delete dispatcher;
107 return true;
110 void AkonadiSender::sendOrQueueMessage( const KMime::Message::Ptr &message, MessageSender::SendMethod method )
112 Q_ASSERT( message );
113 kDebug() << "KMime::Message: \n[\n" << message->encodedContent().left( 1000 ) << "\n]\n";
115 MessageQueueJob *qjob = new MessageQueueJob( this );
116 if ( message->headerByType( "X-KMail-Fcc" ) ) {
117 qjob->sentBehaviourAttribute().setSentBehaviour(
118 SentBehaviourAttribute::MoveToCollection );
119 const int sentCollectionId = message->headerByType( "X-KMail-Fcc" )->asUnicodeString().toInt();
120 qjob->sentBehaviourAttribute().setMoveToCollection(
121 Akonadi::Collection( sentCollectionId ) );
122 } else {
123 qjob->sentBehaviourAttribute().setSentBehaviour(
124 MailTransport::SentBehaviourAttribute::MoveToDefaultSentCollection );
126 qjob->setMessage( message );
128 // Get transport.
129 QString transportName = mCustomTransport;
130 kDebug() << "Custom transportName:" << mCustomTransport;
131 if( transportName.isEmpty() ) {
132 transportName = message->headerByType( "X-KMail-Transport" ) ? message->headerByType( "X-KMail-Transport" )->asUnicodeString() : QString();
133 kDebug() << "TransportName from headers:" << transportName;
135 if( transportName.isEmpty() ) {
136 transportName = TransportManager::self()->defaultTransportName();
137 kDebug() << "Default transport" << TransportManager::self()->defaultTransportName();
139 Transport *transport = TransportManager::self()->transportByName( transportName );
140 Q_ASSERT( transport );
141 kDebug() << "Using transport (" << transportName << "," << transport->id() << ")";
142 qjob->transportAttribute().setTransportId( transport->id() );
144 // if we want to manually queue it for sending later, then do it
145 if( method == MessageSender::SendLater )
146 qjob->dispatchModeAttribute().setDispatchMode( MailTransport::DispatchModeAttribute::Manual );
148 // Get addresses.
149 QStringList to, cc, bcc;
150 QString from;
151 extractSenderToCCAndBcc( message, from, to, cc, bcc );
152 qjob->addressAttribute().setFrom( from );
153 qjob->addressAttribute().setTo( to );
154 qjob->addressAttribute().setCc( cc );
155 qjob->addressAttribute().setBcc( bcc );
157 MessageCore::StringUtil::removePrivateHeaderFields( message );
159 // Queue the message.
160 connect( qjob, SIGNAL(result(KJob*)), this, SLOT(queueJobResult(KJob*)) );
161 mPendingJobs.insert( qjob );
162 qjob->start();
163 kDebug() << "QueueJob started.";
165 // TODO potential problem:
166 // The MDA finishes sending a message before I queue the next one, and
167 // thinking it is finished, the progress item deletes itself.
168 // Turn the MDA offline until everything is queued?
171 void AkonadiSender::queueJobResult( KJob *job )
173 Q_ASSERT( mPendingJobs.contains( job ) );
174 mPendingJobs.remove( job );
176 if( job->error() ) {
177 kDebug() << "QueueJob failed with error" << job->errorString();
178 } else {
179 kDebug() << "QueueJob success.";
183 #include "akonadisender.moc"