• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kmail

  • sources
  • kde-4.14
  • kdepim
  • kmail
kmcommands.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2  This file is part of KMail, the KDE mail client.
3  Copyright (c) 2002 Don Sanders <sanders@kde.org>
4  Copyright (C) 2013-2015 Laurent Montel <montel@kde.org>
5 
6  KMail is free software; you can redistribute it and/or modify it
7  under the terms of the GNU General Public License, version 2, as
8  published by the Free Software Foundation.
9 
10  KMail is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 //
21 // This file implements various "command" classes. These command classes
22 // are based on the command design pattern.
23 //
24 // Historically various operations were implemented as slots of KMMainWin.
25 // This proved inadequate as KMail has multiple top level windows
26 // (KMMainWin, KMReaderMainWin, SearchWindow, KMComposeWin) that may
27 // benefit from using these operations. It is desirable that these
28 // classes can operate without depending on or altering the state of
29 // a KMMainWin, in fact it is possible no KMMainWin object even exists.
30 //
31 // Now these operations have been rewritten as KMCommand based classes,
32 // making them independent of KMMainWin.
33 //
34 // The base command class KMCommand is async, which is a difference
35 // from the conventional command pattern. As normal derived classes implement
36 // the execute method, but client classes call start() instead of
37 // calling execute() directly. start() initiates async operations,
38 // and on completion of these operations calls execute() and then deletes
39 // the command. (So the client must not construct commands on the stack).
40 //
41 // The type of async operation supported by KMCommand is retrieval
42 // of messages from an IMAP server.
43 
44 #include "kmcommands.h"
45 
46 #include "widgets/collectionpane.h"
47 #include "kernel/mailkernel.h"
48 #include "util/mailutil.h"
49 
50 #include <unistd.h> // link()
51 #include <kprogressdialog.h>
52 #include <kpimutils/email.h>
53 #include <kdbusservicestarter.h>
54 #include <kdebug.h>
55 #include <kfiledialog.h>
56 #include <klocale.h>
57 #include <kmessagebox.h>
58 #include <kbookmarkmanager.h>
59 #include <kstandarddirs.h>
60 #include <ktemporaryfile.h>
61 // KIO headers
62 #include <kio/job.h>
63 #include <kio/jobuidelegate.h>
64 #include <kio/netaccess.h>
65 
66 #include <kmime/kmime_message.h>
67 
68 #include <kpimidentities/identitymanager.h>
69 #include <akonadi/itemmodifyjob.h>
70 #include <akonadi/itemfetchjob.h>
71 
72 
73 #include "foldercollection.h"
74 
75 #include "messagecore/misc/mailinglist.h"
76 #include "editor/composer.h"
77 #include "mailcommon/filter/filteractions/filteraction.h"
78 #include "mailcommon/filter/filtermanager.h"
79 #include "mailcommon/filter/mailfilter.h"
80 #include "mailcommon/widgets/redirectdialog.h"
81 #include "kmmainwidget.h"
82 #include "undostack.h"
83 #ifndef QT_NO_CURSOR
84 #include "messageviewer/utils/kcursorsaver.h"
85 #endif
86 #include "messageviewer/viewer/objecttreeparser.h"
87 #include "messageviewer/viewer/csshelper.h"
88 #include "messageviewer/utils/util.h"
89 #include "messageviewer/viewer/mailsourceviewer.h"
90 #include "messageviewer/header/headerstrategy.h"
91 #include "messageviewer/header/headerstyle.h"
92 #include "kmreadermainwin.h"
93 #include "secondarywindow.h"
94 using KMail::SecondaryWindow;
95 #include "util.h"
96 #include "misc/broadcaststatus.h"
97 #include "settings/globalsettings.h"
98 #include "utils/stringutil.h"
99 #include "messageviewer/utils/autoqpointer.h"
100 #include "messageviewer/settings/globalsettings.h"
101 #include "messagecore/settings/globalsettings.h"
102 
103 #include <kpimutils/kfileio.h>
104 
105 #include <akonadi/itemmovejob.h>
106 #include <akonadi/itemcopyjob.h>
107 #include <akonadi/itemdeletejob.h>
108 #include <akonadi/tag.h>
109 #include <akonadi/tagcreatejob.h>
110 #include <mailtransport/transportattribute.h>
111 #include <mailtransport/sentbehaviourattribute.h>
112 
113 #include <messagelist/pane.h>
114 
115 #include <mailtransport/transportmanager.h>
116 using MailTransport::TransportManager;
117 
118 
119 #include "messageviewer/viewer/nodehelper.h"
120 #include "messageviewer/viewer/objecttreeemptysource.h"
121 
122 #include "messagecore/utils/stringutil.h"
123 #include "messagecore/helpers/messagehelpers.h"
124 
125 #include "messagecomposer/sender/messagesender.h"
126 #include "messagecomposer/helper/messagehelper.h"
127 #include "messagecomposer/settings/messagecomposersettings.h"
128 #include "messagecomposer/helper/messagefactory.h"
129 using MessageComposer::MessageFactory;
130 
131 
132 #include "progresswidget/progressmanager.h"
133 using KPIM::ProgressManager;
134 using KPIM::ProgressItem;
135 #include <kmime/kmime_mdn.h>
136 using namespace KMime;
137 
138 #include "kleo/cryptobackend.h"
139 #include "kleo/cryptobackendfactory.h"
140 
141 #include <gpgme++/error.h>
142 
143 #include <QByteArray>
144 #include <QApplication>
145 #include <QList>
146 
147 #ifndef Q_MOC_RUN
148 #include <boost/bind.hpp>
149 #endif
150 #include <algorithm>
151 #include <memory>
152 
153 
154 using namespace MailCommon;
155 
157 static KMail::Composer::TemplateContext replyContext( MessageFactory::MessageReply reply )
158 {
159  if ( reply.replyAll )
160  return KMail::Composer::ReplyToAll;
161  else
162  return KMail::Composer::Reply;
163 }
164 
166 static void showJobError( KJob* job )
167 {
168  assert(job);
169  // we can be called from the KJob::kill, where we are no longer a KIO::Job
170  // so better safe than sorry
171  KIO::Job* kiojob = dynamic_cast<KIO::Job*>(job);
172  if( kiojob && kiojob->ui() )
173  kiojob->ui()->showErrorMessage();
174  else
175  kWarning() << "There is no GUI delegate set for a kjob, and it failed with error:" << job->errorString();
176 }
177 
178 KMCommand::KMCommand( QWidget *parent )
179  : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
180  mEmitsCompletedItself( false ), mParent( parent )
181 {
182 }
183 
184 KMCommand::KMCommand( QWidget *parent, const Akonadi::Item &msg )
185  : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
186  mEmitsCompletedItself( false ), mParent( parent )
187 {
188  if ( msg.isValid() || msg.hasPayload<KMime::Message::Ptr>() ) {
189  mMsgList.append( msg );
190  }
191 }
192 
193 KMCommand::KMCommand( QWidget *parent, const QList<Akonadi::Item> &msgList )
194  : mCountMsgs(0), mResult( Undefined ), mDeletesItself( false ),
195  mEmitsCompletedItself( false ), mParent( parent )
196 {
197  mMsgList = msgList;
198 }
199 
200 
201 
202 KMCommand::~KMCommand()
203 {
204 }
205 
206 KMCommand::Result KMCommand::result() const
207 {
208  if ( mResult == Undefined ) {
209  kDebug() << "mResult is Undefined";
210  }
211  return mResult;
212 }
213 
214 const QList<Akonadi::Item> KMCommand::retrievedMsgs() const
215 {
216  return mRetrievedMsgs;
217 }
218 
219 Akonadi::Item KMCommand::retrievedMessage() const
220 {
221  if ( mRetrievedMsgs.isEmpty() )
222  return Akonadi::Item();
223  return *(mRetrievedMsgs.begin());
224 }
225 
226 QWidget *KMCommand::parentWidget() const
227 {
228  return mParent;
229 }
230 
231 int KMCommand::mCountJobs = 0;
232 
233 void KMCommand::start()
234 {
235  connect( this, SIGNAL(messagesTransfered(KMCommand::Result)),
236  this, SLOT(slotPostTransfer(KMCommand::Result)) );
237 
238  if ( mMsgList.isEmpty() ) {
239  emit messagesTransfered( OK );
240  return;
241  }
242 
243  // Special case of operating on message that isn't in a folder
244  const Akonadi::Item mb = mMsgList.first();
245  if ( ( mMsgList.count() == 1 ) && MessageCore::Util::isStandaloneMessage( mb ) ) {
246  mRetrievedMsgs.append(mMsgList.takeFirst());
247  emit messagesTransfered( OK );
248  return;
249  }
250 
251  // we can only retrieve items with a valid id
252  foreach ( const Akonadi::Item &item, mMsgList ) {
253  if ( !item.isValid() ) {
254  emit messagesTransfered( Failed );
255  return;
256  }
257  }
258 
259  // transfer the selected messages first
260  transferSelectedMsgs();
261 }
262 
263 void KMCommand::slotPostTransfer( KMCommand::Result result )
264 {
265  disconnect( this, SIGNAL(messagesTransfered(KMCommand::Result)),
266  this, SLOT(slotPostTransfer(KMCommand::Result)) );
267  if ( result == OK ) {
268  result = execute();
269  }
270  mResult = result;
271  if ( !emitsCompletedItself() )
272  emit completed( this );
273  if ( !deletesItself() )
274  deleteLater();
275 }
276 
277 Akonadi::ItemFetchJob *KMCommand::createFetchJob( const Akonadi::Item::List &items )
278 {
279  return new Akonadi::ItemFetchJob( items, this );
280 }
281 
282 void KMCommand::transferSelectedMsgs()
283 {
284  // make sure no other transfer is active
285  if (KMCommand::mCountJobs > 0) {
286  emit messagesTransfered( Failed );
287  return;
288  }
289 
290  bool complete = true;
291  KMCommand::mCountJobs = 0;
292  mCountMsgs = 0;
293  mRetrievedMsgs.clear();
294  mCountMsgs = mMsgList.count();
295  uint totalSize = 0;
296  // the KProgressDialog for the user-feedback. Only enable it if it's needed.
297  // For some commands like KMSetStatusCommand it's not needed. Note, that
298  // for some reason the KProgressDialog eats the MouseReleaseEvent (if a
299  // command is executed after the MousePressEvent), cf. bug #71761.
300  if ( mCountMsgs > 0 ) {
301  mProgressDialog = new KProgressDialog(mParent,
302  i18n("Please wait"),
303  i18np("Please wait while the message is transferred",
304  "Please wait while the %1 messages are transferred", mMsgList.count()));
305  mProgressDialog.data()->setModal(true);
306  mProgressDialog.data()->setMinimumDuration(1000);
307  }
308 
309  // TODO once the message list is based on ETM and we get the more advanced caching we need to make that check a bit more clever
310  if ( !mFetchScope.isEmpty() ) {
311  complete = false;
312  ++KMCommand::mCountJobs;
313  Akonadi::ItemFetchJob *fetch = createFetchJob( mMsgList );
314  mFetchScope.fetchAttribute< MessageCore::MDNStateAttribute >();
315  fetch->setFetchScope( mFetchScope );
316  connect( fetch, SIGNAL(itemsReceived(Akonadi::Item::List)), SLOT(slotMsgTransfered(Akonadi::Item::List)) );
317  connect( fetch, SIGNAL(result(KJob*)), SLOT(slotJobFinished()) );
318  } else {
319  // no need to fetch anything
320  if ( !mMsgList.isEmpty() )
321  mRetrievedMsgs = mMsgList;
322  }
323 
324  if ( complete ) {
325  delete mProgressDialog.data();
326  mProgressDialog.clear();
327  emit messagesTransfered( OK );
328  } else {
329  // wait for the transfer and tell the progressBar the necessary steps
330  if ( mProgressDialog.data() ) {
331  connect(mProgressDialog.data(), SIGNAL(cancelClicked()),
332  this, SLOT(slotTransferCancelled()));
333  mProgressDialog.data()->progressBar()->setMaximum(totalSize);
334  }
335  }
336 }
337 
338 void KMCommand::slotMsgTransfered(const Akonadi::Item::List& msgs)
339 {
340  if ( mProgressDialog.data() && mProgressDialog.data()->wasCancelled() ) {
341  emit messagesTransfered( Canceled );
342  return;
343  }
344  // save the complete messages
345  mRetrievedMsgs.append( msgs );
346 }
347 
348 void KMCommand::slotJobFinished()
349 {
350  // the job is finished (with / without error)
351  KMCommand::mCountJobs--;
352 
353  if ( mProgressDialog.data() && mProgressDialog.data()->wasCancelled() ) return;
354 
355  if ( mCountMsgs > mRetrievedMsgs.count() )
356  {
357  // the message wasn't retrieved before => error
358  if ( mProgressDialog.data() )
359  mProgressDialog.data()->hide();
360  slotTransferCancelled();
361  return;
362  }
363  // update the progressbar
364  if ( mProgressDialog.data() ) {
365  mProgressDialog.data()->setLabelText(i18np("Please wait while the message is transferred",
366  "Please wait while the %1 messages are transferred", KMCommand::mCountJobs));
367  }
368  if (KMCommand::mCountJobs == 0)
369  {
370  // all done
371  delete mProgressDialog.data();
372  mProgressDialog.clear();
373  emit messagesTransfered( OK );
374  }
375 }
376 
377 void KMCommand::slotTransferCancelled()
378 {
379  KMCommand::mCountJobs = 0;
380  mCountMsgs = 0;
381  mRetrievedMsgs.clear();
382  emit messagesTransfered( Canceled );
383 }
384 
385 
386 KMMailtoComposeCommand::KMMailtoComposeCommand( const KUrl &url,
387  const Akonadi::Item &msg )
388  :mUrl( url ), mMessage( msg )
389 {
390 }
391 
392 KMCommand::Result KMMailtoComposeCommand::execute()
393 {
394  KMime::Message::Ptr msg( new KMime::Message );
395  uint id = 0;
396 
397  if ( mMessage.isValid() && mMessage.parentCollection().isValid() ) {
398  QSharedPointer<FolderCollection> fd = FolderCollection::forCollection( mMessage.parentCollection(), false );
399  id = fd->identity();
400  }
401 
402  MessageHelper::initHeader( msg, KMKernel::self()->identityManager(),id );
403  msg->contentType()->setCharset("utf-8");
404  if (mUrl.protocol().toLower() == QLatin1String("mailto") ) {
405  msg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ), "utf-8" );
406  }
407 
408  KMail::Composer * win = KMail::makeComposer( msg, false, false,KMail::Composer::New, id );
409  win->setFocusToSubject();
410  win->show();
411  return OK;
412 }
413 
414 
415 KMMailtoReplyCommand::KMMailtoReplyCommand( QWidget *parent,
416  const KUrl &url, const Akonadi::Item &msg, const QString &selection )
417  :KMCommand( parent, msg ), mUrl( url ), mSelection( selection )
418 {
419  fetchScope().fetchFullPayload( true );
420  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
421 }
422 
423 KMCommand::Result KMMailtoReplyCommand::execute()
424 {
425  Akonadi::Item item = retrievedMessage();
426  KMime::Message::Ptr msg = MessageCore::Util::message( item );
427  if ( !msg )
428  return Failed;
429  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
430  factory.setIdentityManager( KMKernel::self()->identityManager() );
431  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
432  factory.setMailingListAddresses( KMail::Util::mailingListsFromMessage( item ) );
433  factory.putRepliesInSameFolder( KMail::Util::putRepliesInSameFolder( item ) );
434  factory.setReplyStrategy( MessageComposer::ReplyNone );
435  factory.setSelection( mSelection );
436  KMime::Message::Ptr rmsg = factory.createReply().msg;
437  rmsg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ), "utf-8" ); //TODO Check the UTF-8
438  bool lastEncrypt = false;
439  bool lastSign = false;
440  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
441 
442  KMail::Composer * win = KMail::makeComposer( rmsg, lastSign, lastEncrypt, KMail::Composer::Reply, 0, mSelection );
443  win->setFocusToEditor();
444  win->show();
445 
446  return OK;
447 }
448 
449 
450 KMMailtoForwardCommand::KMMailtoForwardCommand( QWidget *parent,
451  const KUrl &url, const Akonadi::Item &msg )
452  :KMCommand( parent, msg ), mUrl( url )
453 {
454  fetchScope().fetchFullPayload( true );
455  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
456 }
457 
458 KMCommand::Result KMMailtoForwardCommand::execute()
459 {
460  //TODO : consider factoring createForward into this method.
461  Akonadi::Item item = retrievedMessage();
462  KMime::Message::Ptr msg = MessageCore::Util::message( item );
463  if ( !msg )
464  return Failed;
465  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
466  factory.setIdentityManager( KMKernel::self()->identityManager() );
467  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
468  KMime::Message::Ptr fmsg = factory.createForward();
469  fmsg->to()->fromUnicodeString( KPIMUtils::decodeMailtoUrl( mUrl ).toLower(), "utf-8" ); //TODO check the utf-8
470  bool lastEncrypt = false;
471  bool lastSign = false;
472  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
473 
474  KMail::Composer * win = KMail::makeComposer( fmsg, lastSign, lastEncrypt, KMail::Composer::Forward );
475  win->show();
476 
477  return OK;
478 }
479 
480 
481 KMAddBookmarksCommand::KMAddBookmarksCommand( const KUrl &url, QWidget *parent )
482  : KMCommand( parent ), mUrl( url )
483 {
484 }
485 
486 KMCommand::Result KMAddBookmarksCommand::execute()
487 {
488  const QString filename = KStandardDirs::locateLocal( "data", QString::fromLatin1("konqueror/bookmarks.xml") );
489  KBookmarkManager *bookManager = KBookmarkManager::managerForFile( filename, QLatin1String("konqueror") );
490  KBookmarkGroup group = bookManager->root();
491  group.addBookmark( mUrl.path(), KUrl( mUrl ) );
492  if( bookManager->save() ) {
493  bookManager->emitChanged( group );
494  }
495 
496  return OK;
497 }
498 
499 KMUrlSaveCommand::KMUrlSaveCommand( const KUrl &url, QWidget *parent )
500  : KMCommand( parent ), mUrl( url )
501 {
502 }
503 
504 KMCommand::Result KMUrlSaveCommand::execute()
505 {
506  if ( mUrl.isEmpty() )
507  return OK;
508  const KUrl saveUrl = KFileDialog::getSaveUrl(mUrl.fileName(), QString(),
509  parentWidget() );
510  if ( saveUrl.isEmpty() )
511  return Canceled;
512  if ( KIO::NetAccess::exists( saveUrl, KIO::NetAccess::DestinationSide, parentWidget() ) )
513  {
514  if (KMessageBox::warningContinueCancel(0,
515  i18nc("@info", "File <filename>%1</filename> exists.<nl/>Do you want to replace it?",
516  saveUrl.pathOrUrl()), i18n("Save to File"), KGuiItem(i18n("&Replace")))
517  != KMessageBox::Continue)
518  return Canceled;
519  }
520  KIO::Job *job = KIO::file_copy(mUrl, saveUrl, -1, KIO::Overwrite);
521  connect(job, SIGNAL(result(KJob*)), SLOT(slotUrlSaveResult(KJob*)));
522  setEmitsCompletedItself( true );
523  return OK;
524 }
525 
526 void KMUrlSaveCommand::slotUrlSaveResult( KJob *job )
527 {
528  if ( job->error() ) {
529  showJobError(job);
530  setResult( Failed );
531  emit completed( this );
532  }
533  else {
534  setResult( OK );
535  emit completed( this );
536  }
537 }
538 
539 KMEditMessageCommand::KMEditMessageCommand( QWidget *parent, const KMime::Message::Ptr& msg )
540  :KMCommand( parent ), mMessage( msg )
541 {
542 }
543 
544 KMCommand::Result KMEditMessageCommand::execute()
545 {
546  if ( !mMessage )
547  return Failed;
548 
549  KMail::Composer *win = KMail::makeComposer();
550  bool lastEncrypt = false;
551  bool lastSign = false;
552  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, mMessage);
553  win->setMessage( mMessage, lastSign, lastEncrypt, false, true );
554  win->show();
555  return OK;
556 }
557 
558 
559 KMEditItemCommand::KMEditItemCommand( QWidget *parent, const Akonadi::Item&msg, bool deleteFromSource )
560  :KMCommand( parent, msg )
561  , mDeleteFromSource( deleteFromSource )
562 {
563  fetchScope().fetchFullPayload( true );
564  fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
565  fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
566  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
567 }
568 
569 KMEditItemCommand::~KMEditItemCommand()
570 {
571 }
572 
573 
574 KMCommand::Result KMEditItemCommand::execute()
575 {
576  Akonadi::Item item = retrievedMessage();
577  if (!item.isValid() || !item.parentCollection().isValid() ) {
578  return Failed;
579  }
580  KMime::Message::Ptr msg = MessageCore::Util::message( item );
581  if ( !msg ) {
582  return Failed;
583  }
584 
585  if ( mDeleteFromSource ) {
586  setDeletesItself( true );
587  Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob( item );
588  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotDeleteItem(KJob*)) );
589  }
590  KMail::Composer *win = KMail::makeComposer();
591  bool lastEncrypt = false;
592  bool lastSign = false;
593  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
594  win->setMessage( msg, lastSign, lastEncrypt, false, true );
595 
596  win->setFolder( item.parentCollection() );
597 
598  const MailTransport::TransportAttribute *transportAttribute = item.attribute<MailTransport::TransportAttribute>();
599  if ( transportAttribute ) {
600  win->setCurrentTransport( transportAttribute->transportId() );
601  } else {
602  int transportId = msg->headerByType( "X-KMail-Transport" ) ? msg->headerByType( "X-KMail-Transport" )->asUnicodeString().toInt() : -1;
603  if(transportId!=-1) {
604  win->setCurrentTransport( transportId );
605  }
606  }
607 
608 
609  if(msg->headerByType( "Reply-To" )) {
610  const QString replyTo = msg->headerByType( "Reply-To" )->asUnicodeString();
611  win->setCurrentReplyTo(replyTo);
612  }
613 
614  const MailTransport::SentBehaviourAttribute *sentAttribute = item.attribute<MailTransport::SentBehaviourAttribute>();
615  if ( sentAttribute && ( sentAttribute->sentBehaviour() == MailTransport::SentBehaviourAttribute::MoveToCollection ) )
616  win->setFcc( QString::number( sentAttribute->moveToCollection().id() ) );
617  win->show();
618  if ( mDeleteFromSource )
619  win->setModified( true );
620 
621  return OK;
622 }
623 
624 void KMEditItemCommand::slotDeleteItem( KJob *job )
625 {
626  if ( job->error() ) {
627  showJobError(job);
628  setResult( Failed );
629  emit completed( this );
630  }
631  else {
632  setResult( OK );
633  emit completed( this );
634  }
635  deleteLater( );
636 }
637 
638 KMUseTemplateCommand::KMUseTemplateCommand( QWidget *parent, const Akonadi::Item &msg )
639  :KMCommand( parent, msg )
640 {
641  fetchScope().fetchFullPayload( true );
642  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
643 }
644 
645 KMCommand::Result KMUseTemplateCommand::execute()
646 {
647  Akonadi::Item item = retrievedMessage();
648  if ( !item.isValid()
649  || !item.parentCollection().isValid() ||
650  !CommonKernel->folderIsTemplates( item.parentCollection() )
651  ) {
652  return Failed;
653  }
654  KMime::Message::Ptr msg = MessageCore::Util::message( item );
655  if ( !msg )
656  return Failed;
657 
658  KMime::Message::Ptr newMsg(new KMime::Message);
659  newMsg->setContent( msg->encodedContent() );
660  newMsg->parse();
661  // these fields need to be regenerated for the new message
662  newMsg->removeHeader("Date");
663  newMsg->removeHeader("Message-ID");
664 
665  KMail::Composer *win = KMail::makeComposer();
666 
667  win->setMessage( newMsg, false, false, false, true );
668  win->show();
669  return OK;
670 }
671 
672 KMSaveMsgCommand::KMSaveMsgCommand( QWidget *parent, const QList<Akonadi::Item> &msgList )
673  : KMCommand( parent, msgList )
674 {
675  if ( msgList.empty() )
676  return;
677 
678  fetchScope().fetchFullPayload( true ); // ### unless we call the corresponding KMCommand ctor, this has no effect
679 }
680 
681 KMCommand::Result KMSaveMsgCommand::execute()
682 {
683  if ( !MessageViewer::Util::saveMessageInMbox( retrievedMsgs(), parentWidget()) )
684  return Failed;
685  return OK;
686 }
687 
688 //-----------------------------------------------------------------------------
689 
690 KMOpenMsgCommand::KMOpenMsgCommand( QWidget *parent, const KUrl & url,
691  const QString & encoding, KMMainWidget *main )
692  : KMCommand( parent ),
693  mUrl( url ),
694  mJob( 0 ),
695  mEncoding( encoding ),
696  mMainWidget( main )
697 {
698  qDebug()<<"url :"<<url;
699 }
700 
701 KMCommand::Result KMOpenMsgCommand::execute()
702 {
703  if ( mUrl.isEmpty() ) {
704  mUrl = KFileDialog::getOpenUrl( KUrl( QLatin1String("kfiledialog:///OpenMessage") ),
705  QLatin1String("message/rfc822 application/mbox"),
706  parentWidget(), i18n("Open Message") );
707  }
708  if ( mUrl.isEmpty() ) {
709  return Canceled;
710  }
711 
712  if(mMainWidget) {
713  mMainWidget->addRecentFile(mUrl);
714  }
715 
716  setDeletesItself( true );
717  mJob = KIO::get( mUrl, KIO::NoReload, KIO::HideProgressInfo );
718  connect( mJob, SIGNAL(data(KIO::Job*,QByteArray)),
719  this, SLOT(slotDataArrived(KIO::Job*,QByteArray)) );
720  connect( mJob, SIGNAL(result(KJob*)),
721  SLOT(slotResult(KJob*)) );
722  setEmitsCompletedItself( true );
723  return OK;
724 }
725 
726 void KMOpenMsgCommand::slotDataArrived( KIO::Job *, const QByteArray & data )
727 {
728  if ( data.isEmpty() )
729  return;
730 
731  mMsgString.append( QString::fromLatin1(data.data()) );
732 }
733 
734 void KMOpenMsgCommand::doesNotContainMessage()
735 {
736  KMessageBox::sorry( parentWidget(),
737  i18n( "The file does not contain a message." ) );
738  setResult( Failed );
739  emit completed( this );
740  // Emulate closing of a secondary window so that KMail exits in case it
741  // was started with the --view command line option. Otherwise an
742  // invisible KMail would keep running.
743  SecondaryWindow *win = new SecondaryWindow();
744  win->close();
745  win->deleteLater();
746  deleteLater();
747 
748 }
749 
750 void KMOpenMsgCommand::slotResult( KJob *job )
751 {
752  if ( job->error() ) {
753  // handle errors
754  showJobError(job);
755  setResult( Failed );
756  emit completed( this );
757  }
758  else {
759  if (mMsgString.isEmpty()) {
760  qDebug()<<" Message not found. There is a problem";
761  doesNotContainMessage();
762  return;
763  }
764  int startOfMessage = 0;
765  if ( mMsgString.startsWith( QLatin1String( "From " ) ) ) {
766  startOfMessage = mMsgString.indexOf( QLatin1Char('\n') );
767  if ( startOfMessage == -1 ) {
768  doesNotContainMessage();
769  return;
770  }
771  startOfMessage += 1; // the message starts after the '\n'
772  }
773  // check for multiple messages in the file
774  bool multipleMessages = true;
775  int endOfMessage = mMsgString.indexOf( QLatin1String("\nFrom ") );
776  if ( endOfMessage == -1 ) {
777  endOfMessage = mMsgString.length();
778  multipleMessages = false;
779  }
780  KMime::Message *msg = new KMime::Message;
781  msg->setContent( KMime::CRLFtoLF( mMsgString.mid( startOfMessage,endOfMessage - startOfMessage ).toUtf8() ) );
782  msg->parse();
783  if ( !msg->hasContent() ) {
784  delete msg; msg = 0;
785  doesNotContainMessage();
786  return;
787  }
788  KMReaderMainWin *win = new KMReaderMainWin();
789  KMime::Message::Ptr mMsg( msg );
790  win->showMessage( mEncoding, mMsg );
791  win->show();
792  if ( multipleMessages )
793  KMessageBox::information( win,
794  i18n( "The file contains multiple messages. "
795  "Only the first message is shown." ) );
796  setResult( OK );
797  emit completed( this );
798  }
799  deleteLater();
800 }
801 
802 //-----------------------------------------------------------------------------
803 KMReplyCommand::KMReplyCommand( QWidget *parent, const Akonadi::Item &msg, MessageComposer::ReplyStrategy replyStrategy,
804  const QString &selection, bool noquote, const QString& templateName )
805  : KMCommand( parent, msg ),
806  mSelection( selection ),
807  mTemplate( templateName ),
808  m_replyStrategy( replyStrategy ),
809  mNoQuote(noquote)
810 
811 {
812  if ( !noquote )
813  fetchScope().fetchFullPayload( true );
814 
815  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
816 }
817 
818 KMCommand::Result KMReplyCommand::execute()
819 {
820 #ifndef QT_NO_CURSOR
821  MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
822 #endif
823  Akonadi::Item item = retrievedMessage();
824  KMime::Message::Ptr msg = MessageCore::Util::message( item );
825  if ( !msg )
826  return Failed;
827 
828  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
829  factory.setIdentityManager( KMKernel::self()->identityManager() );
830  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
831  factory.setMailingListAddresses( KMail::Util::mailingListsFromMessage( item ) );
832  factory.putRepliesInSameFolder( KMail::Util::putRepliesInSameFolder( item ) );
833  factory.setReplyStrategy( m_replyStrategy );
834  factory.setSelection( mSelection );
835  if ( !mTemplate.isEmpty() )
836  factory.setTemplate( mTemplate );
837  if(mNoQuote) {
838  factory.setQuote(false);
839  }
840  bool lastEncrypt = false;
841  bool lastSign = false;
842  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
843 
844  MessageFactory::MessageReply reply = factory.createReply();
845  KMail::Composer * win = KMail::makeComposer( KMime::Message::Ptr( reply.msg ), lastSign, lastEncrypt, replyContext( reply ), 0,
846  mSelection,mTemplate );
847  win->setFocusToEditor();
848  win->show();
849 
850  return OK;
851 }
852 
853 
854 KMForwardCommand::KMForwardCommand( QWidget *parent,
855  const QList<Akonadi::Item> &msgList, uint identity,const QString& templateName )
856  : KMCommand( parent, msgList ),
857  mIdentity( identity ),
858  mTemplate( templateName )
859 {
860  fetchScope().fetchFullPayload( true );
861  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
862 }
863 
864 KMForwardCommand::KMForwardCommand( QWidget *parent, const Akonadi::Item &msg,
865  uint identity, const QString& templateName )
866  : KMCommand( parent, msg ),
867  mIdentity( identity ),
868  mTemplate( templateName )
869 {
870  fetchScope().fetchFullPayload( true );
871  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
872 }
873 
874 KMCommand::Result KMForwardCommand::createComposer(const Akonadi::Item& item)
875 {
876  KMime::Message::Ptr msg = MessageCore::Util::message( item );
877  if ( !msg )
878  return Failed;
879 #ifndef QT_NO_CURSOR
880  MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
881 #endif
882  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
883  factory.setIdentityManager( KMKernel::self()->identityManager() );
884  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
885  if ( !mTemplate.isEmpty() )
886  factory.setTemplate( mTemplate );
887  KMime::Message::Ptr fwdMsg = factory.createForward();
888 
889  uint id = msg->headerByType( "X-KMail-Identity" ) ? msg->headerByType("X-KMail-Identity")->asUnicodeString().trimmed().toUInt() : 0;
890  kDebug() << "mail" << msg->encodedContent();
891  bool lastEncrypt = false;
892  bool lastSign = false;
893  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
894 
895  if ( id == 0 )
896  id = mIdentity;
897  {
898  KMail::Composer * win = KMail::makeComposer( fwdMsg, lastSign, lastEncrypt, KMail::Composer::Forward, id,QString(), mTemplate );
899  win->show();
900  }
901  return OK;
902 }
903 
904 KMCommand::Result KMForwardCommand::execute()
905 {
906  QList<Akonadi::Item> msgList = retrievedMsgs();
907 
908  if (msgList.count() >= 2) {
909  // ask if they want a mime digest forward
910 
911  int answer = KMessageBox::questionYesNoCancel(
912  parentWidget(),
913  i18n("Do you want to forward the selected messages as "
914  "attachments in one message (as a MIME digest) or as "
915  "individual messages?"), QString(),
916  KGuiItem(i18n("Send As Digest")),
917  KGuiItem(i18n("Send Individually")) );
918 
919  if ( answer == KMessageBox::Yes ) {
920  Akonadi::Item firstItem( msgList.first() );
921  MessageFactory factory( KMime::Message::Ptr( new KMime::Message ), firstItem.id(), MailCommon::Util::updatedCollection(firstItem.parentCollection()) );
922  factory.setIdentityManager( KMKernel::self()->identityManager() );
923  factory.setFolderIdentity( MailCommon::Util::folderIdentity( firstItem ) );
924 
925  QPair< KMime::Message::Ptr, KMime::Content* > fwdMsg = factory.createForwardDigestMIME(msgList );
926  KMail::Composer * win = KMail::makeComposer( fwdMsg.first, false, false, KMail::Composer::Forward, mIdentity );
927  win->addAttach( fwdMsg.second );
928  win->show();
929  return OK;
930  } else if ( answer == KMessageBox::No ) {// NO MIME DIGEST, Multiple forward
931  QList<Akonadi::Item>::const_iterator it;
932  QList<Akonadi::Item>::const_iterator end( msgList.constEnd() );
933 
934  for ( it = msgList.constBegin(); it != end; ++it ) {
935  if ( createComposer( *it ) == Failed )
936  return Failed;
937  }
938  return OK;
939  } else {
940  // user cancelled
941  return OK;
942  }
943  }
944 
945  // forward a single message at most.
946  Akonadi::Item item = msgList.first();
947  if ( createComposer( item ) == Failed )
948  return Failed;
949  return OK;
950 }
951 
952 
953 KMForwardAttachedCommand::KMForwardAttachedCommand( QWidget *parent,
954  const QList<Akonadi::Item> &msgList, uint identity, KMail::Composer *win )
955  : KMCommand( parent, msgList ), mIdentity( identity ),
956  mWin( QPointer<KMail::Composer>( win ))
957 {
958  fetchScope().fetchFullPayload( true );
959  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
960 }
961 
962 KMForwardAttachedCommand::KMForwardAttachedCommand( QWidget *parent,
963  const Akonadi::Item & msg, uint identity, KMail::Composer *win )
964  : KMCommand( parent, msg ), mIdentity( identity ),
965  mWin( QPointer< KMail::Composer >( win ))
966 {
967  fetchScope().fetchFullPayload( true );
968  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
969 }
970 
971 KMCommand::Result KMForwardAttachedCommand::execute()
972 {
973  QList<Akonadi::Item> msgList = retrievedMsgs();
974  Akonadi::Item firstItem( msgList.first() );
975  MessageFactory factory( KMime::Message::Ptr( new KMime::Message ), firstItem.id(), MailCommon::Util::updatedCollection(firstItem.parentCollection()) );
976  factory.setIdentityManager( KMKernel::self()->identityManager() );
977  factory.setFolderIdentity( MailCommon::Util::folderIdentity( firstItem ) );
978 
979  QPair< KMime::Message::Ptr, QList< KMime::Content* > > fwdMsg = factory.createAttachedForward( msgList );
980  if ( !mWin ) {
981  mWin = KMail::makeComposer( fwdMsg.first, false, false, KMail::Composer::Forward, mIdentity );
982  }
983  foreach( KMime::Content* attach, fwdMsg.second ) {
984  mWin->addAttach( attach );
985  }
986  mWin->show();
987  return OK;
988 }
989 
990 KMRedirectCommand::KMRedirectCommand( QWidget *parent,
991  const QList<Akonadi::Item> &msgList )
992  : KMCommand( parent, msgList )
993 {
994  fetchScope().fetchFullPayload( true );
995  fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
996  fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
997 
998  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
999 }
1000 
1001 KMRedirectCommand::KMRedirectCommand( QWidget *parent,
1002  const Akonadi::Item &msg )
1003  : KMCommand( parent, msg )
1004 {
1005  fetchScope().fetchFullPayload( true );
1006  fetchScope().fetchAttribute<MailTransport::SentBehaviourAttribute>();
1007  fetchScope().fetchAttribute<MailTransport::TransportAttribute>();
1008 
1009  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1010 }
1011 
1012 KMCommand::Result KMRedirectCommand::execute()
1013 {
1014  const MailCommon::RedirectDialog::SendMode sendMode = MessageComposer::MessageComposerSettings::self()->sendImmediate()
1015  ? MailCommon::RedirectDialog::SendNow
1016  : MailCommon::RedirectDialog::SendLater;
1017 
1018  MessageViewer::AutoQPointer<MailCommon::RedirectDialog> dlg( new MailCommon::RedirectDialog( sendMode, parentWidget() ) );
1019  dlg->setObjectName( QLatin1String("redirect") );
1020  if ( dlg->exec() == QDialog::Rejected || !dlg ) {
1021  return Failed;
1022  }
1023  if ( !TransportManager::self()->showTransportCreationDialog( parentWidget(), TransportManager::IfNoTransportExists ) )
1024  return Failed;
1025 
1026  //TODO use sendlateragent here too.
1027  const MessageComposer::MessageSender::SendMethod method = (dlg->sendMode() == MailCommon::RedirectDialog::SendNow)
1028  ? MessageComposer::MessageSender::SendImmediate
1029  : MessageComposer::MessageSender::SendLater;
1030 
1031  const int identity = dlg->identity();
1032  int transportId = dlg->transportId();
1033  const QString to = dlg->to();
1034  const QString cc = dlg->cc();
1035  const QString bcc = dlg->bcc();
1036  foreach( const Akonadi::Item &item, retrievedMsgs() ) {
1037  const KMime::Message::Ptr msg = MessageCore::Util::message( item );
1038  if ( !msg )
1039  return Failed;
1040 
1041  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
1042  factory.setIdentityManager( KMKernel::self()->identityManager() );
1043  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
1044 
1045  if(transportId == -1) {
1046  const MailTransport::TransportAttribute *transportAttribute = item.attribute<MailTransport::TransportAttribute>();
1047  if ( transportAttribute ) {
1048  transportId = transportAttribute->transportId();
1049  const MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportById( transportId );
1050  if ( !transport ) {
1051  transportId = -1;
1052  }
1053  }
1054  }
1055 
1056  const MailTransport::SentBehaviourAttribute *sentAttribute = item.attribute<MailTransport::SentBehaviourAttribute>();
1057  QString fcc;
1058  if ( sentAttribute && ( sentAttribute->sentBehaviour() == MailTransport::SentBehaviourAttribute::MoveToCollection ) )
1059  fcc = QString::number( sentAttribute->moveToCollection().id() );
1060 
1061  const KMime::Message::Ptr newMsg = factory.createRedirect( to, cc, bcc, transportId, fcc, identity );
1062  if ( !newMsg )
1063  return Failed;
1064 
1065  MessageStatus status;
1066  status.setStatusFromFlags( item.flags() );
1067  if ( !status.isRead() )
1068  FilterAction::sendMDN( item, KMime::MDN::Dispatched );
1069 
1070 
1071  if ( !kmkernel->msgSender()->send( newMsg, method ) ) {
1072  kDebug() << "KMRedirectCommand: could not redirect message (sending failed)";
1073  return Failed; // error: couldn't send
1074  }
1075  }
1076 
1077  return OK;
1078 }
1079 
1080 
1081 KMPrintCommand::KMPrintCommand(QWidget *parent, const Akonadi::Item &msg,
1082  MessageViewer::HeaderStyle *headerStyle,
1083  MessageViewer::HeaderStrategy *headerStrategy,
1084  MessageViewer::Viewer::DisplayFormatMessage format, bool htmlLoadExtOverride,
1085  bool useFixedFont, const QString & encoding )
1086  : KMCommand( parent, msg ),
1087  mHeaderStyle( headerStyle ), mHeaderStrategy( headerStrategy ),
1088  mAttachmentStrategy( 0 ),
1089  mEncoding( encoding ),
1090  mFormat( format ),
1091  mHtmlLoadExtOverride( htmlLoadExtOverride ),
1092  mUseFixedFont( useFixedFont ),
1093  mPrintPreview(false)
1094 {
1095  fetchScope().fetchFullPayload( true );
1096  if ( MessageCore::GlobalSettings::useDefaultFonts() )
1097  mOverrideFont = KGlobalSettings::generalFont();
1098  else {
1099  mOverrideFont = MessageCore::GlobalSettings::self()->printFont();
1100  }
1101 }
1102 
1103 
1104 void KMPrintCommand::setOverrideFont( const QFont& font )
1105 {
1106  mOverrideFont = font;
1107 }
1108 
1109 void KMPrintCommand::setAttachmentStrategy( const MessageViewer::AttachmentStrategy *strategy )
1110 {
1111  mAttachmentStrategy = strategy;
1112 }
1113 
1114 void KMPrintCommand::setPrintPreview( bool preview )
1115 {
1116  mPrintPreview = preview;
1117 }
1118 
1119 KMCommand::Result KMPrintCommand::execute()
1120 {
1121  // the window will be deleted after printout is performed, in KMReaderWin::slotPrintMsg()
1122  KMReaderWin *printerWin = new KMReaderWin( 0, kmkernel->mainWin(), 0, 0 );
1123  printerWin->setPrinting( true );
1124  printerWin->readConfig();
1125  if ( mHeaderStyle != 0 && mHeaderStrategy != 0 )
1126  printerWin->setHeaderStyleAndStrategy( mHeaderStyle, mHeaderStrategy );
1127  printerWin->setDisplayFormatMessageOverwrite( mFormat );
1128  printerWin->setHtmlLoadExtOverride( mHtmlLoadExtOverride );
1129  printerWin->setUseFixedFont( mUseFixedFont );
1130  printerWin->setOverrideEncoding( mEncoding );
1131  printerWin->cssHelper()->setPrintFont( mOverrideFont );
1132  printerWin->setDecryptMessageOverwrite( true );
1133  if ( mAttachmentStrategy != 0 )
1134  printerWin->setAttachmentStrategy( mAttachmentStrategy );
1135  if(mPrintPreview)
1136  printerWin->viewer()->printPreviewMessage( retrievedMessage() );
1137  else
1138  printerWin->viewer()->printMessage(retrievedMessage());
1139  return OK;
1140 }
1141 
1142 
1143 KMSetStatusCommand::KMSetStatusCommand( const MessageStatus& status,
1144  const Akonadi::Item::List &items, bool invert )
1145  : KMCommand( 0, items ), mStatus( status ), mInvertMark( invert )
1146 {
1147  setDeletesItself(true);
1148 }
1149 
1150 KMCommand::Result KMSetStatusCommand::execute()
1151 {
1152  bool parentStatus = false;
1153  // Toggle actions on threads toggle the whole thread
1154  // depending on the state of the parent.
1155  if ( mInvertMark ) {
1156  const Akonadi::Item first = retrievedMsgs().first();
1157  MessageStatus pStatus;
1158  pStatus.setStatusFromFlags( first.flags() );
1159  if ( pStatus & mStatus )
1160  parentStatus = true;
1161  else
1162  parentStatus = false;
1163  }
1164 
1165  Akonadi::Item::List itemsToModify;
1166  foreach( const Akonadi::Item &it, retrievedMsgs() ) {
1167  if ( mInvertMark ) {
1168  //kDebug()<<" item ::"<<tmpItem;
1169  if ( it.isValid() ) {
1170  bool myStatus;
1171  MessageStatus itemStatus;
1172  itemStatus.setStatusFromFlags( it.flags() );
1173  if ( itemStatus & mStatus )
1174  myStatus = true;
1175  else
1176  myStatus = false;
1177  if ( myStatus != parentStatus )
1178  continue;
1179  }
1180  }
1181  Akonadi::Item item( it );
1182  const Akonadi::Item::Flag flag = *(mStatus.statusFlags().begin());
1183  if ( mInvertMark ) {
1184  if ( item.hasFlag( flag ) ) {
1185  item.clearFlag( flag );
1186  itemsToModify.push_back( item );
1187  } else {
1188  item.setFlag( flag );
1189  itemsToModify.push_back( item );
1190  }
1191  } else {
1192  if ( !item.hasFlag( flag ) ) {
1193  item.setFlag( flag );
1194  itemsToModify.push_back( item );
1195  }
1196  }
1197  }
1198 
1199  if ( itemsToModify.isEmpty() ) {
1200  slotModifyItemDone( 0 ); // pretend we did something
1201  } else {
1202  Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( itemsToModify, this );
1203  modifyJob->disableRevisionCheck();
1204  modifyJob->setIgnorePayload( true );
1205  connect( modifyJob, SIGNAL(result(KJob*)), this, SLOT(slotModifyItemDone(KJob*)) );
1206  }
1207  return OK;
1208 }
1209 
1210 void KMSetStatusCommand::slotModifyItemDone( KJob * job )
1211 {
1212  if ( job && job->error() ) {
1213  kWarning() << " Error trying to set item status:" << job->errorText();
1214  }
1215  deleteLater();
1216 }
1217 
1218 KMSetTagCommand::KMSetTagCommand( const Akonadi::Tag::List &tags, const QList<Akonadi::Item> &item,
1219  SetTagMode mode )
1220  : mTags( tags )
1221  , mItem( item )
1222  , mMode( mode )
1223 {
1224  setDeletesItself(true);
1225 }
1226 
1227 KMCommand::Result KMSetTagCommand::execute()
1228 {
1229  Q_FOREACH( const Akonadi::Tag &tag, mTags ) {
1230  if ( !tag.isValid() ) {
1231  Akonadi::TagCreateJob *createJob = new Akonadi::TagCreateJob(tag, this);
1232  connect( createJob, SIGNAL(result(KJob*)), this, SLOT(slotModifyItemDone(KJob*)) );
1233  } else {
1234  mCreatedTags << tag;
1235  }
1236  }
1237 
1238  if ( mCreatedTags.size() == mTags.size() ) {
1239  setTags();
1240  } else {
1241  deleteLater();
1242  }
1243 
1244  return OK;
1245 }
1246 
1247 void KMSetTagCommand::setTags()
1248 {
1249  Akonadi::Item::List itemsToModify;
1250  Q_FOREACH( const Akonadi::Item& i, mItem ) {
1251  Akonadi::Item item(i);
1252  if ( mMode == CleanExistingAndAddNew ){
1253  //WorkAround. ClearTags doesn't work.
1254  Q_FOREACH(const Akonadi::Tag &tag, item.tags()) {
1255  item.clearTag(tag);
1256  }
1257  //item.clearTags();
1258  }
1259 
1260  if (mMode == KMSetTagCommand::Toggle) {
1261  Q_FOREACH( const Akonadi::Tag &tag, mCreatedTags ) {
1262  if ( item.hasTag(tag) ) {
1263  item.clearTag(tag);
1264  } else {
1265  item.setTag(tag);
1266  }
1267  }
1268  } else {
1269  if (!mCreatedTags.isEmpty())
1270  item.setTags(mCreatedTags);
1271  }
1272  itemsToModify << item;
1273  }
1274  Akonadi::ItemModifyJob *modifyJob = new Akonadi::ItemModifyJob( itemsToModify, this );
1275  modifyJob->disableRevisionCheck();
1276  modifyJob->setIgnorePayload( true );
1277  connect( modifyJob, SIGNAL(result(KJob*)), this, SLOT(slotModifyItemDone(KJob*)) );
1278 
1279  if(!mCreatedTags.isEmpty()) {
1280  KConfigGroup tag( KMKernel::self()->config(), "MessageListView" );
1281  const QString oldTagList = tag.readEntry("TagSelected");
1282  QStringList lst = oldTagList.split(QLatin1String(","));
1283  Q_FOREACH( const Akonadi::Tag &tag, mCreatedTags ) {
1284  const QString url = tag.url().url();
1285  if(!lst.contains(url)) {
1286  lst.append(url);
1287  }
1288  }
1289  tag.writeEntry("TagSelected",lst);
1290  KMKernel::self()->updatePaneTagComboBox();
1291  }
1292 }
1293 
1294 void KMSetTagCommand::slotModifyItemDone( KJob * job )
1295 {
1296  if ( job && job->error() ) {
1297  kWarning() << " Error trying to set item status:" << job->errorText();
1298  }
1299  deleteLater();
1300 }
1301 
1302 KMFilterActionCommand::KMFilterActionCommand( QWidget *parent,
1303  const QVector<qlonglong> &msgListId,
1304  const QString &filterId)
1305  : KMCommand( parent ), mMsgListId(msgListId), mFilterId( filterId )
1306 {
1307 }
1308 
1309 KMCommand::Result KMFilterActionCommand::execute()
1310 {
1311 #ifndef QT_NO_CURSOR
1312  MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
1313 #endif
1314  int msgCount = 0;
1315  const int msgCountToFilter = mMsgListId.count();
1316  ProgressItem* progressItem =
1317  ProgressManager::createProgressItem (
1318  QLatin1String("filter")+ProgressManager::getUniqueID(),
1319  i18n( "Filtering messages" ), QString(),true, KPIM::ProgressItem::Unknown );
1320  progressItem->setTotalItems( msgCountToFilter );
1321 
1322  foreach ( const qlonglong &id, mMsgListId ) {
1323  int diff = msgCountToFilter - ++msgCount;
1324  if ( diff < 10 || !( msgCount % 10 ) || msgCount <= 10 ) {
1325  progressItem->updateProgress();
1326  const QString statusMsg = i18n( "Filtering message %1 of %2",
1327  msgCount, msgCountToFilter );
1328  KPIM::BroadcastStatus::instance()->setStatusMsg( statusMsg );
1329  qApp->processEvents( QEventLoop::ExcludeUserInputEvents, 50 );
1330  }
1331 
1332 
1333  MailCommon::FilterManager::instance()->filter( Akonadi::Item(id), mFilterId, QString() );
1334  progressItem->incCompletedItems();
1335  }
1336 
1337  progressItem->setComplete();
1338  progressItem = 0;
1339  return OK;
1340 }
1341 
1342 
1343 KMMetaFilterActionCommand::KMMetaFilterActionCommand( const QString &filterId,
1344  KMMainWidget *main )
1345  : QObject( main ),
1346  mFilterId( filterId ), mMainWidget( main )
1347 {
1348 }
1349 
1350 void KMMetaFilterActionCommand::start()
1351 {
1352  KMCommand *filterCommand = new KMFilterActionCommand(
1353  mMainWidget, mMainWidget->messageListPane()->selectionAsMessageItemListId() , mFilterId);
1354  filterCommand->start();
1355 }
1356 
1357 
1358 KMMailingListFilterCommand::KMMailingListFilterCommand( QWidget *parent,
1359  const Akonadi::Item &msg )
1360  : KMCommand( parent, msg )
1361 {
1362 }
1363 
1364 KMCommand::Result KMMailingListFilterCommand::execute()
1365 {
1366  QByteArray name;
1367  QString value;
1368  Akonadi::Item item = retrievedMessage();
1369  KMime::Message::Ptr msg = MessageCore::Util::message( item );
1370  if ( !msg )
1371  return Failed;
1372  if ( !MailingList::name( msg, name, value ).isEmpty() ) {
1373  FilterIf->openFilterDialog( false );
1374  FilterIf->createFilter( name, value );
1375  return OK;
1376  } else {
1377  return Failed;
1378  }
1379 }
1380 
1381 KMCopyCommand::KMCopyCommand( const Akonadi::Collection& destFolder,
1382  const QList<Akonadi::Item> &msgList)
1383  :KMCommand( 0, msgList ), mDestFolder( destFolder )
1384 {
1385 }
1386 
1387 KMCopyCommand::KMCopyCommand( const Akonadi::Collection& destFolder, const Akonadi::Item& msg)
1388  :KMCommand( 0,msg ), mDestFolder( destFolder )
1389 {
1390 }
1391 
1392 KMCommand::Result KMCopyCommand::execute()
1393 {
1394  setDeletesItself( true );
1395 
1396  QList<Akonadi::Item> listItem = retrievedMsgs();
1397  Akonadi::ItemCopyJob *job = new Akonadi::ItemCopyJob( listItem, Akonadi::Collection(mDestFolder.id()),this );
1398  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotCopyResult(KJob*)) );
1399 
1400  return OK;
1401 }
1402 
1403 void KMCopyCommand::slotCopyResult( KJob * job )
1404 {
1405  if ( job->error() ) {
1406  // handle errors
1407  showJobError(job);
1408  setResult( Failed );
1409  }
1410  deleteLater();
1411 }
1412 
1413 KMMoveCommand::KMMoveCommand( const Akonadi::Collection& destFolder,
1414  const QList<Akonadi::Item> &msgList,
1415  MessageList::Core::MessageItemSetReference ref)
1416  : KMCommand( 0, msgList ), mDestFolder( destFolder ), mProgressItem( 0 ), mRef( ref )
1417 {
1418  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1419 }
1420 
1421 KMMoveCommand::KMMoveCommand( const Akonadi::Collection& destFolder,
1422  const Akonadi::Item& msg ,
1423  MessageList::Core::MessageItemSetReference ref)
1424  : KMCommand( 0, msg ), mDestFolder( destFolder ), mProgressItem( 0 ), mRef( ref )
1425 {
1426  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1427 }
1428 
1429 void KMMoveCommand::slotMoveResult( KJob * job )
1430 {
1431  if ( job->error() ) {
1432  // handle errors
1433  showJobError(job);
1434  completeMove( Failed );
1435  }
1436  else
1437  completeMove( OK );
1438 }
1439 
1440 KMCommand::Result KMMoveCommand::execute()
1441 {
1442 #ifndef QT_NO_CURSOR
1443  MessageViewer::KCursorSaver busy( MessageViewer::KBusyPtr::busy() );
1444 #endif
1445  setEmitsCompletedItself( true );
1446  setDeletesItself( true );
1447  if ( mDestFolder.isValid() ) {
1448  Akonadi::ItemMoveJob *job = new Akonadi::ItemMoveJob( retrievedMsgs(), mDestFolder, this );
1449  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotMoveResult(KJob*)) );
1450 
1451  // group by source folder for undo
1452  Akonadi::Item::List items = retrievedMsgs();
1453  std::sort( items.begin(), items.end(), boost::bind( &Akonadi::Item::storageCollectionId, _1 ) <
1454  boost::bind( &Akonadi::Item::storageCollectionId, _2 ) );
1455  Akonadi::Collection parent;
1456  int undoId = -1;
1457  foreach ( const Akonadi::Item &item, items ) {
1458  if ( item.storageCollectionId() <= 0 )
1459  continue;
1460  if ( parent.id() != item.storageCollectionId() ) {
1461  parent = Akonadi::Collection( item.storageCollectionId() );
1462  undoId = kmkernel->undoStack()->newUndoAction( parent, mDestFolder );
1463  }
1464  kmkernel->undoStack()->addMsgToAction( undoId, item );
1465  }
1466  } else {
1467  const QList<Akonadi::Item> retrievedList = retrievedMsgs();
1468  if ( !retrievedList.isEmpty() ) {
1469  Akonadi::ItemDeleteJob *job = new Akonadi::ItemDeleteJob( retrievedList, this );
1470  connect( job, SIGNAL(result(KJob*)), this, SLOT(slotMoveResult(KJob*)) );
1471  }
1472  }
1473 
1474  // TODO set SSL state according to source and destfolder connection?
1475  Q_ASSERT( !mProgressItem );
1476  mProgressItem =
1477  ProgressManager::createProgressItem (QLatin1String("move")+ProgressManager::getUniqueID(),
1478  mDestFolder.isValid() ? i18n( "Moving messages" ) : i18n( "Deleting messages" ), QString(), true, KPIM::ProgressItem::Unknown );
1479  mProgressItem->setUsesBusyIndicator( true );
1480  connect( mProgressItem, SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
1481  this, SLOT(slotMoveCanceled()) );
1482  return OK;
1483 }
1484 
1485 
1486 
1487 void KMMoveCommand::completeMove( Result result )
1488 {
1489  if ( mProgressItem ) {
1490  mProgressItem->setComplete();
1491  mProgressItem = 0;
1492  }
1493  setResult( result );
1494  emit moveDone(this);
1495  emit completed( this );
1496  deleteLater();
1497 }
1498 
1499 void KMMoveCommand::slotMoveCanceled()
1500 {
1501  completeMove( Canceled );
1502 }
1503 
1504 // srcFolder doesn't make much sense for searchFolders
1505 KMTrashMsgCommand::KMTrashMsgCommand( const Akonadi::Collection& srcFolder,
1506  const QList<Akonadi::Item> &msgList,MessageList::Core::MessageItemSetReference ref )
1507  :KMMoveCommand( findTrashFolder( srcFolder ), msgList, ref)
1508 {
1509 }
1510 
1511 KMTrashMsgCommand::KMTrashMsgCommand( const Akonadi::Collection& srcFolder, const Akonadi::Item & msg,MessageList::Core::MessageItemSetReference ref )
1512  :KMMoveCommand( findTrashFolder( srcFolder ), msg, ref)
1513 {
1514 }
1515 
1516 
1517 Akonadi::Collection KMTrashMsgCommand::findTrashFolder( const Akonadi::Collection& folder )
1518 {
1519  Akonadi::Collection col = CommonKernel->trashCollectionFromResource( folder );
1520  if ( !col.isValid() ) {
1521  col = CommonKernel->trashCollectionFolder();
1522  }
1523  if ( folder != col )
1524  return col;
1525  return Akonadi::Collection();
1526 }
1527 
1528 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand(QWidget *parent, const Akonadi::Item& msg , MessageViewer::Viewer *viewer)
1529  : KMCommand( parent, msg ),
1530  mViewer(viewer)
1531 {
1532  fetchScope().fetchFullPayload( true );
1533 }
1534 
1535 KMSaveAttachmentsCommand::KMSaveAttachmentsCommand( QWidget *parent, const QList<Akonadi::Item>& msgs )
1536  : KMCommand( parent, msgs ),
1537  mViewer(0)
1538 {
1539  fetchScope().fetchFullPayload( true );
1540 }
1541 
1542 KMCommand::Result KMSaveAttachmentsCommand::execute()
1543 {
1544  QList<KMime::Content*> contentsToSave;
1545  foreach( const Akonadi::Item &item, retrievedMsgs() ) {
1546  if ( item.hasPayload<KMime::Message::Ptr>() ) {
1547  contentsToSave += MessageViewer::Util::extractAttachments( item.payload<KMime::Message::Ptr>().get() );
1548  } else {
1549  kWarning() << "Retrieved item has no payload? Ignoring for saving the attachments";
1550  }
1551  }
1552  KUrl currentUrl;
1553  if ( MessageViewer::Util::saveAttachments( contentsToSave, parentWidget(), currentUrl ) ) {
1554  if (mViewer) {
1555  mViewer->showOpenAttachmentFolderWidget(currentUrl);
1556  }
1557  return OK;
1558  }
1559  return Failed;
1560 }
1561 
1562 KMResendMessageCommand::KMResendMessageCommand( QWidget *parent,
1563  const Akonadi::Item &msg )
1564  :KMCommand( parent, msg )
1565 {
1566  fetchScope().fetchFullPayload( true );
1567  fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
1568 }
1569 
1570 KMCommand::Result KMResendMessageCommand::execute()
1571 {
1572  Akonadi::Item item = retrievedMessage();
1573  KMime::Message::Ptr msg = MessageCore::Util::message( item );
1574  if ( !msg )
1575  return Failed;
1576 
1577  MessageFactory factory( msg, item.id(), MailCommon::Util::updatedCollection(item.parentCollection()) );
1578  factory.setIdentityManager( KMKernel::self()->identityManager() );
1579  factory.setFolderIdentity( MailCommon::Util::folderIdentity( item ) );
1580  KMime::Message::Ptr newMsg = factory.createResend();
1581  newMsg->contentType()->setCharset( MessageViewer::NodeHelper::charset( msg.get() ) );
1582 
1583  KMail::Composer * win = KMail::makeComposer();
1584  if(msg->headerByType( "Reply-To" )) {
1585  const QString replyTo = msg->headerByType( "Reply-To" )->asUnicodeString();
1586  win->setCurrentReplyTo(replyTo);
1587  }
1588  bool lastEncrypt = false;
1589  bool lastSign = false;
1590  KMail::Util::lastEncryptAndSignState(lastEncrypt, lastSign, msg);
1591  win->setMessage( newMsg, lastSign, lastEncrypt, false, true );
1592 
1593  win->show();
1594 
1595  return OK;
1596 }
1597 
1598 
1599 KMShareImageCommand::KMShareImageCommand(const KUrl &url, QWidget *parent)
1600  : KMCommand( parent ),
1601  mUrl(url)
1602 {
1603 }
1604 
1605 KMCommand::Result KMShareImageCommand::execute()
1606 {
1607  KMime::Message::Ptr msg( new KMime::Message );
1608  uint id = 0;
1609 
1610  MessageHelper::initHeader( msg, KMKernel::self()->identityManager(),id );
1611  msg->contentType()->setCharset("utf-8");
1612 
1613  KMail::Composer * win = KMail::makeComposer(msg, false, false,KMail::Composer::New, id);
1614  win->setFocusToSubject();
1615  win->addAttachment(mUrl, i18n("Image"));
1616  win->show();
1617  return OK;
1618 }
1619 
1620 KMFetchMessageCommand::KMFetchMessageCommand( QWidget *parent, const Akonadi::Item &item )
1621  : KMCommand( parent, item )
1622 {
1623  // Workaround KMCommand::transferSelectedMsgs() expecting non-empty fetchscope
1624  fetchScope().fetchFullPayload(true);
1625 }
1626 
1627 Akonadi::ItemFetchJob *KMFetchMessageCommand::createFetchJob( const Akonadi::Item::List &items )
1628 {
1629  Q_ASSERT( items.size() == 1 );
1630  Akonadi::ItemFetchJob *fetch = MessageViewer::Viewer::createFetchJob( items.first() );
1631  fetchScope() = fetch->fetchScope();
1632  return fetch;
1633 }
1634 
1635 KMCommand::Result KMFetchMessageCommand::execute()
1636 {
1637  Akonadi::Item item = retrievedMessage();
1638  if ( !item.isValid() || !item.hasPayload<KMime::Message::Ptr>() ) {
1639  return Failed;
1640  }
1641 
1642  mItem = item;
1643  return OK;
1644 }
1645 
1646 Akonadi::Item KMFetchMessageCommand::item() const
1647 {
1648  return mItem;
1649 }
KMCommand::parentWidget
QWidget * parentWidget() const
Definition: kmcommands.cpp:226
KMCommand::messagesTransfered
void messagesTransfered(KMCommand::Result result)
KMail::Composer::setFocusToSubject
virtual void setFocusToSubject()=0
Sets the focus to the subject line edit.
QList::clear
void clear()
KMMoveCommand::moveDone
void moveDone(KMMoveCommand *)
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KMForwardCommand::KMForwardCommand
KMForwardCommand(QWidget *parent, const QList< Akonadi::Item > &msgList, uint identity=0, const QString &templateName=QString())
Definition: kmcommands.cpp:854
globalsettings.h
QWidget
KMMailtoForwardCommand::KMMailtoForwardCommand
KMMailtoForwardCommand(QWidget *parent, const KUrl &url, const Akonadi::Item &msg)
Definition: kmcommands.cpp:450
QString::append
QString & append(QChar ch)
KMCommand::deletesItself
bool deletesItself() const
Definition: kmcommands.h:94
KMReaderMainWin::showMessage
void showMessage(const QString &encoding, const Akonadi::Item &msg, const Akonadi::Collection &parentCollection=Akonadi::Collection())
take ownership of and show
Definition: kmreadermainwin.cpp:136
kmmainwidget.h
KMSetTagCommand::slotModifyItemDone
void slotModifyItemDone(KJob *job)
Definition: kmcommands.cpp:1294
KMCommand::retrievedMessage
Akonadi::Item retrievedMessage() const
Definition: kmcommands.cpp:219
KMOpenMsgCommand::KMOpenMsgCommand
KMOpenMsgCommand(QWidget *parent, const KUrl &url=KUrl(), const QString &encoding=QString(), KMMainWidget *main=0)
Definition: kmcommands.cpp:690
QByteArray
KMReaderWin
This class implements a "reader window", that is a window used for reading or viewing messages...
Definition: kmreaderwin.h:49
KPIM::BroadcastStatus::instance
static BroadcastStatus * instance()
KMReaderWin::viewer
MessageViewer::Viewer * viewer()
Definition: kmreaderwin.h:133
KMCommand::KMCommand
KMCommand(QWidget *parent=0)
Definition: kmcommands.cpp:178
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
KMUseTemplateCommand::KMUseTemplateCommand
KMUseTemplateCommand(QWidget *parent, const Akonadi::Item &msg)
Definition: kmcommands.cpp:638
QFont
KMail::Util::putRepliesInSameFolder
Akonadi::Item::Id putRepliesInSameFolder(const Akonadi::Item &item)
Whether or not the mail item has the keep-reply-in-folder attribute set.
Definition: util.cpp:76
KPIM::ProgressItem::Unknown
QPointer
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
QByteArray::isEmpty
bool isEmpty() const
KMMoveCommand::slotMoveCanceled
void slotMoveCanceled()
Definition: kmcommands.cpp:1499
KMMainWidget::messageListPane
CollectionPane * messageListPane() const
Access to the header list pane.
Definition: kmmainwidget.h:124
KMMoveCommand
Definition: kmcommands.h:523
KMPrintCommand::setOverrideFont
void setOverrideFont(const QFont &)
Definition: kmcommands.cpp:1104
KPIM::ProgressItem::updateProgress
void updateProgress()
QWeakPointer::data
T * data() const
KMail::Composer::setMessage
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.
KMFilterActionCommand
Definition: kmcommands.h:461
KMCommand::setResult
void setResult(Result result)
Use this to set the result of the command.
Definition: kmcommands.h:116
KMPrintCommand::KMPrintCommand
KMPrintCommand(QWidget *parent, const Akonadi::Item &msg, MessageViewer::HeaderStyle *headerStyle=0, MessageViewer::HeaderStrategy *headerStrategy=0, MessageViewer::Viewer::DisplayFormatMessage format=MessageViewer::Viewer::UseGlobalSetting, bool htmlLoadExtOverride=false, bool useFixedFont=false, const QString &encoding=QString())
Definition: kmcommands.cpp:1081
KMMetaFilterActionCommand::start
void start()
Definition: kmcommands.cpp:1350
undostack.h
KMReaderWin::setHeaderStyleAndStrategy
void setHeaderStyleAndStrategy(MessageViewer::HeaderStyle *style, MessageViewer::HeaderStrategy *strategy)
Set the header style and strategy.
Definition: kmreaderwin.cpp:283
KPIM::ProgressItem::incCompletedItems
void incCompletedItems(unsigned int v=1)
KMFilterActionCommand::KMFilterActionCommand
KMFilterActionCommand(QWidget *parent, const QVector< qlonglong > &msgListId, const QString &filterId)
Definition: kmcommands.cpp:1302
KMMoveCommand::slotMoveResult
void slotMoveResult(KJob *job)
Definition: kmcommands.cpp:1429
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
KMail::Composer::Forward
Definition: composer.h:46
KMail::Composer
Definition: composer.h:39
KMKernel::self
static KMKernel * self()
normal control stuff
Definition: kmkernel.cpp:1471
KMCommand::result
Result result() const
Returns the result of the command.
Definition: kmcommands.cpp:206
KMail::Util::mailingListsFromMessage
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...
Definition: util.cpp:61
KMReaderWin::setOverrideEncoding
void setOverrideEncoding(const QString &encoding)
Set the override character encoding.
Definition: kmreaderwin.cpp:288
KPIM::BroadcastStatus::setStatusMsg
void setStatusMsg(const QString &message)
KMail::Composer::ReplyToAll
Definition: composer.h:46
KMMetaFilterActionCommand::KMMetaFilterActionCommand
KMMetaFilterActionCommand(const QString &filterId, KMMainWidget *main)
Definition: kmcommands.cpp:1343
KMEditItemCommand::~KMEditItemCommand
~KMEditItemCommand()
Definition: kmcommands.cpp:569
KMail::Composer::setFcc
virtual void setFcc(const QString &idString)=0
KMCommand::createFetchJob
virtual Akonadi::ItemFetchJob * createFetchJob(const Akonadi::Item::List &items)
Definition: kmcommands.cpp:277
KMSetTagCommand::Toggle
Definition: kmcommands.h:441
KMReaderWin::setPrinting
virtual void setPrinting(bool enable)
Definition: kmreaderwin.cpp:676
KMReaderWin::cssHelper
MessageViewer::CSSHelper * cssHelper() const
Definition: kmreaderwin.cpp:589
KMKernel::updatePaneTagComboBox
void updatePaneTagComboBox()
Definition: kmkernel.cpp:1993
KMail::Composer::addAttachment
virtual void addAttachment(const KUrl &url, const QString &comment)=0
QObject::name
const char * name() const
KMMailtoReplyCommand::KMMailtoReplyCommand
KMMailtoReplyCommand(QWidget *parent, const KUrl &url, const Akonadi::Item &msg, const QString &selection)
Definition: kmcommands.cpp:415
KMMoveCommand::KMMoveCommand
KMMoveCommand(const Akonadi::Collection &destFolder, const QList< Akonadi::Item > &msgList, MessageList::Core::MessageItemSetReference ref)
Definition: kmcommands.cpp:1413
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QList::empty
bool empty() const
KMail::Composer::addAttach
virtual void addAttach(KMime::Content *msgPart)=0
Add an attachment to the list.
KMCommand
Small helper structure which encapsulates the KMMessage created when creating a reply, and.
Definition: kmcommands.h:48
KMail::Composer::setFolder
virtual void setFolder(const Akonadi::Collection &)=0
If this folder is set, the original message is inserted back after canceling.
KMReaderWin::setDecryptMessageOverwrite
void setDecryptMessageOverwrite(bool overwrite=true)
Enforce message decryption.
Definition: kmreaderwin.cpp:598
QSharedPointer
Definition: collectionmailinglistpage.h:34
KPIM::ProgressManager
secondarywindow.h
KMCommand::setDeletesItself
void setDeletesItself(bool deletesItself)
Specify whether the subclass takes care of the deletion of the object.
Definition: kmcommands.h:100
KMail::SecondaryWindow
Window class for secondary KMail window like the composer window and the separate message window...
Definition: secondarywindow.h:44
KMReaderWin::setDisplayFormatMessageOverwrite
void setDisplayFormatMessageOverwrite(MessageViewer::Viewer::DisplayFormatMessage format)
Definition: kmreaderwin.cpp:466
replyContext
static KMail::Composer::TemplateContext replyContext(MessageFactory::MessageReply reply)
Small helper function to get the composer context from a reply.
Definition: kmcommands.cpp:157
KMReplyCommand::KMReplyCommand
KMReplyCommand(QWidget *parent, const Akonadi::Item &msg, MessageComposer::ReplyStrategy replyStrategy, const QString &selection=QString(), bool noquote=false, const QString &templateName=QString())
Definition: kmcommands.cpp:803
KMCommand::Canceled
Definition: kmcommands.h:53
QObject
KMShareImageCommand::KMShareImageCommand
KMShareImageCommand(const KUrl &url, QWidget *parent)
Definition: kmcommands.cpp:1599
KMSetStatusCommand::slotModifyItemDone
void slotModifyItemDone(KJob *job)
Definition: kmcommands.cpp:1210
KPIM::ProgressItem::setComplete
void setComplete()
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
progressmanager.h
collectionpane.h
KMCommand::start
void start()
Definition: kmcommands.cpp:233
KMReaderWin::setAttachmentStrategy
void setAttachmentStrategy(const MessageViewer::AttachmentStrategy *strategy)
Definition: kmreaderwin.cpp:279
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
KMCommand::setEmitsCompletedItself
void setEmitsCompletedItself(bool emitsCompletedItself)
Specify whether the subclass takes care of emitting the completed() signal.
Definition: kmcommands.h:110
showJobError
static void showJobError(KJob *job)
Helper to sanely show an error message for a job.
Definition: kmcommands.cpp:166
to
QString to() const
KMReaderWin::setHtmlLoadExtOverride
void setHtmlLoadExtOverride(bool override)
Definition: kmreaderwin.cpp:473
KMTrashMsgCommand::KMTrashMsgCommand
KMTrashMsgCommand(const Akonadi::Collection &srcFolder, const QList< Akonadi::Item > &msgList, MessageList::Core::MessageItemSetReference ref)
Definition: kmcommands.cpp:1505
KMUrlSaveCommand::KMUrlSaveCommand
KMUrlSaveCommand(const KUrl &url, QWidget *parent)
Definition: kmcommands.cpp:499
KMEditMessageCommand::KMEditMessageCommand
KMEditMessageCommand(QWidget *parent, const KMime::Message::Ptr &msg)
Definition: kmcommands.cpp:539
KMCommand::retrievedMsgs
const QList< Akonadi::Item > retrievedMsgs() const
Definition: kmcommands.cpp:214
KMail::Composer::setModified
virtual void setModified(bool modified)=0
KMMainWidget
Definition: kmmainwidget.h:91
KMSetTagCommand::KMSetTagCommand
KMSetTagCommand(const Akonadi::Tag::List &tags, const QList< Akonadi::Item > &item, SetTagMode mode=AddIfNotExisting)
Definition: kmcommands.cpp:1218
KMRedirectCommand::KMRedirectCommand
KMRedirectCommand(QWidget *parent, const Akonadi::Item &msg)
Definition: kmcommands.cpp:1001
QObject::deleteLater
void deleteLater()
QList::first
T & first()
QString
QList< Akonadi::Item >
KMail::Composer::setCurrentReplyTo
virtual void setCurrentReplyTo(const QString &replyTo)=0
QWeakPointer::clear
void clear()
util.h
kmkernel
#define kmkernel
Definition: kmkernel.h:24
QStringList
KMCopyCommand::slotCopyResult
void slotCopyResult(KJob *job)
Definition: kmcommands.cpp:1403
QPair
KMCommand::OK
Definition: kmcommands.h:53
KMCommand::completed
void completed(KMCommand *command)
Emitted when the command has completed.
QLatin1Char
KMPrintCommand::setAttachmentStrategy
void setAttachmentStrategy(const MessageViewer::AttachmentStrategy *strategy)
Definition: kmcommands.cpp:1109
KMail::Composer::Reply
Definition: composer.h:46
KMResendMessageCommand::KMResendMessageCommand
KMResendMessageCommand(QWidget *parent, const Akonadi::Item &msg=Akonadi::Item())
Definition: kmcommands.cpp:1562
KMSetTagCommand::CleanExistingAndAddNew
Definition: kmcommands.h:441
KMSaveAttachmentsCommand::KMSaveAttachmentsCommand
KMSaveAttachmentsCommand(QWidget *parent, const Akonadi::Item &msg, MessageViewer::Viewer *viewer)
Use this to save all attachments of the given message.
Definition: kmcommands.cpp:1528
KMForwardAttachedCommand::KMForwardAttachedCommand
KMForwardAttachedCommand(QWidget *parent, const QList< Akonadi::Item > &msgList, uint identity=0, KMail::Composer *win=0)
Definition: kmcommands.cpp:953
KMAddBookmarksCommand::KMAddBookmarksCommand
KMAddBookmarksCommand(const KUrl &url, QWidget *parent)
Definition: kmcommands.cpp:481
KPIM::ProgressItem::setUsesBusyIndicator
void setUsesBusyIndicator(bool useBusyIndicator)
KMSetStatusCommand::KMSetStatusCommand
KMSetStatusCommand(const MessageStatus &status, const Akonadi::Item::List &items, bool invert=false)
Definition: kmcommands.cpp:1143
KMFetchMessageCommand::KMFetchMessageCommand
KMFetchMessageCommand(QWidget *parent, const Akonadi::Item &item)
Definition: kmcommands.cpp:1620
KMCommand::emitsCompletedItself
bool emitsCompletedItself() const
Definition: kmcommands.h:103
KMMailtoComposeCommand::KMMailtoComposeCommand
KMMailtoComposeCommand(const KUrl &url, const Akonadi::Item &msg=Akonadi::Item())
Definition: kmcommands.cpp:386
QString::mid
QString mid(int position, int n) const
QVector< qlonglong >
KMPrintCommand::setPrintPreview
void setPrintPreview(bool preview)
Definition: kmcommands.cpp:1114
KMail::Composer::TemplateContext
TemplateContext
Definition: composer.h:46
QList::takeFirst
T takeFirst()
QLatin1String
KMCommand::Undefined
Definition: kmcommands.h:53
KMail::Composer::setCurrentTransport
virtual void setCurrentTransport(int transportId)=0
KMCommand::fetchScope
Akonadi::ItemFetchScope & fetchScope()
Allows to configure how much data should be retrieved of the messages.
Definition: kmcommands.h:85
composer.h
KPIM::ProgressItem
KMReaderMainWin
Definition: kmreadermainwin.h:34
QVector::count
int count(const T &value) const
KMFetchMessageCommand::item
Akonadi::Item item() const
Definition: kmcommands.cpp:1646
QString::length
int length() const
KMCommand::Failed
Definition: kmcommands.h:53
QByteArray::data
char * data()
KMail::Util::lastEncryptAndSignState
void lastEncryptAndSignState(bool &lastEncrypt, bool &lastSign, const KMime::Message::Ptr &msg)
Definition: util.cpp:185
KMCopyCommand::KMCopyCommand
KMCopyCommand(const Akonadi::Collection &destFolder, const QList< Akonadi::Item > &msgList)
Definition: kmcommands.cpp:1381
KMail::Composer::setFocusToEditor
virtual void setFocusToEditor()=0
Sets the focus to the edit-widget and the cursor below the "On ... you wrote" line when hasMessage is...
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KPIM::ProgressItem::setTotalItems
void setTotalItems(unsigned int v)
KMCommand::~KMCommand
virtual ~KMCommand()
Definition: kmcommands.cpp:202
KMMainWidget::addRecentFile
void addRecentFile(const KUrl &mUrl)
Definition: kmmainwidget.cpp:4401
KMail::Composer::New
Definition: composer.h:46
kmreadermainwin.h
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
kmcommands.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
main
int main(int argc, char *argv[])
Definition: main.cpp:97
QObject::parent
QObject * parent() const
KMSetTagCommand::SetTagMode
SetTagMode
Definition: kmcommands.h:441
broadcaststatus.h
KMReaderWin::setUseFixedFont
void setUseFixedFont(bool useFixedFont)
Definition: kmreaderwin.cpp:257
KMCommand::Result
Result
Definition: kmcommands.h:53
KJob
QList::begin
iterator begin()
KMSaveMsgCommand::KMSaveMsgCommand
KMSaveMsgCommand(QWidget *parent, const QList< Akonadi::Item > &msgList)
Definition: kmcommands.cpp:672
KMCommand::mRetrievedMsgs
QList< Akonadi::Item > mRetrievedMsgs
Definition: kmcommands.h:137
KMEditItemCommand::KMEditItemCommand
KMEditItemCommand(QWidget *parent, const Akonadi::Item &msg, bool deleteFromSource=true)
Definition: kmcommands.cpp:559
KMMailingListFilterCommand::KMMailingListFilterCommand
KMMailingListFilterCommand(QWidget *parent, const Akonadi::Item &msg)
Definition: kmcommands.cpp:1358
KMReaderWin::readConfig
void readConfig()
Read settings from app's config file.
Definition: kmreaderwin.cpp:274
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:33 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmail

Skip menu "kmail"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal