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

kmail

  • sources
  • kde-4.12
  • kdepim
  • kmail
kmkernel.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-file-style: "gnu" -*- */
2 
3 #include "kmkernel.h"
4 
5 #include "settings/globalsettings.h"
6 #include "misc/broadcaststatus.h"
7 using KPIM::BroadcastStatus;
8 #include "kmstartup.h"
9 #include "kmmainwin.h"
10 #include "editor/composer.h"
11 #include "kmreadermainwin.h"
12 #include "undostack.h"
13 #include <kpimutils/kfileio.h>
14 #include "kmreaderwin.h"
15 #include "kmmainwidget.h"
16 #include "addressline/recentaddresses.h"
17 using KPIM::RecentAddresses;
18 #include "configuredialog/configuredialog.h"
19 #include "kmcommands.h"
20 #include "kmsystemtray.h"
21 #include "utils/stringutil.h"
22 #include "util/mailutil.h"
23 #include "mailcommon/pop3settings.h"
24 #include "mailcommon/folder/foldertreeview.h"
25 #include "mailcommon/filter/kmfilterdialog.h"
26 #include "mailcommon/mailcommonsettings_base.h"
27 #include "pimcommon/util/pimutil.h"
28 
29 // kdepim includes
30 #include "kdepim-version.h"
31 
32 // kdepimlibs includes
33 #include <kpimidentities/identity.h>
34 #include <kpimidentities/identitymanager.h>
35 #include <mailtransport/transport.h>
36 #include <mailtransport/transportmanager.h>
37 #include <mailtransport/dispatcherinterface.h>
38 #include <akonadi/servermanager.h>
39 
40 #include <kde_file.h>
41 #include <kwindowsystem.h>
42 #include "mailserviceimpl.h"
43 using KMail::MailServiceImpl;
44 #include "job/jobscheduler.h"
45 
46 #include "messagecore/settings/globalsettings.h"
47 #include "messagelist/core/settings.h"
48 #include "messagelist/messagelistutil.h"
49 #include "messageviewer/settings/globalsettings.h"
50 #include "messagecomposer/sender/akonadisender.h"
51 #include "settings/messagecomposersettings.h"
52 #include "messagecomposer/helper/messagehelper.h"
53 #include "messagecomposer/settings/messagecomposersettings.h"
54 #include "messagecomposer/autocorrection/composerautocorrection.h"
55 
56 #include "templateparser/templateparser.h"
57 #include "templateparser/globalsettings_base.h"
58 #include "templateparser/templatesutil.h"
59 
60 #include "foldercollection.h"
61 #include "editor/codecmanager.h"
62 
63 
64 #include <kmessagebox.h>
65 #include <knotification.h>
66 #include <progresswidget/progressmanager.h>
67 #include <kstandarddirs.h>
68 #include <kconfig.h>
69 #include <kpassivepopup.h>
70 #include <kapplication.h>
71 #include <ksystemtrayicon.h>
72 #include <kconfiggroup.h>
73 #include <kdebug.h>
74 #include <kio/jobuidelegate.h>
75 #include <kprocess.h>
76 #include <KCrash>
77 
78 #include <kmime/kmime_message.h>
79 #include <kmime/kmime_util.h>
80 #include <Akonadi/Collection>
81 #include <Akonadi/CollectionFetchJob>
82 #include <Akonadi/ChangeRecorder>
83 #include <Akonadi/ItemFetchScope>
84 #include <Akonadi/AgentManager>
85 #include <Akonadi/ItemFetchJob>
86 #include <Akonadi/AttributeFactory>
87 #include <Akonadi/Session>
88 #include <Akonadi/EntityTreeModel>
89 #include <akonadi/entitymimetypefiltermodel.h>
90 #include <Akonadi/CollectionStatisticsJob>
91 
92 #include <QDir>
93 #include <QWidget>
94 #include <QFileInfo>
95 #include <QtDBus/QtDBus>
96 
97 #include <sys/types.h>
98 #include <dirent.h>
99 #include <sys/stat.h>
100 #include <unistd.h>
101 #include <stdio.h>
102 #include <stdlib.h>
103 #include <assert.h>
104 
105 #include <kcmdlineargs.h>
106 #include <kstartupinfo.h>
107 #include <kmailadaptor.h>
108 #include "kmailinterface.h"
109 #include "foldercollectionmonitor.h"
110 #include "imapresourcesettings.h"
111 #include "util.h"
112 #include "mailcommon/kernel/mailkernel.h"
113 
114 #include "searchdialog/searchdescriptionattribute.h"
115 
116 using namespace MailCommon;
117 
118 static KMKernel * mySelf = 0;
119 static bool s_askingToGoOnline = false;
120 
121 /********************************************************************/
122 /* Constructor and destructor */
123 /********************************************************************/
124 KMKernel::KMKernel (QObject *parent, const char *name) :
125  QObject(parent),
126  mIdentityManager(0), mConfigureDialog(0), mMailService(0),
127  mSystemNetworkStatus ( Solid::Networking::status() ), mSystemTray(0)
128 {
129  Akonadi::AttributeFactory::registerAttribute<Akonadi::SearchDescriptionAttribute>();
130  QDBusConnection::sessionBus().registerService(QLatin1String("org.kde.kmail"));
131  KMail::Util::migrateFromKMail1();
132  kDebug() << "Starting up...";
133 
134  mySelf = this;
135  the_startingUp = true;
136  the_firstInstance = true;
137 
138  the_undoStack = 0;
139  the_msgSender = 0;
140  mFilterEditDialog = 0;
141  mWin = 0;
142  mWrapCol = 80;
143  // make sure that we check for config updates before doing anything else
144  KMKernel::config();
145  // this shares the kmailrc parsing too (via KSharedConfig), and reads values from it
146  // so better do it here, than in some code where changing the group of config()
147  // would be unexpected
148  GlobalSettings::self();
149 
150  mJobScheduler = new JobScheduler( this );
151  mXmlGuiInstance = KComponentData();
152 
153  mAutoCorrection = new MessageComposer::ComposerAutoCorrection();
154  KMime::setFallbackCharEncoding( MessageCore::GlobalSettings::self()->fallbackCharacterEncoding() );
155  KMime::setUseOutlookAttachmentEncoding( MessageComposer::MessageComposerSettings::self()->outlookCompatibleAttachments() );
156 
157  // cberzan: this crap moved to CodecManager ======================
158  netCodec = QTextCodec::codecForName( KGlobal::locale()->encoding() );
159 
160  // In the case of Japan. Japanese locale name is "eucjp" but
161  // The Japanese mail systems normally used "iso-2022-jp" of locale name.
162  // We want to change locale name from eucjp to iso-2022-jp at KMail only.
163 
164  // (Introduction to i18n, 6.6 Limit of Locale technology):
165  // EUC-JP is the de-facto standard for UNIX systems, ISO 2022-JP
166  // is the standard for Internet, and Shift-JIS is the encoding
167  // for Windows and Macintosh.
168  if ( netCodec->name().toLower() == "eucjp"
169 #if defined Q_WS_WIN || defined Q_WS_MACX
170  || netCodec->name().toLower() == "shift-jis" // OK?
171 #endif
172  )
173  {
174  netCodec = QTextCodec::codecForName("jis7");
175  // QTextCodec *cdc = QTextCodec::codecForName("jis7");
176  // QTextCodec::setCodecForLocale(cdc);
177  // KGlobal::locale()->setEncoding(cdc->mibEnum());
178  }
179  // until here ================================================
180 
181  Akonadi::Session *session = new Akonadi::Session( "KMail Kernel ETM", this );
182 
183  mFolderCollectionMonitor = new FolderCollectionMonitor( session, this );
184 
185  connect( mFolderCollectionMonitor->monitor(), SIGNAL(collectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)), SLOT(slotCollectionMoved(Akonadi::Collection,Akonadi::Collection,Akonadi::Collection)) );
186  connect( mFolderCollectionMonitor->monitor(), SIGNAL(collectionRemoved(Akonadi::Collection)), SLOT(slotCollectionRemoved(Akonadi::Collection)));
187 
188  mEntityTreeModel = new Akonadi::EntityTreeModel( folderCollectionMonitor(), this );
189  mEntityTreeModel->setIncludeUnsubscribed( false );
190  mEntityTreeModel->setItemPopulationStrategy( Akonadi::EntityTreeModel::LazyPopulation );
191 
192  mCollectionModel = new Akonadi::EntityMimeTypeFilterModel( this );
193  mCollectionModel->setSourceModel( mEntityTreeModel );
194  mCollectionModel->addMimeTypeInclusionFilter( Akonadi::Collection::mimeType() );
195  mCollectionModel->setHeaderGroup( Akonadi::EntityTreeModel::CollectionTreeHeaders );
196  mCollectionModel->setDynamicSortFilter( true );
197  mCollectionModel->setSortCaseSensitivity( Qt::CaseInsensitive );
198 
199 
200  connect( folderCollectionMonitor(), SIGNAL(collectionChanged(Akonadi::Collection,QSet<QByteArray>)),
201  SLOT(slotCollectionChanged(Akonadi::Collection,QSet<QByteArray>)) );
202 
203  connect( MailTransport::TransportManager::self(),
204  SIGNAL(transportRemoved(int,QString)),
205  SLOT(transportRemoved(int,QString)) );
206  connect( MailTransport::TransportManager::self(),
207  SIGNAL(transportRenamed(int,QString,QString)),
208  SLOT(transportRenamed(int,QString,QString)) );
209 
210  QDBusConnection::sessionBus().connect(QString(), QLatin1String( "/MailDispatcherAgent" ), QLatin1String("org.freedesktop.Akonadi.MailDispatcherAgent"), QLatin1String("itemDispatchStarted"),this, SLOT(itemDispatchStarted()) );
211  connect( Akonadi::AgentManager::self(), SIGNAL(instanceStatusChanged(Akonadi::AgentInstance)),
212  this, SLOT(instanceStatusChanged(Akonadi::AgentInstance)) );
213 
214  connect( Akonadi::AgentManager::self(), SIGNAL(instanceError(Akonadi::AgentInstance,QString)),
215  this, SLOT(slotInstanceError(Akonadi::AgentInstance,QString)) );
216 
217  connect( Akonadi::AgentManager::self(), SIGNAL(instanceWarning(Akonadi::AgentInstance,QString)),
218  SLOT(slotInstanceWarning(Akonadi::AgentInstance,QString)) );
219 
220  connect( Akonadi::AgentManager::self(), SIGNAL(instanceRemoved(Akonadi::AgentInstance)),
221  this, SLOT(slotInstanceRemoved(Akonadi::AgentInstance)) );
222 
223  connect ( Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)),
224  this, SLOT(slotSystemNetworkStatusChanged(Solid::Networking::Status)) );
225 
226  connect( KPIM::ProgressManager::instance(), SIGNAL(progressItemCompleted(KPIM::ProgressItem*)),
227  this, SLOT(slotProgressItemCompletedOrCanceled(KPIM::ProgressItem*)) );
228  connect( KPIM::ProgressManager::instance(), SIGNAL(progressItemCanceled(KPIM::ProgressItem*)),
229  this, SLOT(slotProgressItemCompletedOrCanceled(KPIM::ProgressItem*)) );
230  connect( identityManager(), SIGNAL(deleted(uint)), this, SLOT(slotDeleteIdentity(uint)) );
231  CommonKernel->registerKernelIf( this );
232  CommonKernel->registerSettingsIf( this );
233  CommonKernel->registerFilterIf( this );
234 }
235 
236 KMKernel::~KMKernel ()
237 {
238  delete mMailService;
239  mMailService = 0;
240 
241  mSystemTray = 0;
242 
243  stopAgentInstance();
244  slotSyncConfig();
245 
246  delete mAutoCorrection;
247  mySelf = 0;
248  kDebug();
249 }
250 
251 Akonadi::ChangeRecorder * KMKernel::folderCollectionMonitor() const
252 {
253  return mFolderCollectionMonitor->monitor();
254 }
255 
256 Akonadi::EntityTreeModel * KMKernel::entityTreeModel() const
257 {
258  return mEntityTreeModel;
259 }
260 
261 Akonadi::EntityMimeTypeFilterModel * KMKernel::collectionModel() const
262 {
263  return mCollectionModel;
264 }
265 
266 void KMKernel::setupDBus()
267 {
268  (void) new KmailAdaptor( this );
269  QDBusConnection::sessionBus().registerObject( QLatin1String("/KMail"), this );
270  mMailService = new MailServiceImpl();
271 }
272 
273 static KUrl makeAbsoluteUrl( const QString& str )
274 {
275  KUrl url( str );
276  if ( url.protocol().isEmpty() ) {
277  const QString newUrl = KCmdLineArgs::cwd() + QLatin1Char('/') + url.fileName();
278  return KUrl( newUrl );
279  }
280  else {
281  return url;
282  }
283 }
284 
285 bool KMKernel::handleCommandLine( bool noArgsOpensReader )
286 {
287  QString to, cc, bcc, subj, body, inReplyTo, replyTo;
288  QStringList customHeaders;
289  KUrl messageFile;
290  KUrl::List attachURLs;
291  bool mailto = false;
292  bool checkMail = false;
293  bool viewOnly = false;
294  bool calledWithSession = false; // for ignoring '-session foo'
295 
296  // process args:
297  KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
298  if (args->isSet("subject"))
299  {
300  subj = args->getOption("subject");
301  // if kmail is called with 'kmail -session abc' then this doesn't mean
302  // that the user wants to send a message with subject "ession" but
303  // (most likely) that the user clicked on KMail's system tray applet
304  // which results in KMKernel::raise() calling "kmail kmail newInstance"
305  // via D-Bus which apparently executes the application with the original
306  // command line arguments and those include "-session ..." if
307  // kmail/kontact was restored by session management
308  if ( subj == QLatin1String("ession") ) {
309  subj.clear();
310  calledWithSession = true;
311  }
312  else
313  mailto = true;
314  }
315 
316  if (args->isSet("cc"))
317  {
318  mailto = true;
319  cc = args->getOption("cc");
320  }
321 
322  if (args->isSet("bcc"))
323  {
324  mailto = true;
325  bcc = args->getOption("bcc");
326  }
327 
328  if (args->isSet("replyTo"))
329  {
330  mailto = true;
331  replyTo = args->getOption("replyTo");
332  }
333 
334 
335  if (args->isSet("msg"))
336  {
337  mailto = true;
338  const QString file = args->getOption("msg");
339  messageFile = makeAbsoluteUrl(file);
340  }
341 
342  if (args->isSet("body"))
343  {
344  mailto = true;
345  body = args->getOption("body");
346  }
347 
348  const QStringList attachList = args->getOptionList("attach");
349  if ( !attachList.isEmpty() ) {
350  mailto = true;
351  QStringList::ConstIterator end = attachList.constEnd();
352  for ( QStringList::ConstIterator it = attachList.constBegin();
353  it != end; ++it ) {
354  if ( !(*it).isEmpty() ) {
355  attachURLs.append( makeAbsoluteUrl( *it ) );
356  }
357  }
358  }
359 
360  customHeaders = args->getOptionList("header");
361 
362  if (args->isSet("composer"))
363  mailto = true;
364 
365  if (args->isSet("check"))
366  checkMail = true;
367 
368  if ( args->isSet( "view" ) ) {
369  viewOnly = true;
370  const QString filename =
371  args->getOption( "view" );
372  messageFile = KUrl( filename );
373  if ( !messageFile.isValid() ) {
374  messageFile = KUrl();
375  messageFile.setPath( filename );
376  }
377  }
378 
379  if ( !calledWithSession ) {
380  // only read additional command line arguments if kmail/kontact is
381  // not called with "-session foo"
382  const int nbArgs = args->count();
383  for (int i= 0; i < nbArgs; ++i)
384  {
385  if ( args->arg(i).startsWith( QLatin1String( "mailto:" ), Qt::CaseInsensitive ) ) {
386  QMap<QString, QString> values = MessageCore::StringUtil::parseMailtoUrl( args->url( i ) );
387  if ( !values.value( QLatin1String("to") ).isEmpty() )
388  to += values.value( QLatin1String("to") ) + QLatin1String(", ");
389  if ( !values.value( QLatin1String("cc") ).isEmpty() )
390  cc += values.value( QLatin1String("cc") ) + QLatin1String(", ");
391  if ( !values.value( QLatin1String("subject") ).isEmpty() )
392  subj = values.value( QLatin1String("subject") );
393  if ( !values.value( QLatin1String("body") ).isEmpty() )
394  body = values.value(QLatin1String( "body") );
395  if ( !values.value( QLatin1String("in-reply-to") ).isEmpty() ) {
396  inReplyTo = values.value( QLatin1String("in-reply-to") );
397  }
398  const QString attach = values.value( QLatin1String("attachment") );
399  if ( !attach.isEmpty() ) {
400  attachURLs << makeAbsoluteUrl( attach );
401  }
402  }
403  else {
404  QString tmpArg = args->arg(i);
405  KUrl url( tmpArg );
406  if (url.isValid() && !url.protocol().isEmpty())
407  attachURLs += url;
408  else
409  to += tmpArg + QLatin1String(", ");
410  }
411  mailto = true;
412  }
413  if ( !to.isEmpty() ) {
414  // cut off the superfluous trailing ", "
415  to.truncate( to.length() - 2 );
416  }
417  }
418 
419  if ( !calledWithSession )
420  args->clear();
421 
422  if ( !noArgsOpensReader && !mailto && !checkMail && !viewOnly )
423  return false;
424 
425  if ( viewOnly )
426  viewMessage( messageFile.url() );
427  else
428  action( mailto, checkMail, to, cc, bcc, subj, body, messageFile,
429  attachURLs, customHeaders, replyTo, inReplyTo );
430  return true;
431 }
432 
433 /********************************************************************/
434 /* D-Bus-callable, and command line actions */
435 /********************************************************************/
436 void KMKernel::checkMail () //might create a new reader but won't show!!
437 {
438  if ( !kmkernel->askToGoOnline() )
439  return;
440 
441  const QString resourceGroupPattern( QLatin1String("Resource %1") );
442 
443  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
444  foreach( Akonadi::AgentInstance type, lst ) {
445  const QString id = type.identifier();
446  KConfigGroup group( KMKernel::config(), resourceGroupPattern.arg( id ) );
447  if ( group.readEntry( "IncludeInManualChecks", true ) ) {
448  if ( !type.isOnline() )
449  type.setIsOnline( true );
450  if ( mResourcesBeingChecked.isEmpty() ) {
451  kDebug() << "Starting manual mail check";
452  emit startCheckMail();
453  }
454 
455  if ( !mResourcesBeingChecked.contains( id ) ) {
456  mResourcesBeingChecked.append( id );
457  }
458  type.synchronize();
459  }
460  }
461 }
462 
463 void KMKernel::setSystrayIconNotificationsEnabled( bool enabled )
464 {
465  if ( mSystemTray ) {
466  mSystemTray->setSystrayIconNotificationsEnabled( enabled );
467  }
468 }
469 
470 QStringList KMKernel::accounts()
471 {
472  QStringList accountLst;
473  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
474  foreach ( const Akonadi::AgentInstance& type, lst )
475  {
476  // Explicitly make a copy, as we're not changing values of the list but only
477  // the local copy which is passed to action.
478  accountLst<<type.identifier();
479  }
480  return accountLst;
481 }
482 
483 void KMKernel::checkAccount( const QString &account ) //might create a new reader but won't show!!
484 {
485  kDebug();
486  if ( account.isEmpty() )
487  checkMail();
488  else {
489  Akonadi::AgentInstance agent = Akonadi::AgentManager::self()->instance( account );
490  if ( agent.isValid() )
491  agent.synchronize();
492  else
493  kDebug() << "- account with name '" << account <<"' not found";
494  }
495 }
496 
497 void KMKernel::openReader( bool onlyCheck )
498 {
499  mWin = 0;
500  KMainWindow *ktmw = 0;
501  kDebug();
502 
503  foreach ( KMainWindow *window, KMainWindow::memberList() )
504  {
505  if ( ::qobject_cast<KMMainWin *>( window ) )
506  {
507  ktmw = window;
508  break;
509  }
510  }
511 
512  bool activate;
513  if (ktmw) {
514  mWin = static_cast<KMMainWin *>(ktmw);
515  activate = !onlyCheck; // existing window: only activate if not --check
516  if ( activate )
517  mWin->show();
518  }
519  else {
520  mWin = new KMMainWin;
521  mWin->show();
522  activate = false; // new window: no explicit activation (#73591)
523  }
524 
525  if ( activate ) {
526  // Activate window - doing this instead of KWindowSystem::activateWindow(mWin->winId());
527  // so that it also works when called from KMailApplication::newInstance()
528 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
529  KStartupInfo::setNewStartupId( mWin, kapp->startupId() );
530 #endif
531  }
532 }
533 
534 int KMKernel::openComposer(const QString &to, const QString &cc,
535  const QString &bcc, const QString &subject,
536  const QString &body, bool hidden,
537  const QString &messageFile,
538  const QStringList &attachmentPaths,
539  const QStringList &customHeaders,
540  const QString &replyTo, const QString &inReplyTo)
541 {
542  kDebug();
543  KMail::Composer::TemplateContext context = KMail::Composer::New;
544  KMime::Message::Ptr msg( new KMime::Message );
545  MessageHelper::initHeader( msg, identityManager() );
546  msg->contentType()->setCharset("utf-8");
547  if ( !to.isEmpty() )
548  msg->to()->fromUnicodeString( to, "utf-8" );
549 
550  if ( !cc.isEmpty() )
551  msg->cc()->fromUnicodeString( cc, "utf-8" );
552 
553  if ( !bcc.isEmpty() )
554  msg->bcc()->fromUnicodeString( bcc, "utf-8" );
555 
556  if ( !subject.isEmpty() )
557  msg->subject()->fromUnicodeString( subject, "utf-8" );
558 
559  KUrl messageUrl = KUrl( messageFile );
560  if ( !messageUrl.isEmpty() && messageUrl.isLocalFile() ) {
561  const QByteArray str = KPIMUtils::kFileToByteArray( messageUrl.toLocalFile(), true, false );
562  if( !str.isEmpty() ) {
563  context = KMail::Composer::NoTemplate;
564  msg->setBody( QString::fromLocal8Bit( str.data(), str.size() ).toUtf8() );
565  }
566  else {
567  TemplateParser::TemplateParser parser( msg, TemplateParser::TemplateParser::NewMessage );
568  parser.setIdentityManager( KMKernel::self()->identityManager() );
569  parser.process( msg );
570  }
571  }
572  else if ( !body.isEmpty() ) {
573  context = KMail::Composer::NoTemplate;
574  msg->setBody( body.toUtf8() );
575  }
576  else {
577  TemplateParser::TemplateParser parser( msg, TemplateParser::TemplateParser::NewMessage );
578  parser.setIdentityManager( KMKernel::self()->identityManager() );
579  parser.process( msg );
580  }
581 
582  if (!inReplyTo.isEmpty()) {
583  KMime::Headers::InReplyTo *header = new KMime::Headers::InReplyTo( msg.get(), inReplyTo, "utf-8" );
584  msg->setHeader( header );
585  }
586 
587  msg->assemble();
588  KMail::Composer * cWin = KMail::makeComposer( msg, false, false, context );
589  if (!to.isEmpty())
590  cWin->setFocusToSubject();
591  KUrl::List attachURLs = KUrl::List( attachmentPaths );
592  for ( KUrl::List::ConstIterator it = attachURLs.constBegin() ; it != attachURLs.constEnd() ; ++it ) {
593  if( KMimeType::findByUrl( *it )->name() == QLatin1String( "inode/directory" ) ) {
594  if(KMessageBox::questionYesNo(0, i18n("Do you want to attach this folder \"%1\"?",(*it).prettyUrl()), i18n("Attach Folder")) == KMessageBox::No ) {
595  continue;
596  }
597  }
598  cWin->addAttachment( (*it), QString() );
599  }
600  if (!replyTo.isEmpty()) {
601  cWin->setCurrentReplyTo(replyTo);
602  }
603 
604  if (!customHeaders.isEmpty()) {
605  QMap<QByteArray, QString> extraCustomHeaders;
606  QStringList::ConstIterator end = customHeaders.constEnd();
607  for ( QStringList::ConstIterator it = customHeaders.constBegin() ; it != end ; ++it ) {
608  if ( !(*it).isEmpty() ) {
609  const int pos = (*it).indexOf( QLatin1Char(':') );
610  if ( pos > 0 ) {
611  const QString header = (*it).left( pos ).trimmed();
612  const QString value = (*it).mid( pos+1 ).trimmed();
613  if ( !header.isEmpty() && !value.isEmpty() ) {
614  extraCustomHeaders.insert(header.toUtf8(), value);
615  }
616  }
617  }
618  }
619  if (!extraCustomHeaders.isEmpty())
620  cWin->addExtraCustomHeaders(extraCustomHeaders);
621  }
622  if ( !hidden ) {
623  cWin->show();
624  // Activate window - doing this instead of KWindowSystem::activateWindow(cWin->winId());
625  // so that it also works when called from KMailApplication::newInstance()
626 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
627  KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
628 #endif
629  }
630  return 1;
631 }
632 
633 int KMKernel::openComposer (const QString &to, const QString &cc,
634  const QString &bcc, const QString &subject,
635  const QString &body, bool hidden,
636  const QString &attachName,
637  const QByteArray &attachCte,
638  const QByteArray &attachData,
639  const QByteArray &attachType,
640  const QByteArray &attachSubType,
641  const QByteArray &attachParamAttr,
642  const QString &attachParamValue,
643  const QByteArray &attachContDisp,
644  const QByteArray &attachCharset,
645  unsigned int identity )
646 {
647  kDebug();
648  KMail::Composer::TemplateContext context = KMail::Composer::New;
649  KMime::Message::Ptr msg( new KMime::Message );
650  KMime::Content *msgPart = 0;
651  MessageHelper::initHeader( msg, identityManager() );
652  msg->contentType()->setCharset( "utf-8" );
653  if ( !cc.isEmpty() ) msg->cc()->fromUnicodeString( cc, "utf-8" );
654  if ( !bcc.isEmpty() ) msg->bcc()->fromUnicodeString( bcc, "utf-8" );
655  if ( !subject.isEmpty() ) msg->subject()->fromUnicodeString( subject, "utf-8" );
656  if ( !to.isEmpty() ) msg->to()->fromUnicodeString( to, "utf-8" );
657  if ( identity > 0 ) {
658  KMime::Headers::Generic *h = new KMime::Headers::Generic("X-KMail-Identity", msg.get(), QByteArray::number( identity ) );
659  msg->setHeader( h );
660  }
661  if ( !body.isEmpty() ) {
662  msg->setBody(body.toUtf8());
663  context = KMail::Composer::NoTemplate;
664  } else {
665  TemplateParser::TemplateParser parser( msg, TemplateParser::TemplateParser::NewMessage );
666  parser.setIdentityManager( KMKernel::self()->identityManager() );
667  parser.process( KMime::Message::Ptr() );
668  }
669 
670  bool iCalAutoSend = false;
671  bool noWordWrap = false;
672  bool isICalInvitation = false;
673  //KConfigGroup options( config(), "Groupware" );
674  if ( !attachData.isEmpty() ) {
675  isICalInvitation = (attachName ==QLatin1String("cal.ics")) &&
676  attachType == "text" &&
677  attachSubType == "calendar" &&
678  attachParamAttr == "method";
679  // Remove BCC from identity on ical invitations (https://intevation.de/roundup/kolab/issue474)
680  if ( isICalInvitation && bcc.isEmpty() )
681  msg->bcc()->clear();
682  if ( isICalInvitation &&
683  MessageViewer::GlobalSettings::self()->legacyBodyInvites() ) {
684  // KOrganizer invitation caught and to be sent as body instead
685  msg->setBody( attachData );
686  context = KMail::Composer::NoTemplate;
687  msg->contentType()->from7BitString(
688  QString::fromLatin1("text/calendar; method=%1; "
689  "charset=\"utf-8\"" ).
690  arg( attachParamValue ).toLatin1() );
691 
692  iCalAutoSend = true; // no point in editing raw ICAL
693  noWordWrap = true; // we shant word wrap inline invitations
694  } else {
695  // Just do what we're told to do
696  msgPart = new KMime::Content;
697  msgPart->contentType()->setName( attachName, "utf-8" );
698  msgPart->contentTransferEncoding()->fromUnicodeString(QLatin1String(attachCte), "utf-8" );
699  msgPart->setBody( attachData ); //TODO: check if was setBodyEncoded
700  msgPart->contentType()->setMimeType( attachType + '/' + attachSubType );
701  msgPart->contentDisposition()->setParameter( QLatin1String(attachParamAttr), attachParamValue ); //TODO: Check if the content disposition parameter needs to be set!
702  if( ! MessageViewer::GlobalSettings::self()->exchangeCompatibleInvitations() ) {
703  msgPart->contentDisposition()->fromUnicodeString(QLatin1String(attachContDisp), "utf-8" );
704  }
705  if( !attachCharset.isEmpty() ) {
706  // kDebug() << "Set attachCharset to" << attachCharset;
707  msgPart->contentType()->setCharset( attachCharset );
708  }
709  // Don't show the composer window if the automatic sending is checked
710  iCalAutoSend = MessageViewer::GlobalSettings::self()->automaticSending();
711  }
712  }
713 
714  msg->assemble();
715  KMail::Composer * cWin = KMail::makeComposer( KMime::Message::Ptr(), false, false,context );
716  cWin->setMessage( msg, false, false, !isICalInvitation /* mayAutoSign */ );
717  cWin->setSigningAndEncryptionDisabled( isICalInvitation
718  && MessageViewer::GlobalSettings::self()->legacyBodyInvites() );
719  if ( noWordWrap )
720  cWin->disableWordWrap();
721  if ( msgPart )
722  cWin->addAttach( msgPart );
723  if ( isICalInvitation ) {
724  cWin->forceDisableHtml();
725  //cWin->disableRecipientNumberCheck();
726  cWin->disableForgottenAttachmentsCheck();
727  }
728 
729  if ( !hidden && !iCalAutoSend ) {
730  cWin->show();
731  // Activate window - doing this instead of KWin::activateWindow(cWin->winId());
732  // so that it also works when called from KMailApplication::newInstance()
733 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
734  KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
735 #endif
736  } else {
737 
738  // Always disable word wrap when we don't show the composer, since otherwise QTextEdit
739  // gets the widget size wrong and wraps much too early.
740  cWin->disableWordWrap();
741  cWin->slotSendNow();
742  }
743 
744  return 1;
745 }
746 
747 QDBusObjectPath KMKernel::openComposer( const QString &to, const QString &cc,
748  const QString &bcc,
749  const QString &subject,
750  const QString &body, bool hidden )
751 {
752  KMime::Message::Ptr msg( new KMime::Message );
753  MessageHelper::initHeader( msg, identityManager() );
754  msg->contentType()->setCharset("utf-8");
755  if ( !cc.isEmpty() ) msg->cc()->fromUnicodeString( cc, "utf-8" );
756  if ( !bcc.isEmpty() ) msg->bcc()->fromUnicodeString( bcc, "utf-8" );
757  if ( !subject.isEmpty() ) msg->subject()->fromUnicodeString( subject, "utf-8" );
758  if ( !to.isEmpty() ) msg->to()->fromUnicodeString( to, "utf-8" );
759  if ( !body.isEmpty() ) {
760  msg->setBody( body.toUtf8() );
761  } else {
762  TemplateParser::TemplateParser parser( msg, TemplateParser::TemplateParser::NewMessage );
763  parser.setIdentityManager( KMKernel::self()->identityManager() );
764  parser.process( KMime::Message::Ptr() );
765  }
766 
767  msg->assemble();
768  const KMail::Composer::TemplateContext context = body.isEmpty() ? KMail::Composer::New :
769  KMail::Composer::NoTemplate;
770  KMail::Composer * cWin = KMail::makeComposer( msg, false, false, context );
771  if ( !hidden ) {
772  cWin->show();
773  // Activate window - doing this instead of KWindowSystem::activateWindow(cWin->winId());
774  // so that it also works when called from KMailApplication::newInstance()
775 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
776  KStartupInfo::setNewStartupId( cWin, kapp->startupId() );
777 #endif
778  } else {
779  // Always disable word wrap when we don't show the composer; otherwise,
780  // QTextEdit gets the widget size wrong and wraps much too early.
781  cWin->disableWordWrap();
782  cWin->slotSendNow();
783  }
784 
785  return QDBusObjectPath(cWin->dbusObjectPath());
786 }
787 
788 QDBusObjectPath KMKernel::newMessage( const QString &to,
789  const QString &cc,
790  const QString &bcc,
791  bool hidden,
792  bool useFolderId,
793  const QString & /*messageFile*/,
794  const QString &_attachURL)
795 {
796  KUrl attachURL( _attachURL );
797  KMime::Message::Ptr msg( new KMime::Message );
798  QSharedPointer<FolderCollection> folder;
799  uint id = 0;
800 
801  if ( useFolderId ) {
802  //create message with required folder identity
803  folder = currentFolderCollection();
804  id = folder ? folder->identity() : 0;
805  }
806  MessageHelper::initHeader( msg, identityManager(), id );
807  msg->contentType()->setCharset( "utf-8" );
808  //set basic headers
809  if ( !cc.isEmpty() ) msg->cc()->fromUnicodeString( cc, "utf-8" );
810  if ( !bcc.isEmpty() ) msg->bcc()->fromUnicodeString( bcc, "utf-8" );
811  if ( !to.isEmpty() ) msg->to()->fromUnicodeString( to, "utf-8" );
812 
813  msg->assemble();
814  TemplateParser::TemplateParser parser( msg, TemplateParser::TemplateParser::NewMessage );
815  parser.setIdentityManager( identityManager() );
816  Akonadi::Collection col = folder ? folder->collection() : Akonadi::Collection();
817  parser.process( msg, col );
818 
819  KMail::Composer *win = makeComposer( msg, false, false, KMail::Composer::New, id );
820 
821  win->setCollectionForNewMessage(col);
822  //Add the attachment if we have one
823  if ( !attachURL.isEmpty() && attachURL.isValid() ) {
824  win->addAttachment( attachURL, QString() );
825  }
826 
827  //only show window when required
828  if ( !hidden ) {
829  win->show();
830  }
831  return QDBusObjectPath( win->dbusObjectPath() );
832 }
833 
834 int KMKernel::viewMessage( const QString & messageFile )
835 {
836  KMOpenMsgCommand *openCommand = new KMOpenMsgCommand( 0, KUrl( messageFile ) );
837 
838  openCommand->start();
839  return 1;
840 }
841 
842 void KMKernel::raise()
843 {
844  QDBusInterface iface( QLatin1String("org.kde.kmail"), QLatin1String("/MainApplication"),
845  QLatin1String("org.kde.KUniqueApplication"),
846  QDBusConnection::sessionBus());
847  QDBusReply<int> reply;
848  if ( !iface.isValid() || !( reply = iface.call( QLatin1String("newInstance") ) ).isValid() )
849  {
850  QDBusError err = iface.lastError();
851  kError() << "Communication problem with KMail. "
852  << "Error message was:" << err.name() << ": \"" << err.message() << "\"";
853  }
854 
855 }
856 
857 bool KMKernel::showMail( quint32 serialNumber, const QString& /* messageId */ )
858 {
859  KMMainWidget *mainWidget = 0;
860 
861  // First look for a KMainWindow.
862  foreach ( KMainWindow* window, KMainWindow::memberList() ) {
863  // Then look for a KMMainWidget.
864  QList<KMMainWidget*> l = window->findChildren<KMMainWidget*>();
865  if ( !l.isEmpty() && l.first() ) {
866  mainWidget = l.first();
867  if ( window->isActiveWindow() )
868  break;
869  }
870  }
871  if ( mainWidget ) {
872  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( Akonadi::Item(serialNumber ),this );
873  job->fetchScope().fetchFullPayload();
874  if ( job->exec() ) {
875  if ( job->items().count() >= 1 ) {
876  KMReaderMainWin *win = new KMReaderMainWin( false, false );
877  win->showMessage( MessageCore::GlobalSettings::self()->overrideCharacterEncoding(),
878  job->items().at( 0 ) );
879  win->show();
880  return true;
881  }
882  }
883  }
884  return false;
885 }
886 
887 void KMKernel::pauseBackgroundJobs()
888 {
889  mBackgroundTasksTimer->stop();
890  mJobScheduler->pause();
891 }
892 
893 void KMKernel::resumeBackgroundJobs()
894 {
895  mJobScheduler->resume();
896  mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000 );
897 }
898 
899 void KMKernel::stopNetworkJobs()
900 {
901  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
902  return;
903 
904  setAccountStatus(false);
905 
906  GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Offline );
907  BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be offline; all network jobs are suspended"));
908  emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
909 
910 }
911 
912 void KMKernel::setAccountStatus(bool goOnline)
913 {
914  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances(false);
915  foreach ( Akonadi::AgentInstance type, lst ) {
916  const QString identifier( type.identifier() );
917  if ( identifier.contains( IMAP_RESOURCE_IDENTIFIER ) ||
918  identifier.contains( POP3_RESOURCE_IDENTIFIER ) ||
919  identifier.contains( QLatin1String("akonadi_maildispatcher_agent") ) ) {
920  type.setIsOnline( goOnline );
921  }
922  }
923  if ( goOnline && MessageComposer::MessageComposerSettings::self()->sendImmediate() ) {
924  const qint64 nbMsgOutboxCollection = MailCommon::Util::updatedCollection( CommonKernel->outboxCollectionFolder() ).statistics().count();
925  if(nbMsgOutboxCollection > 0) {
926  kmkernel->msgSender()->sendQueued();
927  }
928  }
929 }
930 
931 void KMKernel::resumeNetworkJobs()
932 {
933  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Online )
934  return;
935 
936  if ( ( mSystemNetworkStatus == Solid::Networking::Connected ) ||
937  ( mSystemNetworkStatus == Solid::Networking::Unknown ) ) {
938  setAccountStatus(true);
939  BroadcastStatus::instance()->setStatusMsg( i18n("KMail is set to be online; all network jobs resumed"));
940  }
941  else {
942  BroadcastStatus::instance()->setStatusMsg( i18n ( "KMail is set to be online; all network jobs will resume when a network connection is detected" ) );
943  }
944  GlobalSettings::setNetworkState( GlobalSettings::EnumNetworkState::Online );
945  emit onlineStatusChanged( (GlobalSettings::EnumNetworkState::type)GlobalSettings::networkState() );
946  KMMainWidget *widget = getKMMainWidget();
947  if ( widget ) {
948  widget->clearViewer();
949  }
950 }
951 
952 bool KMKernel::isOffline()
953 {
954  Solid::Networking::Status networkStatus = Solid::Networking::status();
955  if ( ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline ) ||
956  ( networkStatus == Solid::Networking::Unconnected ) ||
957  ( networkStatus == Solid::Networking::Disconnecting ) ||
958  ( networkStatus == Solid::Networking::Connecting ))
959  return true;
960  else
961  return false;
962 }
963 
964 void KMKernel::checkMailOnStartup()
965 {
966  if ( !kmkernel->askToGoOnline() )
967  return;
968 
969  const QString resourceGroupPattern( QLatin1String("Resource %1") );
970 
971  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
972  foreach( Akonadi::AgentInstance type, lst ) {
973  KConfigGroup group( KMKernel::config(), resourceGroupPattern.arg( type.identifier() ) );
974  if ( group.readEntry( "CheckOnStartup", false ) ) {
975  if ( !type.isOnline() )
976  type.setIsOnline( true );
977  type.synchronize();
978  }
979 
980  // "false" is also hardcoded in ConfigureDialog, don't forget to change there.
981  if ( group.readEntry( "OfflineOnShutdown", false ) ) {
982  if ( !type.isOnline() )
983  type.setIsOnline( true );
984  }
985  }
986 }
987 
988 bool KMKernel::askToGoOnline()
989 {
990  // already asking means we are offline and need to wait anyhow
991  if ( s_askingToGoOnline ) {
992  return false;
993  }
994 
995  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline ) {
996  s_askingToGoOnline = true;
997  int rc =
998  KMessageBox::questionYesNo( KMKernel::self()->mainWin(),
999  i18n("KMail is currently in offline mode. "
1000  "How do you want to proceed?"),
1001  i18n("Online/Offline"),
1002  KGuiItem(i18n("Work Online")),
1003  KGuiItem(i18n("Work Offline")));
1004 
1005  s_askingToGoOnline = false;
1006  if( rc == KMessageBox::No ) {
1007  return false;
1008  } else {
1009  kmkernel->resumeNetworkJobs();
1010  }
1011  }
1012  if( kmkernel->isOffline() )
1013  return false;
1014 
1015  return true;
1016 }
1017 
1018 void KMKernel::slotSystemNetworkStatusChanged( Solid::Networking::Status status )
1019 {
1020  mSystemNetworkStatus = status;
1021  if ( GlobalSettings::self()->networkState() == GlobalSettings::EnumNetworkState::Offline )
1022  return;
1023 
1024  if ( status == Solid::Networking::Connected || status == Solid::Networking::Unknown) {
1025  BroadcastStatus::instance()->setStatusMsg( i18n(
1026  "Network connection detected, all network jobs resumed") );
1027  kmkernel->setAccountStatus( true );
1028  }
1029  else {
1030  BroadcastStatus::instance()->setStatusMsg( i18n(
1031  "No network connection detected, all network jobs are suspended"));
1032  kmkernel->setAccountStatus( false );
1033  }
1034 }
1035 
1036 /********************************************************************/
1037 /* Kernel methods */
1038 /********************************************************************/
1039 
1040 void KMKernel::quit()
1041 {
1042  // Called when all windows are closed. Will take care of compacting,
1043  // sending... should handle session management too!!
1044 }
1045  /* TODO later:
1046  Asuming that:
1047  - msgsender is nonblocking
1048  (our own, QSocketNotifier based. Pops up errors and sends signal
1049  senderFinished when done)
1050 
1051  o If we are getting mail, stop it (but don't lose something!)
1052  [Done already, see mailCheckAborted]
1053  o If we are sending mail, go on UNLESS this was called by SM,
1054  in which case stop ASAP that too (can we warn? should we continue
1055  on next start?)
1056  o If we are compacting, or expunging, go on UNLESS this was SM call.
1057  In that case stop compacting ASAP and continue on next start, before
1058  touching any folders. [Not needed anymore with CompactionJob]
1059 
1060  KMKernel::quit ()
1061  {
1062  SM call?
1063  if compacting, stop;
1064  if sending, stop;
1065  if receiving, stop;
1066  Windows will take care of themselves (composer should dump
1067  its messages, if any but not in deadMail)
1068  declare us ready for the End of the Session
1069 
1070  No, normal quit call
1071  All windows are off. Anything to do, should compact or sender sends?
1072  Yes, maybe put an icon in panel as a sign of life
1073  if sender sending, connect us to his finished slot, declare us ready
1074  for quit and wait for senderFinished
1075  if not, Folder manager, go compact sent-mail and outbox
1076 } (= call slotFinished())
1077 
1078 void KMKernel::slotSenderFinished()
1079 {
1080  good, Folder manager go compact sent-mail and outbox
1081  clean up stage1 (release folders and config, unregister from dcop)
1082  -- another kmail may start now ---
1083  qApp->quit();
1084 }
1085 */
1086 
1087 
1088 /********************************************************************/
1089 /* Init, Exit, and handler methods */
1090 /********************************************************************/
1091 
1092 //-----------------------------------------------------------------------------
1093 // Open a composer for each message found in the dead.letter folder
1094 void KMKernel::recoverDeadLetters()
1095 {
1096  const QString pathName = localDataPath();
1097  QDir dir( pathName );
1098  if ( !dir.exists( QLatin1String("autosave") ) )
1099  return;
1100 
1101  dir.cd( localDataPath() + QLatin1String("autosave") );
1102  const QFileInfoList autoSaveFiles = dir.entryInfoList();
1103  foreach( const QFileInfo &file, autoSaveFiles ) {
1104  // Disregard the '.' and '..' folders
1105  const QString filename = file.fileName();
1106  if( filename == QLatin1String( "." ) ||
1107  filename == QLatin1String( ".." )
1108  || file.isDir() )
1109  continue;
1110  kDebug() << "Opening autosave file:" << file.absoluteFilePath();
1111  QFile autoSaveFile( file.absoluteFilePath() );
1112  if( autoSaveFile.open( QIODevice::ReadOnly ) ) {
1113  const KMime::Message::Ptr autoSaveMessage( new KMime::Message() );
1114  const QByteArray msgData = autoSaveFile.readAll();
1115  autoSaveMessage->setContent( msgData );
1116  autoSaveMessage->parse();
1117 
1118  // Show the a new composer dialog for the message
1119  KMail::Composer * autoSaveWin = KMail::makeComposer();
1120  autoSaveWin->setMessage( autoSaveMessage, false, false, false );
1121  autoSaveWin->setAutoSaveFileName( filename );
1122  autoSaveWin->show();
1123  autoSaveFile.close();
1124  } else {
1125  KMessageBox::sorry( 0, i18n( "Failed to open autosave file at %1.\nReason: %2" ,
1126  file.absoluteFilePath(), autoSaveFile.errorString() ),
1127  i18n( "Opening Autosave File Failed" ) );
1128  }
1129  }
1130 }
1131 
1132 
1133 void KMKernel::akonadiStateChanged( Akonadi::ServerManager::State state )
1134 {
1135  kDebug() << "KMKernel has akonadi state changed to:" << int( state );
1136 
1137  if( state == Akonadi::ServerManager::Running ) {
1138  CommonKernel->initFolders();
1139  }
1140 }
1141 static void kmCrashHandler( int sigId )
1142 {
1143  fprintf( stderr, "*** KMail got signal %d (Exiting)\n", sigId );
1144  // try to cleanup all windows
1145  if ( kmkernel ) {
1146  kmkernel->dumpDeadLetters();
1147  fprintf( stderr, "*** Dead letters dumped.\n" );
1148  kmkernel->stopAgentInstance();
1149  }
1150 }
1151 
1152 void KMKernel::init()
1153 {
1154  the_shuttingDown = false;
1155 
1156  the_firstStart = GlobalSettings::self()->firstStart();
1157  GlobalSettings::self()->setFirstStart( false );
1158  the_previousVersion = GlobalSettings::self()->previousVersion();
1159  GlobalSettings::self()->setPreviousVersion( QLatin1String(KDEPIM_VERSION) );
1160 
1161  readConfig();
1162 
1163  the_undoStack = new UndoStack(20);
1164 
1165  the_msgSender = new MessageComposer::AkonadiSender;
1166  readConfig();
1167  // filterMgr->dump();
1168 
1169  mBackgroundTasksTimer = new QTimer( this );
1170  mBackgroundTasksTimer->setSingleShot( true );
1171  connect( mBackgroundTasksTimer, SIGNAL(timeout()), this, SLOT(slotRunBackgroundTasks()) );
1172 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
1173  mBackgroundTasksTimer->start( 10000 ); // 10s, singleshot
1174 #else
1175  mBackgroundTasksTimer->start( 5 * 60000 ); // 5 minutes, singleshot
1176 #endif
1177 
1178  KCrash::setEmergencySaveFunction( kmCrashHandler );
1179 
1180  kDebug() << "KMail init with akonadi server state:" << int( Akonadi::ServerManager::state() );
1181  if( Akonadi::ServerManager::state() == Akonadi::ServerManager::Running ) {
1182  CommonKernel->initFolders();
1183  }
1184 
1185  connect( Akonadi::ServerManager::self(), SIGNAL(stateChanged(Akonadi::ServerManager::State)), this, SLOT(akonadiStateChanged(Akonadi::ServerManager::State)) );
1186  connect( folderCollectionMonitor(), SIGNAL(itemRemoved(Akonadi::Item)), the_undoStack, SLOT(msgDestroyed(Akonadi::Item)) );
1187 
1188 
1189 }
1190 
1191 void KMKernel::readConfig()
1192 {
1193  mWrapCol = MessageComposer::MessageComposerSettings::self()->lineWrapWidth();
1194  if ((mWrapCol == 0) || (mWrapCol > 78))
1195  mWrapCol = 78;
1196  else if (mWrapCol < 30)
1197  mWrapCol = 30;
1198 }
1199 
1200 
1201 bool KMKernel::doSessionManagement()
1202 {
1203 
1204  // Do session management
1205  if (kapp->isSessionRestored()){
1206  int n = 1;
1207  while (KMMainWin::canBeRestored(n)){
1208  //only restore main windows! (Matthias);
1209  if (KMMainWin::classNameOfToplevel(n) == QLatin1String("KMMainWin"))
1210  (new KMMainWin)->restoreDockedState(n);
1211  n++;
1212  }
1213  return true; // we were restored by SM
1214  }
1215  return false; // no, we were not restored
1216 }
1217 
1218 void KMKernel::closeAllKMailWindows()
1219 {
1220  QList<KMainWindow*> windowsToDelete;
1221 
1222  foreach ( KMainWindow* window, KMainWindow::memberList() ) {
1223  if ( ::qobject_cast<KMMainWin *>(window) ||
1224  ::qobject_cast<KMail::SecondaryWindow *>(window) )
1225  {
1226  // close and delete the window
1227  window->setAttribute(Qt::WA_DeleteOnClose);
1228  window->close();
1229  windowsToDelete.append( window );
1230  }
1231  }
1232 
1233  // We delete all main windows here. Above we called close(), but that calls
1234  // deleteLater() internally, therefore does not delete it immediately.
1235  // This would lead to problems when closing Kontact when a composer window
1236  // is open, because the destruction order is:
1237  //
1238  // 1. destructor of the Kontact mainwinow
1239  // 2. delete all parts
1240  // 3. the KMail part destructor calls KMKernel::cleanup(), which calls
1241  // this function
1242  // 4. delete all other mainwindows
1243  //
1244  // Deleting the composer windows here will make sure that step 4 will not delete
1245  // any composer window, which would fail because the kernel is already deleted.
1246  qDeleteAll( windowsToDelete );
1247  windowsToDelete.clear();
1248 }
1249 
1250 void KMKernel::cleanup(void)
1251 {
1252  disconnect( Akonadi::AgentManager::self(), SIGNAL(instanceStatusChanged(Akonadi::AgentInstance)));
1253  disconnect( Akonadi::AgentManager::self(), SIGNAL(instanceError(Akonadi::AgentInstance,QString)));
1254  disconnect( Akonadi::AgentManager::self(), SIGNAL(instanceWarning(Akonadi::AgentInstance,QString)));
1255  disconnect( Akonadi::AgentManager::self(), SIGNAL(instanceRemoved(Akonadi::AgentInstance)));
1256  disconnect ( Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)));
1257  disconnect( KPIM::ProgressManager::instance(), SIGNAL(progressItemCompleted(KPIM::ProgressItem*)));
1258  disconnect( KPIM::ProgressManager::instance(), SIGNAL(progressItemCanceled(KPIM::ProgressItem*)));
1259 
1260  dumpDeadLetters();
1261  the_shuttingDown = true;
1262  closeAllKMailWindows();
1263 
1264  // Flush the cache of foldercollection objects. This results
1265  // in configuration writes, so we need to do it early enough.
1266  MailCommon::FolderCollection::clearCache();
1267 
1268  // Write the config while all other managers are alive
1269  delete the_msgSender;
1270  the_msgSender = 0;
1271  delete the_undoStack;
1272  the_undoStack = 0;
1273 
1274  KSharedConfig::Ptr config = KMKernel::config();
1275  Akonadi::Collection trashCollection = CommonKernel->trashCollectionFolder();
1276  if ( trashCollection.isValid() ) {
1277  if ( GlobalSettings::self()->emptyTrashOnExit() ) {
1278  Akonadi::CollectionStatisticsJob *jobStatistics = new Akonadi::CollectionStatisticsJob( trashCollection );
1279  if ( jobStatistics->exec() ) {
1280  if ( jobStatistics->statistics().count() > 0 ) {
1281  mFolderCollectionMonitor->expunge( trashCollection, true /*sync*/ );
1282  }
1283  }
1284  }
1285  }
1286  delete mConfigureDialog;
1287  mConfigureDialog = 0;
1288  // do not delete, because mWin may point to an existing window
1289  // delete mWin;
1290  mWin = 0;
1291 
1292  if ( RecentAddresses::exists() )
1293  RecentAddresses::self( config.data() )->save( config.data() );
1294 }
1295 
1296 void KMKernel::dumpDeadLetters()
1297 {
1298  if ( shuttingDown() )
1299  return; //All documents should be saved before shutting down is set!
1300 
1301  // make all composer windows autosave their contents
1302  foreach ( KMainWindow* window, KMainWindow::memberList() ) {
1303  if ( KMail::Composer * win = ::qobject_cast<KMail::Composer*>( window ) ) {
1304  win->autoSaveMessage(true);
1305 
1306  while ( win->isComposing() ) {
1307  kWarning() << "Danger, using an event loop, this should no longer be happening!";
1308  qApp->processEvents();
1309  }
1310  }
1311  }
1312 }
1313 
1314 
1315 
1316 void KMKernel::action( bool mailto, bool check, const QString &to,
1317  const QString &cc, const QString &bcc,
1318  const QString &subj, const QString &body,
1319  const KUrl &messageFile,
1320  const KUrl::List &attachURLs,
1321  const QStringList &customHeaders,
1322  const QString &replyTo,
1323  const QString &inReplyTo)
1324 {
1325  if ( mailto ) {
1326  openComposer( to, cc, bcc, subj, body, 0,
1327  messageFile.pathOrUrl(), attachURLs.toStringList(),
1328  customHeaders, replyTo, inReplyTo );
1329  }
1330  else
1331  openReader( check );
1332 
1333  if ( check )
1334  checkMail();
1335  //Anything else?
1336 }
1337 
1338 void KMKernel::slotRequestConfigSync()
1339 {
1340  // ### FIXME: delay as promised in the kdoc of this function ;-)
1341  slotSyncConfig();
1342 }
1343 
1344 void KMKernel::slotSyncConfig()
1345 {
1346  MessageCore::GlobalSettings::self()->writeConfig();
1347  MessageViewer::GlobalSettings::self()->writeConfig();
1348  MessageComposer::MessageComposerSettings::self()->writeConfig();
1349  TemplateParser::GlobalSettings::self()->writeConfig();
1350  MessageList::Core::Settings::self()->writeConfig();
1351  MailCommon::MailCommonSettings::self()->writeConfig();
1352  GlobalSettings::self()->writeConfig();
1353  KMKernel::config()->sync();
1354 }
1355 
1356 void KMKernel::updateConfig()
1357 {
1358  slotConfigChanged();
1359 }
1360 
1361 void KMKernel::slotShowConfigurationDialog()
1362 {
1363  if( KMKernel::getKMMainWidget() == 0 ) {
1364  // ensure that there is a main widget available
1365  // as parts of the configure dialog (identity) rely on this
1366  // and this slot can be called when there is only a KMComposeWin showing
1367  KMMainWin *win = new KMMainWin;
1368  win->show();
1369 
1370  }
1371 
1372  if( !mConfigureDialog ) {
1373  mConfigureDialog = new ConfigureDialog( 0, false );
1374  mConfigureDialog->setObjectName( QLatin1String("configure") );
1375  connect( mConfigureDialog, SIGNAL(configChanged()),
1376  this, SLOT(slotConfigChanged()) );
1377  }
1378 
1379  // Save all current settings.
1380  if( getKMMainWidget() )
1381  getKMMainWidget()->writeReaderConfig();
1382 
1383  if( mConfigureDialog->isHidden() ) {
1384  mConfigureDialog->show();
1385  } else {
1386  mConfigureDialog->raise();
1387  }
1388 }
1389 
1390 void KMKernel::slotConfigChanged()
1391 {
1392  readConfig();
1393  CodecManager::self()->updatePreferredCharsets();
1394  emit configChanged();
1395 }
1396 
1397 //-------------------------------------------------------------------------------
1398 //static
1399 QString KMKernel::localDataPath()
1400 {
1401  return KStandardDirs::locateLocal( "data", QLatin1String("kmail2/") );
1402 }
1403 
1404 //-------------------------------------------------------------------------------
1405 
1406 bool KMKernel::haveSystemTrayApplet() const
1407 {
1408  return (mSystemTray!=0);
1409 }
1410 
1411 void KMKernel::updateSystemTray()
1412 {
1413  if ( mSystemTray && !the_shuttingDown ) {
1414  mSystemTray->updateSystemTray();
1415  }
1416 }
1417 
1418 KPIMIdentities::IdentityManager * KMKernel::identityManager() {
1419  if ( !mIdentityManager ) {
1420  kDebug();
1421  mIdentityManager = new KPIMIdentities::IdentityManager( false, this, "mIdentityManager" );
1422  }
1423  return mIdentityManager;
1424 }
1425 
1426 KMainWindow* KMKernel::mainWin()
1427 {
1428  // First look for a KMMainWin.
1429  foreach ( KMainWindow* window, KMainWindow::memberList() )
1430  if ( ::qobject_cast<KMMainWin *>(window) )
1431  return window;
1432 
1433  // There is no KMMainWin. Use any other KMainWindow instead (e.g. in
1434  // case we are running inside Kontact) because we anyway only need
1435  // it for modal message boxes and for KNotify events.
1436  if ( !KMainWindow::memberList().isEmpty() ) {
1437  KMainWindow *kmWin = KMainWindow::memberList().first();
1438  if ( kmWin )
1439  return kmWin;
1440  }
1441 
1442  // There's not a single KMainWindow. Create a KMMainWin.
1443  // This could happen if we want to pop up an error message
1444  // while we are still doing the startup wizard and no other
1445  // KMainWindow is running.
1446  mWin = new KMMainWin;
1447  return mWin;
1448 }
1449 
1450 
1451 KMKernel* KMKernel::self()
1452 {
1453  return mySelf;
1454 }
1455 
1456 KSharedConfig::Ptr KMKernel::config()
1457 {
1458  assert( mySelf );
1459  if ( !mySelf->mConfig )
1460  {
1461  mySelf->mConfig = KSharedConfig::openConfig( QLatin1String("kmail2rc") );
1462  // Check that all updates have been run on the config file:
1463  KMail::checkConfigUpdates();
1464  MessageList::Core::Settings::self()->setSharedConfig( mySelf->mConfig );
1465  MessageList::Core::Settings::self()->readConfig();
1466  TemplateParser::GlobalSettings::self()->setSharedConfig( mySelf->mConfig );
1467  TemplateParser::GlobalSettings::self()->readConfig();
1468  MessageComposer::MessageComposerSettings::self()->setSharedConfig( mySelf->mConfig );
1469  MessageComposer::MessageComposerSettings::self()->readConfig();
1470  MessageCore::GlobalSettings::self()->setSharedConfig( mySelf->mConfig );
1471  MessageCore::GlobalSettings::self()->readConfig();
1472  MessageViewer::GlobalSettings::self()->setSharedConfig( mySelf->mConfig );
1473  MessageViewer::GlobalSettings::self()->readConfig();
1474  MailCommon::MailCommonSettings::self()->setSharedConfig( mySelf->mConfig );
1475  MailCommon::MailCommonSettings::self()->readConfig();
1476  }
1477  return mySelf->mConfig;
1478 }
1479 
1480 void KMKernel::syncConfig()
1481 {
1482  slotRequestConfigSync();
1483 }
1484 
1485 
1486 void KMKernel::selectCollectionFromId( const Akonadi::Collection::Id id)
1487 {
1488  KMMainWidget *widget = getKMMainWidget();
1489  Q_ASSERT( widget );
1490  if ( !widget )
1491  return;
1492 
1493  Akonadi::Collection colFolder = CommonKernel->collectionFromId( id );
1494 
1495  if( colFolder.isValid() )
1496  widget->slotSelectCollectionFolder( colFolder );
1497 }
1498 
1499 bool KMKernel::selectFolder( const QString &folder )
1500 {
1501  KMMainWidget *widget = getKMMainWidget();
1502  Q_ASSERT( widget );
1503  if ( !widget )
1504  return false;
1505 
1506  const Akonadi::Collection colFolder = CommonKernel->collectionFromId( folder.toLongLong() );
1507 
1508  if( colFolder.isValid() ) {
1509  widget->slotSelectCollectionFolder( colFolder );
1510  return true;
1511  }
1512  return false;
1513 }
1514 
1515 KMMainWidget *KMKernel::getKMMainWidget()
1516 {
1517  //This could definitely use a speadup
1518  QWidgetList l = QApplication::topLevelWidgets();
1519  QWidget *wid;
1520 
1521  Q_FOREACH( wid, l ) {
1522  QList<KMMainWidget*> l2 = wid->window()->findChildren<KMMainWidget*>();
1523  if ( !l2.isEmpty() && l2.first() )
1524  return l2.first();
1525  }
1526  return 0;
1527 }
1528 
1529 void KMKernel::slotRunBackgroundTasks() // called regularly by timer
1530 {
1531  // Hidden KConfig keys. Not meant to be used, but a nice fallback in case
1532  // a stable kmail release goes out with a nasty bug in CompactionJob...
1533  if ( GlobalSettings::self()->autoExpiring() ) {
1534  mFolderCollectionMonitor->expireAllFolders( false /*scheduled, not immediate*/, entityTreeModel() );
1535  }
1536 
1537 #ifdef DEBUG_SCHEDULER // for debugging, see jobscheduler.h
1538  mBackgroundTasksTimer->start( 60 * 1000 ); // check again in 1 minute
1539 #else
1540  mBackgroundTasksTimer->start( 4 * 60 * 60 * 1000 ); // check again in 4 hours
1541 #endif
1542 
1543 }
1544 
1545 static Akonadi::Collection::List collect_collections( const QAbstractItemModel *model,
1546  const QModelIndex &parent )
1547 {
1548  Akonadi::Collection::List collections;
1549  const int numberOfCollection( model->rowCount( parent ) );
1550  for ( int i = 0; i < numberOfCollection; ++i ) {
1551  const QModelIndex child = model->index( i, 0, parent );
1552  Akonadi::Collection collection =
1553  model->data( child, Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
1554  if ( collection.isValid() ) {
1555  collections << collection;
1556  }
1557  collections += collect_collections( model, child );
1558  }
1559  return collections;
1560 }
1561 
1562 Akonadi::Collection::List KMKernel::allFolders() const
1563 {
1564  return collect_collections( collectionModel(), QModelIndex() );
1565 }
1566 
1567 void KMKernel::expireAllFoldersNow() // called by the GUI
1568 {
1569  mFolderCollectionMonitor->expireAllFolders( true /*immediate*/, entityTreeModel() );
1570 }
1571 
1572 bool KMKernel::canQueryClose()
1573 {
1574  if ( KMMainWidget::mainWidgetList() &&
1575  KMMainWidget::mainWidgetList()->count() > 1 )
1576  return true;
1577  if ( !mSystemTray || GlobalSettings::closeDespiteSystemTray() )
1578  return true;
1579  if ( mSystemTray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowAlways ) {
1580  mSystemTray->hideKMail();
1581  return false;
1582  } else if ( ( mSystemTray->mode() == GlobalSettings::EnumSystemTrayPolicy::ShowOnUnread ) ) {
1583  if( mSystemTray->hasUnreadMail() )
1584  mSystemTray->setStatus( KStatusNotifierItem::Active );
1585  mSystemTray->hideKMail();
1586  return false;
1587  }
1588  return true;
1589 }
1590 
1591 QSharedPointer<FolderCollection> KMKernel::currentFolderCollection()
1592 {
1593  KMMainWidget *widget = getKMMainWidget();
1594  QSharedPointer<FolderCollection> folder;
1595  if ( widget ) {
1596  folder = widget->currentFolder();
1597  }
1598  return folder;
1599 }
1600 
1601 // can't be inline, since KMSender isn't known to implement
1602 // KMail::MessageSender outside this .cpp file
1603 MessageComposer::MessageSender * KMKernel::msgSender()
1604 {
1605  return the_msgSender;
1606 }
1607 
1608 void KMKernel::transportRemoved(int id, const QString & name)
1609 {
1610  Q_UNUSED( id );
1611 
1612  // reset all identities using the deleted transport
1613  QStringList changedIdents;
1614  KPIMIdentities::IdentityManager * im = identityManager();
1615  KPIMIdentities::IdentityManager::Iterator end = im->modifyEnd();
1616  for ( KPIMIdentities::IdentityManager::Iterator it = im->modifyBegin(); it != end; ++it ) {
1617  if ( name == (*it).transport() ) {
1618  (*it).setTransport( QString() );
1619  changedIdents += (*it).identityName();
1620  }
1621  }
1622 
1623  // if the deleted transport is the currently used transport reset it to default
1624  const QString& currentTransport = GlobalSettings::self()->currentTransport();
1625  if ( name == currentTransport )
1626  GlobalSettings::self()->setCurrentTransport( QString() );
1627 
1628  if ( !changedIdents.isEmpty() ) {
1629  QString information = i18np( "This identity has been changed to use the default transport:",
1630  "These %1 identities have been changed to use the default transport:",
1631  changedIdents.count() );
1632  //Don't set parent otherwise we will swith to current KMail and we configure it. So not good
1633  KMessageBox::informationList( 0, information, changedIdents );
1634  im->commit();
1635  }
1636 }
1637 
1638 void KMKernel::transportRenamed(int id, const QString & oldName, const QString & newName)
1639 {
1640  Q_UNUSED( id );
1641 
1642  QStringList changedIdents;
1643  KPIMIdentities::IdentityManager * im = identityManager();
1644  KPIMIdentities::IdentityManager::Iterator end = im->modifyEnd();
1645  for ( KPIMIdentities::IdentityManager::Iterator it = im->modifyBegin(); it != end; ++it ) {
1646  if ( oldName == (*it).transport() ) {
1647  (*it).setTransport( newName );
1648  changedIdents << (*it).identityName();
1649  }
1650  }
1651 
1652  if ( !changedIdents.isEmpty() ) {
1653  const QString information =
1654  i18np( "This identity has been changed to use the modified transport:",
1655  "These %1 identities have been changed to use the modified transport:",
1656  changedIdents.count() );
1657  //Don't set parent otherwise we will swith to current KMail and we configure it. So not good
1658  KMessageBox::informationList( 0, information, changedIdents );
1659  im->commit();
1660  }
1661 }
1662 
1663 void KMKernel::itemDispatchStarted()
1664 {
1665  // Watch progress of the MDA.
1666  KPIM::ProgressManager::createProgressItem( 0,
1667  MailTransport::DispatcherInterface().dispatcherInstance(),
1668  QString::fromLatin1( "Sender" ),
1669  i18n( "Sending messages" ),
1670  i18n( "Initiating sending process..." ),
1671  true );
1672 }
1673 
1674 void KMKernel::instanceStatusChanged( const Akonadi::AgentInstance &instance )
1675 {
1676  if (instance.identifier() == QLatin1String( "akonadi_mailfilter_agent" ) ) {
1677  // Creating a progress item twice is ok, it will simply return the already existing
1678  // item
1679  KPIM::ProgressItem *progress = KPIM::ProgressManager::createProgressItem( 0, instance,
1680  instance.identifier(), instance.name(), instance.statusMessage(),
1681  false, true );
1682  progress->setProperty( "AgentIdentifier", instance.identifier() );
1683  return;
1684  }
1685  if ( MailCommon::Util::agentInstances(true).contains( instance ) ) {
1686  if ( instance.status() == Akonadi::AgentInstance::Running ) {
1687 
1688  if ( mResourcesBeingChecked.isEmpty() ) {
1689  kDebug() << "A Resource started to synchronize, starting a mail check.";
1690  emit startCheckMail();
1691  }
1692 
1693  const QString identifier(instance.identifier());
1694  if ( !mResourcesBeingChecked.contains( identifier ) ) {
1695  mResourcesBeingChecked.append( identifier );
1696  }
1697 
1698  bool useCrypto = false;
1699  if(mResourceCryptoSettingCache.contains(identifier)) {
1700  useCrypto = mResourceCryptoSettingCache.value(identifier);
1701  } else {
1702  if ( identifier.contains( IMAP_RESOURCE_IDENTIFIER ) ) {
1703  OrgKdeAkonadiImapSettingsInterface *iface = PimCommon::Util::createImapSettingsInterface( identifier );
1704  if ( iface->isValid() ) {
1705  const QString imapSafety = iface->safety();
1706  useCrypto = ( imapSafety == QLatin1String( "SSL" ) || imapSafety == QLatin1String( "STARTTLS" ) );
1707  mResourceCryptoSettingCache.insert(identifier,useCrypto);
1708  }
1709  delete iface;
1710  } else if ( identifier.contains( POP3_RESOURCE_IDENTIFIER ) ) {
1711  OrgKdeAkonadiPOP3SettingsInterface *iface = MailCommon::Util::createPop3SettingsInterface( identifier );
1712  if ( iface->isValid() ) {
1713  useCrypto = ( iface->useSSL() || iface->useTLS() );
1714  mResourceCryptoSettingCache.insert(identifier,useCrypto);
1715  }
1716  delete iface;
1717  }
1718  }
1719 
1720 
1721  // Creating a progress item twice is ok, it will simply return the already existing
1722  // item
1723  KPIM::ProgressItem *progress = KPIM::ProgressManager::createProgressItem( 0, instance,
1724  instance.identifier(), instance.name(), instance.statusMessage(),
1725  true, useCrypto );
1726  progress->setProperty( "AgentIdentifier", instance.identifier() );
1727  } else if ( instance.status() == Akonadi::AgentInstance::Broken ) {
1728  agentInstanceBroken( instance );
1729  }
1730  }
1731 }
1732 
1733 void KMKernel::agentInstanceBroken( const Akonadi::AgentInstance &instance )
1734 {
1735  const QString summary = i18n( "Resource %1 is broken. This resource is now %2", instance.name(), instance.isOnline() ? i18n( "online" ) : i18n( "offline" ) );
1736  if( xmlGuiInstance().isValid() ) {
1737  KNotification::event( QLatin1String("akonadi-resource-broken"),
1738  summary,
1739  QPixmap(),
1740  0,
1741  KNotification::CloseOnTimeout,
1742  xmlGuiInstance() );
1743  } else {
1744  KNotification::event( QLatin1String("akonadi-resource-broken"),
1745  summary,
1746  QPixmap(),
1747  0,
1748  KNotification::CloseOnTimeout );
1749  }
1750 
1751 }
1752 
1753 void KMKernel::slotProgressItemCompletedOrCanceled( KPIM::ProgressItem *item )
1754 {
1755  const QString identifier = item->property( "AgentIdentifier" ).toString();
1756  const Akonadi::AgentInstance agent = Akonadi::AgentManager::self()->instance( identifier );
1757  if ( agent.isValid() ) {
1758  mResourcesBeingChecked.removeAll( identifier );
1759  if ( mResourcesBeingChecked.isEmpty() ) {
1760  kDebug() << "Last resource finished syncing, mail check done";
1761  emit endCheckMail();
1762  }
1763  }
1764 }
1765 
1766 void KMKernel::updatedTemplates()
1767 {
1768  emit customTemplatesChanged();
1769 }
1770 
1771 
1772 bool KMKernel::isImapFolder( const Akonadi::Collection &col, bool &isOnline ) const
1773 {
1774  const Akonadi::AgentInstance agentInstance = Akonadi::AgentManager::self()->instance( col.resource() );
1775  isOnline = agentInstance.isOnline();
1776 
1777  return (agentInstance.type().identifier() == IMAP_RESOURCE_IDENTIFIER);
1778 }
1779 
1780 
1781 void KMKernel::stopAgentInstance()
1782 {
1783  const QString resourceGroupPattern( QLatin1String("Resource %1") );
1784 
1785  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
1786  foreach( Akonadi::AgentInstance type, lst ) {
1787  KConfigGroup group( KMKernel::config(), resourceGroupPattern.arg( type.identifier() ) );
1788 
1789  // "false" is also hardcoded in ConfigureDialog, don't forget to change there.
1790  if ( group.readEntry( "OfflineOnShutdown", false ) )
1791  type.setIsOnline( false );
1792  }
1793 }
1794 
1795 void KMKernel::slotCollectionRemoved(const Akonadi::Collection &col)
1796 {
1797  KConfigGroup group( KMKernel::config(), MailCommon::FolderCollection::configGroupName( col ) );
1798  group.deleteGroup();
1799  group.sync();
1800  const QString colStr = QString::number( col.id() );
1801  TemplateParser::Util::deleteTemplate( colStr );
1802  MessageList::Util::deleteConfig( colStr );
1803 }
1804 
1805 void KMKernel::slotDeleteIdentity( uint identity)
1806 {
1807  TemplateParser::Util::deleteTemplate( QString::fromLatin1( "IDENTITY_%1" ).arg( identity ) );
1808 }
1809 
1810 void KMKernel::slotCollectionMoved( const Akonadi::Collection &collection, const Akonadi::Collection &source, const Akonadi::Collection &destination )
1811 {
1812  //TODO add undo/redo move collection
1813 }
1814 
1815 bool KMKernel::showPopupAfterDnD()
1816 {
1817  return GlobalSettings::self()->showPopupAfterDnD();
1818 }
1819 
1820 bool KMKernel::excludeImportantMailFromExpiry()
1821 {
1822  return GlobalSettings::self()->excludeImportantMailFromExpiry();
1823 }
1824 
1825 qreal KMKernel::closeToQuotaThreshold()
1826 {
1827  return GlobalSettings::self()->closeToQuotaThreshold();
1828 }
1829 
1830 Akonadi::Entity::Id KMKernel::lastSelectedFolder()
1831 {
1832  return GlobalSettings::self()->lastSelectedFolder();
1833 }
1834 
1835 void KMKernel::setLastSelectedFolder(const Akonadi::Entity::Id& col)
1836 {
1837  GlobalSettings::self()->setLastSelectedFolder( col );
1838 }
1839 
1840 QStringList KMKernel::customTemplates()
1841 {
1842  return GlobalSettingsBase::self()->customTemplates();
1843 }
1844 
1845 void KMKernel::openFilterDialog(bool createDummyFilter)
1846 {
1847  if ( !mFilterEditDialog ) {
1848  mFilterEditDialog = new MailCommon::KMFilterDialog( getKMMainWidget()->actionCollections(), 0, createDummyFilter );
1849  mFilterEditDialog->setObjectName( QLatin1String("filterdialog") );
1850  }
1851  mFilterEditDialog->show();
1852  mFilterEditDialog->raise();
1853  mFilterEditDialog->activateWindow();
1854 }
1855 
1856 void KMKernel::createFilter(const QByteArray& field, const QString& value)
1857 {
1858  mFilterEditDialog->createFilter( field, value );
1859 
1860 }
1861 
1862 
1863 void KMKernel::checkFolderFromResources( const Akonadi::Collection::List &collectionList )
1864 {
1865  const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
1866  foreach( const Akonadi::AgentInstance& type, lst ) {
1867  if ( type.status() == Akonadi::AgentInstance::Broken )
1868  continue;
1869  if ( type.identifier().contains( IMAP_RESOURCE_IDENTIFIER ) ) {
1870  OrgKdeAkonadiImapSettingsInterface *iface = PimCommon::Util::createImapSettingsInterface( type.identifier() );
1871  if ( iface->isValid() ) {
1872  foreach( const Akonadi::Collection& collection, collectionList ) {
1873  const Akonadi::Collection::Id collectionId = collection.id();
1874  if ( iface->trashCollection() == collectionId ) {
1875  //Use default trash
1876  iface->setTrashCollection( CommonKernel->trashCollectionFolder().id() );
1877  iface->writeConfig();
1878  break;
1879  }
1880  }
1881  }
1882  delete iface;
1883  }
1884  else if ( type.identifier().contains( POP3_RESOURCE_IDENTIFIER ) ) {
1885  OrgKdeAkonadiPOP3SettingsInterface *iface = MailCommon::Util::createPop3SettingsInterface( type.identifier() );
1886  if ( iface->isValid() ) {
1887  foreach( const Akonadi::Collection& collection, collectionList ) {
1888  const Akonadi::Collection::Id collectionId = collection.id();
1889  if ( iface->targetCollection() == collectionId ) {
1890  //Use default inbox
1891  iface->setTargetCollection( CommonKernel->inboxCollectionFolder().id() );
1892  iface->writeConfig();
1893  break;
1894  }
1895  }
1896  }
1897  delete iface;
1898  }
1899  }
1900 }
1901 
1902 const QAbstractItemModel* KMKernel::treeviewModelSelection()
1903 {
1904  if ( getKMMainWidget() )
1905  return getKMMainWidget()->folderTreeView()->selectionModel()->model();
1906  else
1907  return entityTreeModel();
1908 }
1909 
1910 void KMKernel::slotInstanceWarning(const Akonadi::AgentInstance &instance , const QString &message)
1911 {
1912  const QString summary = i18nc( "<source>: <error message>", "%1: %2", instance.name(), message );
1913  if( xmlGuiInstance().isValid() ) {
1914  KNotification::event( QLatin1String("akonadi-instance-warning"),
1915  summary,
1916  QPixmap(),
1917  0,
1918  KNotification::CloseOnTimeout,
1919  xmlGuiInstance() );
1920  } else {
1921  KNotification::event( QLatin1String("akonadi-instance-warning"),
1922  summary,
1923  QPixmap(),
1924  0,
1925  KNotification::CloseOnTimeout );
1926  }
1927 }
1928 
1929 void KMKernel::slotInstanceError(const Akonadi::AgentInstance &instance, const QString &message)
1930 {
1931  const QString summary = i18nc( "<source>: <error message>", "%1: %2", instance.name(), message );
1932  if( xmlGuiInstance().isValid() ) {
1933  KNotification::event( QLatin1String("akonadi-instance-error"),
1934  summary,
1935  QPixmap(),
1936  0,
1937  KNotification::CloseOnTimeout,
1938  xmlGuiInstance() );
1939  } else {
1940  KNotification::event( QLatin1String("akonadi-instance-error"),
1941  summary,
1942  QPixmap(),
1943  0,
1944  KNotification::CloseOnTimeout );
1945  }
1946 }
1947 
1948 
1949 void KMKernel::slotInstanceRemoved(const Akonadi::AgentInstance& instance)
1950 {
1951  const QString identifier(instance.identifier());
1952  const QString resourceGroup = QString::fromLatin1( "Resource %1" ).arg( identifier );
1953  if ( KMKernel::config()->hasGroup( resourceGroup ) ) {
1954  KConfigGroup group( KMKernel::config(), resourceGroup );
1955  group.deleteGroup();
1956  group.sync();
1957  }
1958  if(mResourceCryptoSettingCache.contains(identifier)) {
1959  mResourceCryptoSettingCache.remove(identifier);
1960  }
1961 }
1962 
1963 void KMKernel::savePaneSelection()
1964 {
1965  KMMainWidget *widget = getKMMainWidget();
1966  if ( widget ) {
1967  widget->savePaneSelection();
1968  }
1969 }
1970 
1971 void KMKernel::updatePaneTagComboBox()
1972 {
1973  KMMainWidget *widget = getKMMainWidget();
1974  if ( widget ) {
1975  widget->updatePaneTagComboBox();
1976  }
1977 }
1978 
1979 void KMKernel::resourceGoOnLine()
1980 {
1981  KMMainWidget *widget = getKMMainWidget();
1982  if ( widget ) {
1983  if(widget->currentFolder()) {
1984  Akonadi::Collection collection = widget->currentFolder()->collection();
1985  Akonadi::AgentInstance instance = Akonadi::AgentManager::self()->instance( collection.resource() );
1986  instance.setIsOnline( true );
1987  widget->clearViewer();
1988  }
1989  }
1990 }
1991 
1992 void KMKernel::makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode)
1993 {
1994  switch(mode) {
1995  case MessageViewer::Viewer::AllResources:
1996  resumeNetworkJobs();
1997  break;
1998  case MessageViewer::Viewer::SelectedResource:
1999  resourceGoOnLine();
2000  break;
2001  }
2002 }
2003 
2004 MessageComposer::ComposerAutoCorrection* KMKernel::composerAutoCorrection()
2005 {
2006  return mAutoCorrection;
2007 }
2008 
2009 void KMKernel::toggleSystemTray()
2010 {
2011  KMMainWidget *widget = getKMMainWidget();
2012  if ( widget ) {
2013  if ( !mSystemTray && GlobalSettings::self()->systemTrayEnabled() ) {
2014  mSystemTray = new KMail::KMSystemTray(widget);
2015  } else if ( mSystemTray && !GlobalSettings::self()->systemTrayEnabled() ) {
2016  // Get rid of system tray on user's request
2017  kDebug() << "deleting systray";
2018  delete mSystemTray;
2019  mSystemTray = 0;
2020  }
2021 
2022  // Set mode of systemtray. If mode has changed, tray will handle this.
2023  if ( mSystemTray ) {
2024  mSystemTray->setMode( GlobalSettings::self()->systemTrayPolicy() );
2025  mSystemTray->setShowUnreadCount( GlobalSettings::self()->systemTrayShowUnread() );
2026  }
2027 
2028  }
2029 }
2030 
2031 void KMKernel::showFolder(const QString &collectionId)
2032 {
2033  if (!collectionId.isEmpty()) {
2034  const Akonadi::Collection::Id id = collectionId.toLongLong();
2035  selectCollectionFromId(id);
2036  }
2037 }
2038 
2039 void KMKernel::slotCollectionChanged(const Akonadi::Collection &, const QSet<QByteArray> &set)
2040 {
2041  if(set.contains("newmailnotifierattribute")) {
2042  if ( mSystemTray ) {
2043  mSystemTray->updateSystemTray();
2044  }
2045  }
2046 }
2047 
2048 #include "kmkernel.moc"
CodecManager::updatePreferredCharsets
void updatePreferredCharsets()
Re-read the preferred charsets from settings.
Definition: codecmanager.cpp:81
KMail::Composer::setFocusToSubject
virtual void setFocusToSubject()=0
Sets the focus to the subject line edit.
KMKernel::KMKernel
KMKernel(QObject *parent=0, const char *name=0)
Definition: kmkernel.cpp:124
KMKernel::accounts
Q_SCRIPTABLE QStringList accounts()
Definition: kmkernel.cpp:470
KMKernel::init
void init()
Definition: kmkernel.cpp:1152
KMKernel::createFilter
void createFilter(const QByteArray &field, const QString &value)
Definition: kmkernel.cpp:1856
s_askingToGoOnline
static bool s_askingToGoOnline
Definition: kmkernel.cpp:119
KMail::Util::migrateFromKMail1
void migrateFromKMail1()
Definition: util.cpp:237
KMKernel::viewMessage
Q_SCRIPTABLE int viewMessage(const QString &messageFile)
Definition: kmkernel.cpp:834
globalsettings.h
KPIM::ProgressManager::instance
static ProgressManager * instance()
KMKernel::setSystrayIconNotificationsEnabled
Q_SCRIPTABLE void setSystrayIconNotificationsEnabled(bool enabled)
Enables/disables systray icon changing when mail arrives.
Definition: kmkernel.cpp:463
QSharedPointer
Definition: collectionmailinglistpage.h:34
KPIM::ProgressManager::createProgressItem
static ProgressItem * createProgressItem(const QString &label)
KMail::Composer::disableForgottenAttachmentsCheck
virtual void disableForgottenAttachmentsCheck()=0
KMail::Composer::addExtraCustomHeaders
virtual void addExtraCustomHeaders(const QMap< QByteArray, QString > &header)=0
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:137
KMKernel::stopNetworkJobs
Q_SCRIPTABLE void stopNetworkJobs()
Stops all network related jobs and enter offline mode New network jobs cannot be started.
Definition: kmkernel.cpp:899
KMKernel::slotShowConfigurationDialog
void slotShowConfigurationDialog()
Definition: kmkernel.cpp:1361
KMail::KMSystemTray::updateSystemTray
void updateSystemTray()
Definition: kmsystemtray.cpp:417
makeAbsoluteUrl
static KUrl makeAbsoluteUrl(const QString &str)
Definition: kmkernel.cpp:273
kmmainwidget.h
KMail::Composer::setAutoSaveFileName
virtual void setAutoSaveFileName(const QString &fileName)=0
KMMainWin
Definition: kmmainwin.h:34
KMKernel::composerAutoCorrection
MessageComposer::ComposerAutoCorrection * composerAutoCorrection()
Definition: kmkernel.cpp:2004
KMail::Composer::NoTemplate
Definition: composer.h:44
KMKernel::openComposer
Q_SCRIPTABLE int openComposer(const QString &to, const QString &cc, const QString &bcc, const QString &subject, const QString &body, bool hidden, const QString &messageFile, const QStringList &attachmentPaths, const QStringList &customHeaders, const QString &replyTo=QString(), const QString &inReplyTo=QString())
Opens a composer window and prefills it with different message parts.
Definition: kmkernel.cpp:534
KMKernel
Central point of coordination in KMail.
Definition: kmkernel.h:103
KMKernel::openReader
Q_SCRIPTABLE void openReader()
Definition: kmkernel.h:119
KMKernel::slotConfigChanged
void slotConfigChanged()
Definition: kmkernel.cpp:1390
KMKernel::isImapFolder
bool isImapFolder(const Akonadi::Collection &, bool &isOnline) const
Definition: kmkernel.cpp:1772
QWidget
KMKernel::newMessage
Q_SCRIPTABLE QDBusObjectPath newMessage(const QString &to, const QString &cc, const QString &bcc, bool hidden, bool useFolderId, const QString &messageFile, const QString &attachURL)
Opens a composer window and prefills it with different message parts.
Definition: kmkernel.cpp:788
KMKernel::updatedTemplates
void updatedTemplates()
Custom templates have changed, so all windows using them need to regenerate their menus...
Definition: kmkernel.cpp:1766
KMail::Composer::disableWordWrap
virtual void disableWordWrap()=0
KMMainWidget::writeReaderConfig
void writeReaderConfig()
Definition: kmmainwidget.cpp:921
configuredialog.h
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.
KMKernel::action
void action(bool mailto, bool check, const QString &to, const QString &cc, const QString &bcc, const QString &subj, const QString &body, const KUrl &messageFile, const KUrl::List &attach, const QStringList &customHeaders, const QString &replyTo, const QString &inReplyTo)
Definition: kmkernel.cpp:1316
KMKernel::cleanup
void cleanup(void)
Definition: kmkernel.cpp:1250
KMail::KMSystemTray::setSystrayIconNotificationsEnabled
void setSystrayIconNotificationsEnabled(bool enable)
Use this method to disable any systray icon changing.
Definition: kmsystemtray.cpp:233
KMKernel::collectionModel
Akonadi::EntityMimeTypeFilterModel * collectionModel() const
Returns a model of all folders in KMail.
Definition: kmkernel.cpp:261
kmmainwin.h
undostack.h
KMMainWidget::currentFolder
QSharedPointer< MailCommon::FolderCollection > currentFolder() const
Definition: kmmainwidget.cpp:4394
KMKernel::raise
void raise()
Definition: kmkernel.cpp:842
KMKernel::folderCollectionMonitor
Akonadi::ChangeRecorder * folderCollectionMonitor() const
Definition: kmkernel.cpp:251
KMKernel::xmlGuiInstance
const KComponentData & xmlGuiInstance()
Definition: kmkernel.h:347
KMail::KMSystemTray
Definition: kmsystemtray.h:35
QObject
KMKernel::customTemplatesChanged
void customTemplatesChanged()
KMail::Composer
Definition: composer.h:37
KMKernel::toggleSystemTray
void toggleSystemTray()
Definition: kmkernel.cpp:2009
KMKernel::self
static KMKernel * self()
normal control stuff
Definition: kmkernel.cpp:1451
kmreaderwin.h
KMKernel::config
KSharedConfig::Ptr config()
Definition: kmkernel.cpp:1456
KMKernel::savePaneSelection
void savePaneSelection()
Definition: kmkernel.cpp:1963
KMMainWidget::folderTreeView
MailCommon::FolderTreeView * folderTreeView() const
Definition: kmmainwidget.h:140
KMKernel::showPopupAfterDnD
bool showPopupAfterDnD()
Definition: kmkernel.cpp:1815
KMKernel::selectCollectionFromId
void selectCollectionFromId(const Akonadi::Collection::Id id)
Definition: kmkernel.cpp:1486
KMKernel::startCheckMail
void startCheckMail()
KMKernel::updatePaneTagComboBox
void updatePaneTagComboBox()
Definition: kmkernel.cpp:1971
KMail::Composer::addAttachment
virtual void addAttachment(const KUrl &url, const QString &comment)=0
KMail::KMSystemTray::mode
int mode() const
Definition: kmsystemtray.cpp:174
KMKernel::resumeNetworkJobs
Q_SCRIPTABLE void resumeNetworkJobs()
Resumes all network related jobs and enter online mode New network jobs can be started.
Definition: kmkernel.cpp:931
KMKernel::treeviewModelSelection
const QAbstractItemModel * treeviewModelSelection()
Definition: kmkernel.cpp:1902
KMail::Composer::addAttach
virtual void addAttach(KMime::Content *msgPart)=0
Add an attachment to the list.
KMKernel::makeResourceOnline
Q_SCRIPTABLE void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode)
Definition: kmkernel.cpp:1992
KMMainWidget::updatePaneTagComboBox
void updatePaneTagComboBox()
Definition: kmmainwidget.cpp:4825
progressmanager.h
KMCommand::start
void start()
Definition: kmcommands.cpp:234
KMKernel::checkAccount
Q_SCRIPTABLE void checkAccount(const QString &account)
Checks the account with the specified name for new mail.
Definition: kmkernel.cpp:483
to
QString to() const
subject
QString subject() const
KMKernel::selectFolder
Q_SCRIPTABLE bool selectFolder(const QString &folder)
Definition: kmkernel.cpp:1499
kmsystemtray.h
KMKernel::endCheckMail
void endCheckMail()
KMMainWidget::savePaneSelection
void savePaneSelection()
Definition: kmmainwidget.cpp:4788
KMKernel::checkMailOnStartup
void checkMailOnStartup()
End of D-Bus callable stuff.
Definition: kmkernel.cpp:964
KMKernel::recoverDeadLetters
void recoverDeadLetters()
Definition: kmkernel.cpp:1094
KMMainWidget
Definition: kmmainwidget.h:83
KMKernel::updateConfig
Q_SCRIPTABLE void updateConfig()
Definition: kmkernel.cpp:1356
KMKernel::checkMail
Q_SCRIPTABLE void checkMail()
Start of D-Bus callable stuff.
Definition: kmkernel.cpp:436
KMKernel::showMail
Q_SCRIPTABLE bool showMail(quint32 serialNumber, const QString &messageId)
Definition: kmkernel.cpp:857
KMail::Composer::setCurrentReplyTo
virtual void setCurrentReplyTo(const QString &replyTo)=0
util.h
KMKernel::slotRunBackgroundTasks
void slotRunBackgroundTasks()
Definition: kmkernel.cpp:1529
KMKernel::isOffline
static bool isOffline()
Checks if the current network state is online or offline.
Definition: kmkernel.cpp:952
KMKernel::slotRequestConfigSync
void slotRequestConfigSync()
Call this slot instead of directly KConfig::sync() to minimize the overall config writes...
Definition: kmkernel.cpp:1338
kmkernel
#define kmkernel
Definition: kmkernel.h:22
KMMainWidget::mainWidgetList
static const PtrList * mainWidgetList()
Returns a list of all KMMainWidgets.
Definition: kmmainwidget.cpp:4384
KMKernel::setAccountStatus
void setAccountStatus(bool)
Definition: kmkernel.cpp:912
ConfigureDialog
Definition: configuredialog.h:29
KMKernel::excludeImportantMailFromExpiry
bool excludeImportantMailFromExpiry()
Definition: kmkernel.cpp:1820
KMKernel::haveSystemTrayApplet
bool haveSystemTrayApplet() const
Returns true if we have a system tray applet.
Definition: kmkernel.cpp:1406
codecmanager.h
KMail::KMSystemTray::hasUnreadMail
bool hasUnreadMail() const
Definition: kmsystemtray.cpp:400
KMKernel::configChanged
void configChanged()
KMOpenMsgCommand
Definition: kmcommands.h:267
KMail::Composer::setSigningAndEncryptionDisabled
virtual void setSigningAndEncryptionDisabled(bool v)=0
Disabled signing and encryption completely for this composer window.
KMKernel::syncConfig
void syncConfig()
Definition: kmkernel.cpp:1480
KMKernel::readConfig
void readConfig()
Definition: kmkernel.cpp:1191
KMMainWidget::slotSelectCollectionFolder
void slotSelectCollectionFolder(const Akonadi::Collection &col)
Definition: kmmainwidget.cpp:2294
KMKernel::shuttingDown
bool shuttingDown() const
Definition: kmkernel.h:372
KMail::KMSystemTray::setMode
void setMode(int mode)
Definition: kmsystemtray.cpp:154
mySelf
static KMKernel * mySelf
Definition: kmkernel.cpp:118
set
void set(quint32, const QString &, const QString &, const QString &, const QString &, time_t)
GlobalSettings::self
static GlobalSettings * self()
Definition: globalsettings.cpp:30
kmkernel.h
KMKernel::askToGoOnline
static bool askToGoOnline()
A static helper function that asks the user if they want to go online.
Definition: kmkernel.cpp:988
KPIM::BroadcastStatus
KMail::MailServiceImpl
Definition: mailserviceimpl.h:41
KMKernel::showFolder
Q_SCRIPTABLE void showFolder(const QString &collectionId)
Definition: kmkernel.cpp:2031
KMail::Composer::dbusObjectPath
virtual QString dbusObjectPath() const =0
KMail::Composer::TemplateContext
TemplateContext
Definition: composer.h:44
KMKernel::setupDBus
void setupDBus()
Definition: kmkernel.cpp:266
KMKernel::agentInstanceBroken
void agentInstanceBroken(const Akonadi::AgentInstance &instance)
Definition: kmkernel.cpp:1733
KMKernel::entityTreeModel
Akonadi::EntityTreeModel * entityTreeModel() const
Returns the main model, which contains all folders and the items of recently opened folders...
Definition: kmkernel.cpp:256
KMail::UndoStack
Definition: undostack.h:43
composer.h
mailserviceimpl.h
KMMainWidget::clearViewer
void clearViewer()
Definition: kmmainwidget.cpp:535
kmstartup.h
KPIM::ProgressItem
CodecManager::self
static CodecManager * self()
Returns the CodecManager instance.
Definition: codecmanager.cpp:71
KMReaderMainWin
Definition: kmreadermainwin.h:32
KMail::KMSystemTray::hideKMail
void hideKMail()
Definition: kmsystemtray.cpp:333
kmCrashHandler
static void kmCrashHandler(int sigId)
Definition: kmkernel.cpp:1141
KMKernel::resumeBackgroundJobs
Q_SCRIPTABLE void resumeBackgroundJobs()
Resumes all background jobs and allows new jobs to be started.
Definition: kmkernel.cpp:893
KMKernel::updateSystemTray
void updateSystemTray()
Definition: kmkernel.cpp:1411
KMKernel::handleCommandLine
Q_SCRIPTABLE bool handleCommandLine(bool noArgsOpensReader)
Definition: kmkernel.cpp:285
KMKernel::dumpDeadLetters
void dumpDeadLetters()
Save contents of all open composer widnows to ~/dead.letter.
Definition: kmkernel.cpp:1296
KMKernel::stopAgentInstance
void stopAgentInstance()
Definition: kmkernel.cpp:1781
KMKernel::identityManager
KPIMIdentities::IdentityManager * identityManager()
return the pointer to the identity manager
Definition: kmkernel.cpp:1418
KMKernel::doSessionManagement
bool doSessionManagement()
Definition: kmkernel.cpp:1201
KMKernel::openFilterDialog
void openFilterDialog(bool createDummyFilter=true)
Definition: kmkernel.cpp:1845
KMail::KMSystemTray::setShowUnreadCount
void setShowUnreadCount(bool showUnreadCount)
Definition: kmsystemtray.cpp:146
collect_collections
static Akonadi::Collection::List collect_collections(const QAbstractItemModel *model, const QModelIndex &parent)
Definition: kmkernel.cpp:1545
KMKernel::mainWin
KMainWindow * mainWin()
returns a reference to the first Mainwin or a temporary Mainwin
Definition: kmkernel.cpp:1426
KMKernel::closeAllKMailWindows
void closeAllKMailWindows()
Definition: kmkernel.cpp:1218
serialNumber
quint32 serialNumber() const
KMail::Composer::New
Definition: composer.h:44
KMKernel::quit
void quit()
Definition: kmkernel.cpp:1040
kmreadermainwin.h
KMail::Composer::forceDisableHtml
virtual void forceDisableHtml()=0
KMKernel::msgSender
MessageComposer::MessageSender * msgSender()
Definition: kmkernel.cpp:1603
kmcommands.h
KMail::Composer::setCollectionForNewMessage
virtual void setCollectionForNewMessage(const Akonadi::Collection &folder)=0
KMKernel::closeToQuotaThreshold
qreal closeToQuotaThreshold()
Definition: kmkernel.cpp:1825
KPIM::RecentAddresses
broadcaststatus.h
KMKernel::checkFolderFromResources
void checkFolderFromResources(const Akonadi::Collection::List &collectionList)
Definition: kmkernel.cpp:1863
KMKernel::setLastSelectedFolder
void setLastSelectedFolder(const Akonadi::Collection::Id &col)
Definition: kmkernel.cpp:1835
KMKernel::customTemplates
QStringList customTemplates()
Definition: kmkernel.cpp:1840
KMKernel::slotSyncConfig
void slotSyncConfig()
Sync the config immediatley.
Definition: kmkernel.cpp:1344
KMKernel::expireAllFoldersNow
void expireAllFoldersNow()
Expire all folders, used for the gui action.
Definition: kmkernel.cpp:1567
KMKernel::onlineStatusChanged
void onlineStatusChanged(GlobalSettings::EnumNetworkState::type)
KMKernel::lastSelectedFolder
Akonadi::Collection::Id lastSelectedFolder()
Definition: kmkernel.cpp:1830
KMKernel::allFolders
Akonadi::Collection::List allFolders() const
Returns a list of all currently loaded folders.
Definition: kmkernel.cpp:1562
QMap
Definition: kmmainwidget.h:58
KMKernel::localDataPath
static QString localDataPath()
Returns the full path of the user's local data directory for KMail.
Definition: kmkernel.cpp:1399
KMKernel::canQueryClose
Q_SCRIPTABLE bool canQueryClose()
Definition: kmkernel.cpp:1572
KMKernel::~KMKernel
~KMKernel()
Definition: kmkernel.cpp:236
KMKernel::pauseBackgroundJobs
Q_SCRIPTABLE void pauseBackgroundJobs()
Pauses all background jobs and does not allow new background jobs to be started.
Definition: kmkernel.cpp:887
QList
KMail::Composer::slotSendNow
virtual void slotSendNow()=0
searchdescriptionattribute.h
recentaddresses.h
KMKernel::getKMMainWidget
KMMainWidget * getKMMainWidget()
Get first mainwidget.
Definition: kmkernel.cpp:1515
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:52 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

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