1 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net> 2 3 This file is part of the Trojita Qt IMAP e-mail client, 4 http://trojita.flaska.net/ 5 6 This program is free software; you can redistribute it and/or 7 modify it under the terms of the GNU General Public License as 8 published by the Free Software Foundation; either version 2 of 9 the License or (at your option) version 3 or any later version 10 accepted by the membership of KDE e.V. (or its successor approved 11 by the membership of KDE e.V.), which shall act as a proxy 12 defined in Section 14 of version 3 of the license. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21 */ 22 23 //#define TROJITA_DEBUG_TASK_TREE 24 25 #ifndef IMAP_MODEL_H 26 #define IMAP_MODEL_H 27 28 #include <QAbstractItemModel> 29 #include <QPointer> 30 #include <QTimer> 31 #include "Cache.h" 32 #include "../ConnectionState.h" 33 #include "../Parser/Parser.h" 34 #include "CacheLoadingMode.h" 35 #include "CopyMoveOperation.h" 36 #include "FlagsOperation.h" 37 #include "NetworkPolicy.h" 38 #include "ParserState.h" 39 #include "TaskFactory.h" 40 41 #include "Common/Logging.h" 42 43 class QAuthenticator; 44 class QNetworkSession; 45 class QSslError; 46 47 class FakeCapabilitiesInjector; 48 class ImapModelIdleTest; 49 class LibMailboxSync; 50 51 namespace Composer { 52 class ImapMessageAttachmentItem; 53 class ImapPartAttachmentItem; 54 class MessageComposer; 55 } 56 57 namespace Streams { 58 class SocketFactory; 59 } 60 61 /** @short Namespace for IMAP interaction */ 62 namespace Imap 63 { 64 65 /** @short Classes for handling of mailboxes and connections */ 66 namespace Mailbox 67 { 68 69 class TreeItem; 70 class TreeItemMailbox; 71 class TreeItemMsgList; 72 class TreeItemMessage; 73 class TreeItemPart; 74 class MsgListModel; 75 class MailboxModel; 76 class DummyNetworkWatcher; 77 class SystemNetworkWatcher; 78 79 class ImapTask; 80 class KeepMailboxOpenTask; 81 class TaskPresentationModel; 82 template <typename SourceModel> class SubtreeClassSpecificItem; 83 typedef std::unique_ptr<Streams::SocketFactory> SocketFactoryPtr; 84 85 /** @short Progress of mailbox synchronization with the IMAP server */ 86 typedef enum { STATE_WAIT_FOR_CONN, /**< Waiting for connection to become active */ 87 STATE_SELECTING, /**< SELECT command in progress */ 88 STATE_SYNCING_UIDS, /**< UID syncing in progress */ 89 STATE_SYNCING_FLAGS, /**< Flag syncing in progress */ 90 STATE_DONE /**< Mailbox is fully synchronized, both UIDs and flags are up to date */ 91 } MailboxSyncingProgress; 92 93 /** @short A model implementing view of the whole IMAP server */ 94 class Model: public QAbstractItemModel 95 { 96 Q_OBJECT 97 98 Q_PROPERTY(QString imapUser READ imapUser WRITE setImapUser) 99 Q_PROPERTY(QString imapPassword READ imapPassword WRITE setImapPassword RESET unsetImapPassword) 100 Q_PROPERTY(QString imapAuthError READ imapAuthError NOTIFY imapAuthErrorChanged) 101 Q_PROPERTY(bool isNetworkAvailable READ isNetworkAvailable NOTIFY networkPolicyChanged) 102 Q_PROPERTY(bool isNetworkOnline READ isNetworkOnline NOTIFY networkPolicyChanged) 103 104 /** @short How to open a mailbox */ 105 enum RWMode { 106 ReadOnly /**< @short Use EXAMINE or leave it in SELECTed mode*/, 107 ReadWrite /**< @short Invoke SELECT if necessarry */ 108 }; 109 110 mutable AbstractCache *m_cache; 111 mutable SocketFactoryPtr m_socketFactory; 112 TaskFactoryPtr m_taskFactory; 113 mutable QMap<Parser *,ParserState> m_parsers; 114 int m_maxParsers; 115 mutable TreeItemMailbox *m_mailboxes; 116 mutable NetworkPolicy m_netPolicy; 117 bool m_startTls; 118 119 mutable QList<Imap::Responses::NamespaceData> m_personalNamespace, m_otherUsersNamespace, m_sharedNamespace; 120 121 QList<QPair<QPair<QList<QSslCertificate>, QList<QSslError> >, bool> > m_sslErrorPolicy; 122 123 124 public: 125 Model(QObject *parent, AbstractCache *cache, SocketFactoryPtr m_socketFactory, TaskFactoryPtr m_taskFactory); 126 ~Model(); 127 128 virtual QModelIndex index(int row, int column, const QModelIndex &parent) const; 129 virtual QModelIndex parent(const QModelIndex &index) const; 130 virtual int rowCount(const QModelIndex &index) const; 131 virtual int columnCount(const QModelIndex &index) const; 132 virtual QVariant data(const QModelIndex &index, int role) const; 133 virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; 134 135 void handleState(Imap::Parser *ptr, const Imap::Responses::State *const resp); 136 void handleCapability(Imap::Parser *ptr, const Imap::Responses::Capability *const resp); 137 void handleNumberResponse(Imap::Parser *ptr, const Imap::Responses::NumberResponse *const resp); 138 void handleList(Imap::Parser *ptr, const Imap::Responses::List *const resp); 139 void handleFlags(Imap::Parser *ptr, const Imap::Responses::Flags *const resp); 140 void handleSearch(Imap::Parser *ptr, const Imap::Responses::Search *const resp); 141 void handleESearch(Imap::Parser *ptr, const Imap::Responses::ESearch *const resp); 142 void handleStatus(Imap::Parser *ptr, const Imap::Responses::Status *const resp); 143 void handleFetch(Imap::Parser *ptr, const Imap::Responses::Fetch *const resp); 144 void handleNamespace(Imap::Parser *ptr, const Imap::Responses::Namespace *const resp); 145 void handleSort(Imap::Parser *ptr, const Imap::Responses::Sort *const resp); 146 void handleThread(Imap::Parser *ptr, const Imap::Responses::Thread *const resp); 147 void handleId(Imap::Parser *ptr, const Imap::Responses::Id *const resp); 148 void handleEnabled(Imap::Parser *ptr, const Imap::Responses::Enabled *const resp); 149 void handleVanished(Imap::Parser *ptr, const Imap::Responses::Vanished *const resp); 150 void handleGenUrlAuth(Imap::Parser *ptr, const Imap::Responses::GenUrlAuth *const resp); 151 void handleSocketEncryptedResponse(Imap::Parser *ptr, const Imap::Responses::SocketEncryptedResponse *const resp); 152 void handleSocketDisconnectedResponse(Imap::Parser *ptr, const Imap::Responses::SocketDisconnectedResponse *const resp); 153 void handleParseErrorResponse(Imap::Parser *ptr, const Imap::Responses::ParseErrorResponse *const resp); 154 cache()155 AbstractCache *cache() const { return m_cache; } 156 /** Throw away current cache implementation, replace it with the new one 157 158 The old cache is automatically deleted. 159 */ 160 void setCache(AbstractCache *cache); 161 162 /** @short Force a SELECT / EXAMINE of a mailbox 163 164 This command sends a SELECT or EXAMINE command to the remote server, even if the 165 requested mailbox is currently selected. This has a side effect that we synchronize 166 the list of messages, which is why this function exists in the first place. 167 */ 168 void resyncMailbox(const QModelIndex &mbox); 169 170 /** @short Mark all messages in a given mailbox as read */ 171 void markMailboxAsRead(const QModelIndex &mailbox); 172 /** @short Add/Remove a flag for the indicated message */ 173 ImapTask *setMessageFlags(const QModelIndexList &messages, const QString flag, const FlagsOperation marked); 174 /** @short Ask the server to set/unset the \\Deleted flag for the indicated messages */ 175 void markMessagesDeleted(const QModelIndexList &messages, const FlagsOperation marked); 176 /** @short Ask the server to set/unset the \\Seen flag for the indicated messages */ 177 void markMessagesRead(const QModelIndexList &messages, const FlagsOperation marked); 178 179 /** @short Run the EXPUNGE command in the specified mailbox */ 180 void expungeMailbox(const QModelIndex &mailbox); 181 182 /** @short Copy or move a sequence of messages between two mailboxes */ 183 void copyMoveMessages(TreeItemMailbox *sourceMbox, const QString &destMboxName, Imap::Uids uids, const CopyMoveOperation op); 184 185 /** @short Create a new mailbox */ 186 void createMailbox(const QString &name, const AutoSubscription subscription = AutoSubscription::NO_EXPLICIT_SUBSCRIPTION); 187 /** @short Delete an existing mailbox */ 188 void deleteMailbox(const QString &name); 189 190 /** @short Subscribe a mailbox */ 191 void subscribeMailbox(const QString &name); 192 /** @short Unsubscribe a mailbox */ 193 void unsubscribeMailbox(const QString &name); 194 195 /** @short Save a message into a mailbox */ 196 AppendTask* appendIntoMailbox(const QString &mailbox, const QByteArray &rawMessageData, const QStringList &flags, 197 const QDateTime ×tamp); 198 199 /** @short Save a message into a mailbox using the CATENATE extension */ 200 AppendTask* appendIntoMailbox(const QString &mailbox, const QList<CatenatePair> &data, const QStringList &flags, 201 const QDateTime ×tamp); 202 203 /** @short Issue the GENURLAUTH command for a specified part/section */ 204 GenUrlAuthTask *generateUrlAuthForMessage(const QString &host, const QString &user, const QString &mailbox, 205 const uint uidValidity, const uint uid, const QString &part, const QString &access); 206 207 /** @short Send a mail through the UID SEND mechanism */ 208 UidSubmitTask *sendMailViaUidSubmit(const QString &mailbox, const uint uidValidity, const uint uid, 209 const UidSubmitOptionsList &options); 210 211 212 /** @short Returns true if we are allowed to access the network */ isNetworkAvailable()213 bool isNetworkAvailable() const { return m_netPolicy != NETWORK_OFFLINE; } 214 /** @short Returns true if the network access is cheap */ isNetworkOnline()215 bool isNetworkOnline() const { return m_netPolicy == NETWORK_ONLINE; } 216 217 /** @short Return a TreeItem* for a specified index 218 219 Certain proxy models implement their own indexes. These indexes typically won't 220 share the internalPointer() with the original model. Because we use this pointer 221 quite often, a method is needed to automatically go through the list of all proxy 222 models and return the appropriate raw pointer. 223 224 Upon success, a valid pointer is returned, *whichModel is set to point to the 225 corresponding Model instance and *translatedIndex contains the index in the real 226 underlying model. If any of these pointers is NULL, it won't get changed, of course. 227 228 Upon failure, this function returns 0 and doesn't touch any of @arg whichModel 229 and @arg translatedIndex. 230 */ 231 static TreeItem *realTreeItem(QModelIndex index, const Model **whichModel = 0, QModelIndex *translatedIndex = 0); 232 233 /** @short Inform the model that data for this message won't likely be requested in near future 234 235 Model will transform the corresponding TreeItemMessage into the state similar to how it would look 236 right after a fresh mailbox synchronization. All TreeItemParts will be freed, envelope and body 237 structure forgotten. This will substantially reduce Model's memory usage. 238 239 The UID and flags are not affected by this operation. The cache and any data stored in there will 240 also be left intact (and would indeed be consulted instead of the network when future requests for 241 this message happen again. 242 243 */ 244 void releaseMessageData(const QModelIndex &message); 245 246 /** @short Return a list of capabilities which are supported by the server */ 247 QStringList capabilities() const; 248 249 /** @short Log an IMAP-related message */ 250 void logTrace(uint parserId, const Common::LogKind kind, const QString &source, const QString &message); 251 void logTrace(const QModelIndex &relevantIndex, const Common::LogKind kind, const QString &source, const QString &message); 252 253 /** @short Return the server's response to the ID command 254 255 When the server indicates that the ID command is available, Trojitá will always send the ID command. The information sent to 256 the server is controlled by the trojita-imap-id-no-versions property. By default, Trojitá will tell the truth and proudly 257 present herself under her own name and using detailed version information and OS info. If set, it will just send the Trojita 258 name, but no version info. 259 260 The command is always sent upon each connection (ie. one protocol session, not the mailbox session). The result of this 261 function will therefore not make much sense (like be empty) when the model has always been offline. Each reconnection updates 262 the cached result. See RFC 2971 for the semantics of the ID command. 263 */ 264 QMap<QByteArray,QByteArray> serverId() const; 265 266 QStringList normalizeFlags(const QStringList &source) const; 267 268 QString imapUser() const; 269 void setImapUser(const QString &imapUser); 270 QString imapPassword() const; 271 void setImapPassword(const QString &imapPassword); 272 void unsetImapPassword(); 273 274 /** @short Return an index for the message specified by the mailbox name and the message UID */ 275 QModelIndex messageIndexByUid(const QString &mailboxName, const uint uid); 276 277 /** @short Provide a list of capabilities to not use 278 279 All blacklisted capabilities must be provided in the upper case. Capabilities are filtered only as they are reported by the 280 IMAP server. Calling this function while the connection is already open and kicking might have terrible consequences. 281 */ 282 void setCapabilitiesBlacklist(const QStringList &blacklist); 283 284 bool isCatenateSupported() const; 285 bool isGenUrlAuthSupported() const; 286 bool isImapSubmissionSupported() const; 287 288 void setNumberRefreshInterval(const int interval); 289 290 public slots: 291 /** @short Ask for an updated list of mailboxes on the server */ 292 void reloadMailboxList(); 293 294 /** @short Try to maintain a connection to the given mailbox 295 296 This function informs the Model that the user is interested in receiving 297 updates about the mailbox state, such as about the arrival of new messages. 298 The usual response to such a hint is launching the IDLE command. 299 */ 300 void switchToMailbox(const QModelIndex &mbox); 301 302 /** @short Get a pointer to the model visualizing the state of the tasks 303 304 The returned object still belongs to this Imap::Mailbox::Model, and its internal working is implementation-specific. The only 305 valid method of access is through the usual Qt Interview framework. 306 */ 307 QAbstractItemModel *taskModel() const; 308 309 void setSslPolicy(const QList<QSslCertificate> &sslChain, const QList<QSslError> &sslErrors, bool proceed); 310 311 void invalidateAllMessageCounts(); 312 313 QString imapAuthError() const; 314 315 private slots: 316 /** @short Helper for low-level state change propagation */ 317 void handleSocketStateChanged(Imap::Parser *parser, Imap::ConnectionState state); 318 319 /** @short The parser has received a full line */ 320 void slotParserLineReceived(Imap::Parser *parser, const QByteArray &line); 321 322 /** @short The parser has sent a block of data */ 323 void slotParserLineSent(Imap::Parser *parser, const QByteArray &line); 324 325 /** @short There's been a change in the state of various tasks */ 326 void slotTasksChanged(); 327 328 /** @short A maintaining task is about to die */ 329 void slotTaskDying(QObject *obj); 330 331 void setImapAuthError(const QString &error); 332 333 signals: 334 /** @short This signal is emitted then the server sent us an ALERT response code */ 335 void alertReceived(const QString &message); 336 /** @short The network went offline 337 338 This signal is emitted if the network connection went offline for any reason. 339 Common reasons are an explicit user action or a network error. 340 */ 341 void networkPolicyOffline(); 342 /** @short The network access policy got changed to "expensive" */ 343 void networkPolicyExpensive(); 344 /** @short The network is available and cheap again */ 345 void networkPolicyOnline(); 346 347 /** @short The network policy has changed 348 349 This signal is emitted whenever the network policy (might) got changed to any state and for any reason. No filtering for false 350 positives is done, i.e. it might be emitted even when no change has actually taken place. 351 */ 352 void networkPolicyChanged(); 353 354 /** @short Something bad happened to the network connectivity */ 355 void networkError(const QString &message); 356 357 /** @short An error at the application layer, e.g. an IMAP error, synchronization error, etc */ 358 void imapError(const QString &message); 359 360 /** @short The server requests the user to authenticate 361 362 The user is expected to file username and password through setting the "imapUser" and "imapPassword" properties. The imapUser 363 shall be set at first (if needed); a change to imapPassword will trigger the authentication process. 364 */ 365 void authRequested(); 366 367 /** @short The authentication attempt has failed 368 369 Slots attached to his signal should display an appropriate message to the user and (if applicable) also invalidate 370 the cached credentials. The credentials be requested when the model decides to try logging in again via the usual 371 authRequested() function. 372 */ 373 void authAttemptFailed(const QString &message); 374 375 /** @short Signal the need for a decision about accepting a particular SSL state 376 377 This signal is emitted in case a conneciton has hit a series of SSL errors which has not been encountered before. The rest 378 of the code shall make a decision about whether the presented sequence of errors is safe to allow and call the setSslPolicy() 379 with the passed list of errors and an instruction whether to continue or not. 380 */ 381 void needsSslDecision(const QList<QSslCertificate> &certificates, const QList<QSslError> &sslErrors); 382 383 /** @short Inform the user that it is advised to enable STARTTLS in future connection attempts */ 384 void requireStartTlsInFuture(); 385 386 /** @short The amount of messages in the indicated mailbox might have changed */ 387 void messageCountPossiblyChanged(const QModelIndex &mailbox); 388 389 /** @short We've succeeded to create the given mailbox */ 390 void mailboxCreationSucceded(const QString &mailbox); 391 /** @short The mailbox creation failed for some reason */ 392 void mailboxCreationFailed(const QString &mailbox, const QString &message); 393 /** @short We've succeeded to delete a mailbox */ 394 void mailboxDeletionSucceded(const QString &mailbox); 395 /** @short Mailbox deletion failed */ 396 void mailboxDeletionFailed(const QString &mailbox, const QString &message); 397 /** @short Got an error while syncing a mailbox */ 398 void mailboxSyncFailed(const QString &mailbox, const QString &message); 399 400 /** @short Inform the GUI about the progress of a connection */ 401 void connectionStateChanged(uint parserId, Imap::ConnectionState state); // got to use fully qualified namespace here 402 403 /** @short The parser has encountered a fatal error */ 404 void logParserFatalError(uint parser, const QString &exceptionClass, const QString &message, const QByteArray &line, int position); 405 406 void mailboxSyncingProgress(const QModelIndex &mailbox, Imap::Mailbox::MailboxSyncingProgress state); 407 408 void mailboxFirstUnseenMessage(const QModelIndex &maillbox, const QModelIndex &message); 409 410 /** @short Threading has arrived */ 411 void threadingAvailable(const QModelIndex &mailbox, const QByteArray &algorithm, 412 const QStringList &searchCriteria, const QVector<Imap::Responses::ThreadingNode> &mapping); 413 414 /** @short Failed to obtain threading information */ 415 void threadingFailed(const QModelIndex &mailbox, const QByteArray &algorithm, const QStringList &searchCriteria); 416 417 void capabilitiesUpdated(const QStringList &capabilities); 418 419 void logged(uint parserId, const Common::LogMessage &message); 420 421 void imapAuthErrorChanged(const QString &error); 422 423 private: 424 Model &operator=(const Model &); // don't implement 425 Model(const Model &); // don't implement 426 427 428 friend class TreeItem; 429 friend class TreeItemMailbox; 430 friend class TreeItemMsgList; 431 friend class TreeItemMessage; 432 friend class TreeItemPart; 433 friend class TreeItemModifiedPart; // needs access to createIndex() 434 friend class MsgListModel; // needs access to createIndex() 435 friend class MailboxModel; // needs access to createIndex() 436 friend class ThreadingMsgListModel; // needs access to taskFactory 437 friend class SubtreeClassSpecificItem<Model>; // needs access to createIndex() 438 439 friend class IdleLauncher; 440 441 friend class ImapTask; 442 friend class FetchMsgPartTask; 443 friend class UpdateFlagsTask; 444 friend class UpdateFlagsOfAllMessagesTask; 445 friend class ListChildMailboxesTask; 446 friend class NumberOfMessagesTask; 447 friend class FetchMsgMetadataTask; 448 friend class ExpungeMailboxTask; 449 friend class ExpungeMessagesTask; 450 friend class CreateMailboxTask; 451 friend class DeleteMailboxTask; 452 friend class CopyMoveMessagesTask; 453 friend class ObtainSynchronizedMailboxTask; 454 friend class KeepMailboxOpenTask; 455 friend class OpenConnectionTask; 456 friend class GetAnyConnectionTask; 457 friend class IdTask; 458 friend class Fake_ListChildMailboxesTask; 459 friend class Fake_OpenConnectionTask; 460 friend class NoopTask; 461 friend class ThreadTask; 462 friend class UnSelectTask; 463 friend class OfflineConnectionTask; 464 friend class SortTask; 465 friend class AppendTask; 466 friend class SubscribeUnsubscribeTask; 467 friend class GenUrlAuthTask; 468 friend class UidSubmitTask; 469 470 friend class TestingTaskFactory; // needs access to socketFactory 471 friend class DummyNetworkWatcher; // needs access to the network policy manipulation 472 friend class SystemNetworkWatcher; // needs access to the network policy manipulation 473 friend class NetworkWatcher; // needs access to the network policy manipulation 474 475 friend class ::FakeCapabilitiesInjector; // for injecting fake capabilities 476 friend class ::ImapModelIdleTest; // needs access to findTaskResponsibleFor() for IDLE testing 477 friend class TaskPresentationModel; // needs access to the ParserState 478 friend class ::LibMailboxSync; // needs access to accessParser/ParserState 479 480 friend class Composer::ImapMessageAttachmentItem; // needs access to findMailboxByName and findMessagesByUids 481 friend class Composer::ImapPartAttachmentItem; // dtto 482 friend class Composer::MessageComposer; // dtto 483 484 void askForChildrenOfMailbox(TreeItemMailbox *item, bool forceReload); 485 void askForMessagesInMailbox(TreeItemMsgList *item); 486 void askForNumberOfMessages(TreeItemMsgList *item); 487 488 typedef enum {PRELOAD_PER_POLICY, PRELOAD_DISABLED} PreloadingMode; 489 490 void askForMsgMetadata(TreeItemMessage *item, PreloadingMode preloadMode); 491 void askForMsgPart(TreeItemPart *item, bool onlyFromCache=false); 492 493 void finalizeList(Parser *parser, TreeItemMailbox *const mailboxPtr); 494 void finalizeIncrementalList(Parser *parser, const QString &parentMailboxName); 495 bool finalizeFetchPart(TreeItemMailbox *const mailbox, const uint sequenceNo, const QByteArray &partId); 496 void genericHandleFetch(TreeItemMailbox *mailbox, const Imap::Responses::Fetch *const resp); 497 498 void replaceChildMailboxes(TreeItemMailbox *mailboxPtr, const TreeItemChildrenList &mailboxes); 499 void updateCapabilities(Parser *parser, const QStringList capabilities); 500 501 TreeItem *translatePtr(const QModelIndex &index) const; 502 503 void emitMessageCountChanged(TreeItemMailbox *const mailbox); 504 505 TreeItemMailbox *findMailboxByName(const QString &name) const; 506 TreeItemMailbox *findMailboxByName(const QString &name, const TreeItemMailbox *const root) const; 507 TreeItemMailbox *findParentMailboxByName(const QString &name) const; 508 QList<TreeItemMessage *> findMessagesByUids(const TreeItemMailbox *const mailbox, const Imap::Uids &uids); 509 TreeItemChildrenList::iterator findMessageOrNextOneByUid(TreeItemMsgList *list, const uint uid); 510 511 static TreeItemMailbox *mailboxForSomeItem(QModelIndex index); 512 513 void saveUidMap(TreeItemMsgList *list); 514 515 /** @short Return a corresponding KeepMailboxOpenTask for a given mailbox */ 516 KeepMailboxOpenTask *findTaskResponsibleFor(const QModelIndex &mailbox); 517 KeepMailboxOpenTask *findTaskResponsibleFor(TreeItemMailbox *mailboxPtr); 518 519 /** @short Find a mailbox which is expected to be common for all passed items 520 521 The @arg items is expected to consists of message parts or messages themselves. 522 If they belong to different mailboxes, an exception is thrown. 523 */ 524 QModelIndex findMailboxForItems(const QModelIndexList &items); 525 networkPolicy()526 NetworkPolicy networkPolicy() const { return m_netPolicy; } 527 void setNetworkPolicy(const NetworkPolicy policy); 528 529 /** @short Helper function for changing connection state */ 530 void changeConnectionState(Parser *parser, ConnectionState state); 531 532 void processSslErrors(OpenConnectionTask *task); 533 534 /** @short Is the reason for killing the parser an expected one? */ 535 typedef enum { 536 PARSER_KILL_EXPECTED, /**< @short Normal operation */ 537 PARSER_KILL_HARD, /**< @short Sudden, unexpected death */ 538 PARSER_JUST_DELETE_LATER /**< @short Just call deleteLater(), nothing else */ 539 } ParserKillingMethod; 540 541 /** @short Dispose of the parser in a C++-safe way */ 542 void killParser(Parser *parser, ParserKillingMethod method=PARSER_KILL_HARD); 543 544 ParserState &accessParser(Parser *parser); 545 546 /** @short Helper for the slotParseError() */ 547 void broadcastParseError(const uint parser, const QString &exceptionClass, const QString &errorMessage, const QByteArray &line, int position); 548 549 void responseReceived(const QMap<Parser *,ParserState>::iterator it); 550 551 /** @short Remove deleted Tasks from the activeTasks list */ 552 void removeDeletedTasks(const QList<ImapTask *> &deletedTasks, QList<ImapTask *> &activeTasks); 553 554 void informTasksAboutNewPassword(); 555 556 QStringList onlineMessageFetch; 557 558 /** @short Model visualizing the state of the tasks */ 559 TaskPresentationModel *m_taskModel; 560 561 QMap<QByteArray,QByteArray> m_idResult; 562 563 mutable QSet<QString> m_flagLiterals; 564 565 /** @short Username for login */ 566 QString m_imapUser; 567 /** @short Cached copy of the IMAP password */ 568 QString m_imapPassword; 569 /** @short Is the IMAP password cached in the Model already? */ 570 enum class PasswordAvailability { 571 NOT_REQUESTED, 572 ASKED_WAITING, 573 AVAILABLE, 574 }; 575 PasswordAvailability m_hasImapPassword; 576 /** @short Contains IMAP error output while password prompt process*/ 577 QString m_imapAuthError; 578 579 QTimer *m_periodicMailboxNumbersRefresh; 580 581 QStringList m_capabilitiesBlacklist; 582 583 protected slots: 584 void responseReceived(); 585 void responseReceived(Imap::Parser *parser); 586 void askForChildrenOfMailbox(const QModelIndex &index, const Imap::Mailbox::CacheLoadingMode cacheMode); 587 void askForMessagesInMailbox(const QModelIndex &index); 588 589 void runReadyTasks(); 590 591 #ifdef TROJITA_DEBUG_TASK_TREE 592 void checkTaskTreeConsistency(); 593 void checkDependentTasksConsistency(Parser *parser, ImapTask *task, ImapTask *expectedParentTask, int depth); 594 #endif 595 596 }; 597 598 } 599 600 } 601 602 #endif /* IMAP_MODEL_H */ 603