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