1 // 2 3 #pragma once 4 5 #include <MailCommon/MailInterfaces> 6 7 #include <QDBusObjectPath> 8 #include <QList> 9 #include <QObject> 10 #include <QPointer> 11 12 #include <QUrl> 13 14 #include "kmail_export.h" 15 #include "settings/kmailsettings.h" 16 #include <Akonadi/ServerManager> 17 #include <Libkdepim/ProgressManager> 18 #include <MessageViewer/Viewer> 19 20 #include <memory> 21 22 #define kmkernel KMKernel::self() 23 #define kmconfig KMKernel::config() 24 25 class QAbstractItemModel; 26 namespace Akonadi 27 { 28 class Collection; 29 class ChangeRecorder; 30 class EntityTreeModel; 31 class EntityMimeTypeFilterModel; 32 } 33 34 namespace Akonadi 35 { 36 namespace Search 37 { 38 namespace PIM 39 { 40 class IndexedItems; 41 } 42 } 43 } 44 45 namespace KIO 46 { 47 class Job; 48 } 49 50 namespace MessageComposer 51 { 52 class MessageSender; 53 } 54 namespace PimCommon 55 { 56 class AutoCorrection; 57 } 58 59 /** The KMail namespace contains classes used for KMail. 60 * This is to keep them out of the way from all the other 61 * un-namespaced classes in libs and the rest of PIM. 62 */ 63 namespace KMail 64 { 65 class MailServiceImpl; 66 class UndoStack; 67 class UnityServiceManager; 68 } 69 namespace MessageComposer 70 { 71 class AkonadiSender; 72 } 73 74 namespace KIdentityManagement 75 { 76 class Identity; 77 class IdentityManager; 78 } 79 80 namespace MailCommon 81 { 82 class Kernel; 83 class FolderSettings; 84 class FolderCollectionMonitor; 85 class JobScheduler; 86 class KMFilterDialog; 87 class MailCommonSettings; 88 } 89 90 #ifdef WITH_KUSERFEEDBACK 91 class KMailUserFeedbackProvider; 92 namespace KUserFeedback 93 { 94 class Provider; 95 } 96 #endif 97 98 namespace Kleo 99 { 100 class KeyCache; 101 } 102 103 class QTimer; 104 class KMainWindow; 105 class KMMainWidget; 106 class ConfigureDialog; 107 class FolderArchiveManager; 108 class CheckIndexingManager; 109 110 /** 111 * @short Central point of coordination in KMail 112 * 113 * The KMKernel class represents the core of KMail, where the different parts 114 * come together and are coordinated. It is currently also the class which exports 115 * KMail's main D-BUS interfaces. 116 * 117 * The kernel is responsible for creating various 118 * (singleton) objects such as the identity manager and the message sender. 119 * 120 * The kernel also creates an Akonadi Session, Monitor and EntityTreeModel. These 121 * are shared so that other objects in KMail have access to it. Having only one EntityTreeModel 122 * instead of many reduces the overall communication with the Akonadi server. 123 * 124 * The kernel also manages some stuff that should be factored out: 125 * - default collection handling, like inboxCollectionFolder() 126 * - job handling, like jobScheduler() 127 * - handling of some config settings, like wrapCol() 128 * - various other stuff 129 */ 130 class KMAIL_EXPORT KMKernel : public QObject, public MailCommon::IKernel, public MailCommon::ISettings, public MailCommon::IFilter 131 { 132 Q_OBJECT 133 Q_CLASSINFO("D-Bus Interface", "org.kde.kmail.kmail") 134 135 public: 136 explicit KMKernel(QObject *parent = nullptr); 137 ~KMKernel() override; 138 139 /** 140 * Start of D-Bus callable stuff. The D-Bus methods need to be public slots, 141 * otherwise they can't be accessed. 142 */ 143 public Q_SLOTS: 144 145 Q_SCRIPTABLE void checkMail(); 146 Q_SCRIPTABLE void openReader(); 147 148 /** 149 * Pauses all background jobs and does not 150 * allow new background jobs to be started. 151 */ 152 Q_SCRIPTABLE void pauseBackgroundJobs(); 153 154 /** 155 * Resumes all background jobs and allows 156 * new jobs to be started. 157 */ 158 Q_SCRIPTABLE void resumeBackgroundJobs(); 159 160 /** 161 * Stops all network related jobs and enter offline mode 162 * New network jobs cannot be started. 163 */ 164 Q_SCRIPTABLE void stopNetworkJobs(); 165 166 /** 167 * Resumes all network related jobs and enter online mode 168 * New network jobs can be started. 169 */ 170 Q_SCRIPTABLE void resumeNetworkJobs(); 171 172 Q_SCRIPTABLE QStringList accounts() const; 173 174 Q_SCRIPTABLE void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode); 175 176 /** 177 * Checks the account with the specified name for new mail. 178 * If the account name is empty, all accounts not excluded from manual 179 * mail check will be checked. 180 */ 181 Q_SCRIPTABLE void checkAccount(const QString &account); 182 183 Q_SCRIPTABLE bool selectFolder(const QString &folder); 184 185 Q_SCRIPTABLE bool canQueryClose(); 186 187 Q_SCRIPTABLE bool handleCommandLine(bool noArgsOpensReader, const QStringList &args, const QString &workingDir); 188 189 /** 190 * Opens a composer window and prefills it with different 191 * message parts. 192 * 193 * 194 * @param to A comma separated list of To addresses. 195 * @param cc A comma separated list of CC addresses. 196 * @param bcc A comma separated list of BCC addresses. 197 * @param subject The message subject. 198 * @param body The message body. 199 * @param hidden Whether the composer window shall initially be hidden. 200 * @param messageFile A message file that will be used as message body. 201 * @param attachmentPaths A list of files that will be attached to the message. 202 * @param customHeaders A list of custom headers. 203 * @param replyTo A list of reply-to headers. 204 * @param inReplyTo A list of in-reply-to headers. 205 * @param identity The mail identity. 206 */ 207 Q_SCRIPTABLE void openComposer(const QString &to, 208 const QString &cc, 209 const QString &bcc, 210 const QString &subject, 211 const QString &body, 212 bool hidden, 213 const QString &messageFile, 214 const QStringList &attachmentPaths, 215 const QStringList &customHeaders, 216 const QString &replyTo = QString(), 217 const QString &inReplyTo = QString(), 218 const QString &identity = QString()); 219 220 /** 221 * Opens a composer window and prefills it with different 222 * message parts. 223 * 224 * @param to A comma separated list of To addresses. 225 * @param cc A comma separated list of CC addresses. 226 * @param bcc A comma separated list of BCC addresses. 227 * @param subject The message subject. 228 * @param body The message body. 229 * @param hidden Whether the composer window shall initially be hidden. 230 * @param attachName The name of the attachment. 231 * @param attachCte The content transfer encoding of the attachment. 232 * @param attachData The raw data of the attachment. 233 * @param attachType The mime type of the attachment. 234 * @param attachSubType The sub mime type of the attachment. 235 * @param attachParamAttr The parameter attribute of the attachment. 236 * @param attachParamValue The parameter value of the attachment. 237 * @param attachContDisp The content display type of the attachment. 238 * @param attachCharset The charset of the attachment. 239 * @param identity The identity identifier which will be used as sender identity. 240 */ 241 Q_SCRIPTABLE void openComposer(const QString &to, 242 const QString &cc, 243 const QString &bcc, 244 const QString &subject, 245 const QString &body, 246 bool hidden, 247 const QString &attachName, 248 const QByteArray &attachCte, 249 const QByteArray &attachData, 250 const QByteArray &attachType, 251 const QByteArray &attachSubType, 252 const QByteArray &attachParamAttr, 253 const QString &attachParamValue, 254 const QByteArray &attachContDisp, 255 const QByteArray &attachCharset, 256 unsigned int identity); 257 258 /** 259 * Opens a composer window and prefills it with different 260 * message parts. 261 * @since 5.0 262 * 263 * @param to A comma separated list of To addresses. 264 * @param cc A comma separated list of CC addresses. 265 * @param bcc A comma separated list of BCC addresses. 266 * @param subject The message subject. 267 * @param body The message body. 268 * @param attachName The name of the attachment. 269 * @param attachCte The content transfer encoding of the attachment. 270 * @param attachData The raw data of the attachment. 271 * @param attachType The mime type of the attachment. 272 * @param attachSubType The sub mime type of the attachment. 273 * @param attachParamAttr The parameter attribute of the attachment. 274 * @param attachParamValue The parameter value of the attachment. 275 * @param attachContDisp The content display type of the attachment. 276 * @param attachCharset The charset of the attachment. 277 * @param identity The identity identifier which will be used as sender identity. 278 */ 279 Q_SCRIPTABLE void openComposer(const QString &to, 280 const QString &cc, 281 const QString &bcc, 282 const QString &subject, 283 const QString &body, 284 const QString &attachName, 285 const QByteArray &attachCte, 286 const QByteArray &attachData, 287 const QByteArray &attachType, 288 const QByteArray &attachSubType, 289 const QByteArray &attachParamAttr, 290 const QString &attachParamValue, 291 const QByteArray &attachContDisp, 292 const QByteArray &attachCharset, 293 unsigned int identity); 294 295 /** 296 * Opens a composer window and prefills it with different 297 * message parts. 298 * 299 * 300 * @param to A comma separated list of To addresses. 301 * @param cc A comma separated list of CC addresses. 302 * @param bcc A comma separated list of BCC addresses. 303 * @param subject The message subject. 304 * @param body The message body. 305 * @param hidden Whether the composer window shall initially be hidden. 306 */ 307 Q_SCRIPTABLE void openComposer(const QString &to, const QString &cc, const QString &bcc, const QString &subject, const QString &body, bool hidden); 308 309 /** 310 * Opens a composer window and prefills it with different 311 * message parts. 312 * 313 * @returns The DBus object path for the composer. 314 * 315 * @param to A comma separated list of To addresses. 316 * @param cc A comma separated list of CC addresses. 317 * @param bcc A comma separated list of BCC addresses. 318 * @param hidden Whether the composer window shall initially be hidden. 319 * @param useFolderId The id of the folder whose associated identity will be used. 320 * @param messageFile A message file that will be used as message body. 321 * @param attachURL The URL to the file that will be attached to the message. 322 */ 323 Q_SCRIPTABLE void 324 newMessage(const QString &to, const QString &cc, const QString &bcc, bool hidden, bool useFolderId, const QString &messageFile, const QString &attachURL); 325 326 Q_SCRIPTABLE bool showMail(qint64 serialNumber); 327 328 Q_SCRIPTABLE int viewMessage(const QString &messageFile); 329 330 Q_SCRIPTABLE void updateConfig(); 331 332 Q_SCRIPTABLE void showFolder(const QString &collectionId); 333 334 Q_SCRIPTABLE void reloadFolderArchiveConfig(); 335 336 Q_SCRIPTABLE bool replyMail(qint64 serialNumber, bool replyToAll); 337 338 /** 339 * End of D-Bus callable stuff 340 */ 341 342 public: 343 void checkMailOnStartup(); 344 345 /** A static helper function that asks the user 346 * if they want to go online. 347 * @return true if the user wants to go online 348 * @return false if the user wants to stay offline 349 */ 350 static bool askToGoOnline(); 351 352 /** Checks if the current network state is online or offline 353 * @return true if the network state is offline 354 * @return false if the network state is online 355 */ 356 static bool isOffline(); 357 358 /** normal control stuff */ 359 360 static KMKernel *self(); 361 KSharedConfig::Ptr config() override; 362 void syncConfig() override; 363 364 void init(); 365 void setupDBus(); 366 367 void expunge(Akonadi::Collection::Id col, bool sync) override; 368 Akonadi::ChangeRecorder *folderCollectionMonitor() const override; 369 370 /** 371 * Returns the main model, which contains all folders and the items of recently opened folders. 372 */ 373 Akonadi::EntityTreeModel *entityTreeModel() const; 374 375 /** 376 * Returns a model of all folders in KMail. This is basically the same as entityTreeModel(), 377 * but with items filtered out, the model contains only collections. 378 */ 379 Q_REQUIRED_RESULT Akonadi::EntityMimeTypeFilterModel *collectionModel() const override; 380 381 void recoverDeadLetters(); 382 void closeAllKMailWindows(); 383 void cleanup(); 384 void quit(); 385 void doSessionManagement(); 386 Q_REQUIRED_RESULT bool firstInstance() const; 387 void setFirstInstance(bool value); 388 void action(bool mailto, 389 bool check, 390 bool startInTray, 391 const QString &to, 392 const QString &cc, 393 const QString &bcc, 394 const QString &subj, 395 const QString &body, 396 const QUrl &messageFile, 397 const QList<QUrl> &attach, 398 const QStringList &customHeaders, 399 const QString &replyTo, 400 const QString &inReplyTo, 401 const QString &identity); 402 403 // sets online status for akonadi accounts. true for online, false for offline 404 void setAccountStatus(bool); 405 406 Q_REQUIRED_RESULT const QString xmlGuiInstanceName() const; 407 void setXmlGuiInstanceName(const QString &instance); 408 409 Q_REQUIRED_RESULT KMail::UndoStack *undoStack() const; 410 MessageComposer::MessageSender *msgSender() override; 411 412 void openFilterDialog(bool createDummyFilter = true) override; 413 void createFilter(const QByteArray &field, const QString &value) override; 414 415 /** return the pointer to the identity manager */ 416 KIdentityManagement::IdentityManager *identityManager() override; 417 418 MailCommon::JobScheduler *jobScheduler() const override; 419 420 /** Expire all folders, used for the gui action */ 421 void expireAllFoldersNow(); 422 423 Q_REQUIRED_RESULT bool firstStart() const; 424 Q_REQUIRED_RESULT bool shuttingDown() const; 425 void setShuttingDown(bool flag); 426 427 /** Returns true if we have a system tray applet. This is needed in order 428 * to know whether the application should be allowed to exit in case the 429 * last visible composer or separate message window is closed. 430 */ 431 Q_REQUIRED_RESULT bool haveSystemTrayApplet() const; 432 433 Q_REQUIRED_RESULT QTextCodec *networkCodec() const; 434 435 /** returns a reference to the first Mainwin or a temporary Mainwin */ 436 KMainWindow *mainWin(); 437 438 /** Get first mainwidget */ 439 KMMainWidget *getKMMainWidget() const; 440 441 /** 442 * Returns a list of all currently loaded folders. Since folders are loaded async, this 443 * is empty at startup. 444 */ 445 Q_REQUIRED_RESULT Akonadi::Collection::List allFolders() const; 446 447 /** 448 * Includes all subfolders of @p col, including the @p col itself. 449 */ 450 Q_REQUIRED_RESULT Akonadi::Collection::List subfolders(const Akonadi::Collection &col) const; 451 452 // 453 void selectCollectionFromId(Akonadi::Collection::Id id); 454 455 void raise(); 456 457 void stopAgentInstance(); 458 459 // ISettings 460 Q_REQUIRED_RESULT bool showPopupAfterDnD() override; 461 462 bool excludeImportantMailFromExpiry() override; 463 464 qreal closeToQuotaThreshold() override; 465 466 Q_REQUIRED_RESULT Akonadi::Collection::Id lastSelectedFolder() override; 467 void setLastSelectedFolder(Akonadi::Collection::Id col) override; 468 469 QStringList customTemplates() override; 470 471 void checkFolderFromResources(const Akonadi::Collection::List &collectionList); 472 473 Q_REQUIRED_RESULT const QAbstractItemModel *treeviewModelSelection(); 474 475 void savePaneSelection(); 476 477 void updatePaneTagComboBox(); 478 479 Q_REQUIRED_RESULT PimCommon::AutoCorrection *composerAutoCorrection(); 480 481 void toggleSystemTray(); 482 FolderArchiveManager *folderArchiveManager() const; 483 484 Q_REQUIRED_RESULT bool allowToDebug() const; 485 486 Q_REQUIRED_RESULT Akonadi::Search::PIM::IndexedItems *indexedItems() const; 487 488 void cleanupTemporaryFiles(); 489 Q_REQUIRED_RESULT MailCommon::MailCommonSettings *mailCommonSettings() const; 490 #ifdef WITH_KUSERFEEDBACK 491 KUserFeedback::Provider *userFeedbackProvider() const; 492 #endif 493 protected: 494 void agentInstanceBroken(const Akonadi::AgentInstance &instance); 495 496 public Q_SLOTS: 497 498 void updateSystemTray() override; 499 500 /** Custom templates have changed, so all windows using them need 501 to regenerate their menus */ 502 void updatedTemplates(); 503 504 /// Save contents of all open composer windows to ~/dead.letter 505 void dumpDeadLetters(); 506 507 /** Call this slot instead of directly KConfig::sync() to 508 minimize the overall config writes. Calling this slot will 509 schedule a sync of the application config file using a timer, so 510 that many consecutive calls can be condensed into a single 511 sync, which is more efficient. */ 512 void slotRequestConfigSync(); 513 514 /** 515 * Sync the config immediatley 516 */ 517 void slotSyncConfig(); 518 519 void slotShowConfigurationDialog(); 520 void slotRunBackgroundTasks(); 521 522 void slotConfigChanged(); 523 Q_SIGNALS: 524 void configChanged(); 525 void onlineStatusChanged(KMailSettings::EnumNetworkState::type); 526 void customTemplatesChanged(); 527 528 void startCheckMail(); 529 void endCheckMail(); 530 531 void incomingAccountsChanged(); 532 private Q_SLOTS: 533 /** Updates identities when a transport has been deleted. */ 534 void transportRemoved(int id, const QString &name); 535 /** Updates identities when a transport has been renamed. */ 536 void transportRenamed(int id, const QString &oldName, const QString &newName); 537 void itemDispatchStarted(); 538 void instanceStatusChanged(const Akonadi::AgentInstance &); 539 540 void akonadiStateChanged(Akonadi::ServerManager::State); 541 void slotProgressItemCompletedOrCanceled(KPIM::ProgressItem *item); 542 void slotInstanceError(const Akonadi::AgentInstance &instance, const QString &message); 543 void slotInstanceWarning(const Akonadi::AgentInstance &instance, const QString &message); 544 void slotCollectionRemoved(const Akonadi::Collection &col); 545 void slotDeleteIdentity(uint identity); 546 void slotInstanceRemoved(const Akonadi::AgentInstance &); 547 void slotInstanceAdded(const Akonadi::AgentInstance &); 548 void slotSystemNetworkStatusChanged(bool isOnline); 549 void slotCollectionChanged(const Akonadi::Collection &, const QSet<QByteArray> &set); 550 551 void slotCheckAccount(Akonadi::ServerManager::State state); 552 553 private: 554 void viewMessage(const QUrl &url); 555 Q_REQUIRED_RESULT Akonadi::Collection currentCollection() const; 556 557 /* 558 * Fills a composer cWin 559 * 560 */ 561 void fillComposer(bool hidden, 562 const QString &to, 563 const QString &cc, 564 const QString &bcc, 565 const QString &subject, 566 const QString &body, 567 const QString &attachName, 568 const QByteArray &attachCte, 569 const QByteArray &attachData, 570 const QByteArray &attachType, 571 const QByteArray &attachSubType, 572 const QByteArray &attachParamAttr, 573 const QString &attachParamValue, 574 const QByteArray &attachContDisp, 575 const QByteArray &attachCharset, 576 unsigned int identity, 577 bool forceShowWindow); 578 579 void verifyAccount(); 580 void resourceGoOnLine(); 581 void openReader(bool onlyCheck, bool startInTray); 582 QSharedPointer<MailCommon::FolderSettings> currentFolderCollection(); 583 void saveConfig(); 584 585 KMail::UndoStack *the_undoStack = nullptr; 586 MessageComposer::AkonadiSender *the_msgSender = nullptr; 587 /** is this the first start? read from config */ 588 bool the_firstStart = false; 589 /** are we going down? set from here */ 590 bool the_shuttingDown = false; 591 /** true unles kmail is closed by session management */ 592 bool the_firstInstance = false; 593 594 KSharedConfig::Ptr mConfig; 595 QTextCodec *mNetCodec = nullptr; 596 QString mXmlGuiInstance; 597 ConfigureDialog *mConfigureDialog = nullptr; 598 599 QTimer *mBackgroundTasksTimer = nullptr; 600 MailCommon::JobScheduler *const mJobScheduler; 601 KMail::MailServiceImpl *mMailService = nullptr; 602 603 bool mSystemNetworkStatus = true; 604 605 KMail::UnityServiceManager *mUnityServiceManager = nullptr; 606 QHash<QString, KPIM::ProgressItem::CryptoStatus> mResourceCryptoSettingCache; 607 MailCommon::FolderCollectionMonitor *mFolderCollectionMonitor = nullptr; 608 Akonadi::EntityTreeModel *mEntityTreeModel = nullptr; 609 Akonadi::EntityMimeTypeFilterModel *mCollectionModel = nullptr; 610 611 /// List of Akonadi resources that are currently being checked. 612 QStringList mResourcesBeingChecked; 613 614 QPointer<MailCommon::KMFilterDialog> mFilterEditDialog; 615 PimCommon::AutoCorrection *mAutoCorrection = nullptr; 616 FolderArchiveManager *const mFolderArchiveManager; 617 CheckIndexingManager *mCheckIndexingManager = nullptr; 618 Akonadi::Search::PIM::IndexedItems *mIndexedItems = nullptr; 619 MailCommon::MailCommonSettings *mMailCommonSettings = nullptr; 620 #ifdef WITH_KUSERFEEDBACK 621 KMailUserFeedbackProvider *mUserFeedbackProvider = nullptr; 622 #endif 623 std::shared_ptr<const Kleo::KeyCache> mKeyCache; 624 625 bool mDebug = false; 626 }; 627 628