File indexing completed on 2024-06-23 05:21:15

0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
0002 
0003    This file is part of the Trojita Qt IMAP e-mail client,
0004    http://trojita.flaska.net/
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public License as
0008    published by the Free Software Foundation; either version 2 of
0009    the License or (at your option) version 3 or any later version
0010    accepted by the membership of KDE e.V. (or its successor approved
0011    by the membership of KDE e.V.), which shall act as a proxy
0012    defined in Section 14 of version 3 of the license.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    You should have received a copy of the GNU General Public License
0020    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #ifndef IMAP_OBTAINSYNCHRONIZEDMAILBOXTASK_H
0024 #define IMAP_OBTAINSYNCHRONIZEDMAILBOXTASK_H
0025 
0026 #include "ImapTask.h"
0027 #include <QModelIndex>
0028 #include "../Model/Model.h"
0029 
0030 namespace Imap
0031 {
0032 namespace Mailbox
0033 {
0034 
0035 class UnSelectTask;
0036 
0037 /** @short Create a synchronized connection to the IMAP server
0038 
0039 Upon creation, this class will obtain a connection to the IMAP
0040 server (either by creating new one, or simply stealing one from
0041 an already established one, open a mailbox, fully synchronize it
0042 and when all of the above is done, simply declare itself completed.
0043 */
0044 class ObtainSynchronizedMailboxTask : public ImapTask
0045 {
0046     Q_OBJECT
0047 public:
0048     ObtainSynchronizedMailboxTask(Model *model, const QModelIndex &mailboxIndex, ImapTask *parentTask, KeepMailboxOpenTask *keepTask);
0049     void perform() override;
0050     bool handleStateHelper(const Imap::Responses::State *const resp) override;
0051     bool handleNumberResponse(const Imap::Responses::NumberResponse *const resp) override;
0052     bool handleFlags(const Imap::Responses::Flags *const resp) override;
0053     bool handleSearch(const Imap::Responses::Search *const resp) override;
0054     bool handleESearch(const Imap::Responses::ESearch *const resp) override;
0055     bool handleFetch(const Imap::Responses::Fetch *const resp) override;
0056     bool handleVanished(const Imap::Responses::Vanished *const resp) override;
0057     bool handleEnabled(const Responses::Enabled * const resp) override;
0058 
0059     typedef enum { UID_SYNC_ALL, UID_SYNC_ONLY_NEW } UidSyncingMode;
0060 
0061     void addDependentTask(ImapTask *task) override;
0062 
0063     QString debugIdentification() const override;
0064     QVariant taskData(const int role) const override;
0065     bool needsMailbox() const override {return false;}
0066 
0067 private:
0068     void finalizeSelect();
0069     void fullMboxSync(TreeItemMailbox *mailbox, TreeItemMsgList *list);
0070     void syncNoNewNoDeletions(TreeItemMailbox *mailbox, TreeItemMsgList *list);
0071     void syncOnlyAdditions(TreeItemMailbox *mailbox, TreeItemMsgList *list);
0072     void syncGeneric(TreeItemMailbox *mailbox, TreeItemMsgList *list);
0073 
0074     void applyUids(TreeItemMailbox *mailbox);
0075     void finalizeSearch();
0076 
0077     void syncUids(TreeItemMailbox *mailbox, const uint lowestUidToQuery=0);
0078     void syncFlags(TreeItemMailbox *mailbox);
0079     void updateHighestKnownUid(TreeItemMailbox *mailbox, const TreeItemMsgList *list) const;
0080 
0081     void notifyInterestingMessages(TreeItemMailbox *mailbox);
0082 
0083     bool handleResponseCodeInsideState(const Imap::Responses::State *const resp);
0084 
0085     /** @short Check current mailbox for validty, and take an evasive action if it disappeared
0086 
0087       There's a problem when going online after an outage, where the underlying TreeItemMailbox could disappear.
0088       This function checks the index for validity, and queues a fake "unselect" task just to make sure that
0089       we get out of that mailbox as soon as possible. This task will also die() in such situation.
0090 
0091       See issue #88 for details.
0092 
0093       @returns true if the current response shall be consumed
0094     */
0095     bool dieIfInvalidMailbox();
0096 
0097 private slots:
0098     /** @short We're now out of that mailbox, hurray! */
0099     void slotUnSelectCompleted();
0100 
0101     void signalSyncFailure(const QString &message);
0102 
0103 private:
0104     ImapTask *conn;
0105     QPersistentModelIndex mailboxIndex;
0106     CommandHandle selectCmd;
0107     CommandHandle uidSyncingCmd;
0108     CommandHandle flagsCmd;
0109     QList<CommandHandle> newArrivalsFetch;
0110     Imap::Mailbox::MailboxSyncingProgress status;
0111     UidSyncingMode uidSyncingMode;
0112     Imap::Uids uidMap;
0113     uint firstUnknownUidOffset;
0114     SyncState oldSyncState;
0115     bool m_usingQresync;
0116 
0117     /** @short An UNSELECT task, if active */
0118     UnSelectTask *unSelectTask;
0119 
0120     /** @short The KeepMailboxOpenTask for which we're working */
0121     KeepMailboxOpenTask *keepTaskChild;
0122 
0123     friend class KeepMailboxOpenTask; // needs access to conn because it wants to re-use its parser, yay
0124 };
0125 
0126 }
0127 }
0128 
0129 #endif // IMAP_OBTAINSYNCHRONIZEDMAILBOXTASK_H