File indexing completed on 2024-11-24 04:44:33
0001 /* 0002 SPDX-FileCopyrightText: 2010 Thomas McGuire <mcguire@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #pragma once 0008 0009 class KJob; 0010 #include <Akonadi/ResourceBase> 0011 #include <KMime/Message> 0012 #include <QSet> 0013 0014 #include "settings.h" 0015 0016 class DeleteJob; 0017 0018 namespace Akonadi 0019 { 0020 class ItemCreateJob; 0021 } 0022 class POPSession; 0023 class QTimer; 0024 namespace QKeychain 0025 { 0026 class Job; 0027 } 0028 class POP3Resource : public Akonadi::ResourceBase, public Akonadi::AgentBase::Observer 0029 { 0030 Q_OBJECT 0031 0032 public: 0033 explicit POP3Resource(const QString &id); 0034 ~POP3Resource() override; 0035 0036 void clearCachedPassword(); 0037 0038 void cleanup() override; 0039 0040 protected: 0041 using ResourceBase::retrieveItems; // Suppress -Woverload-virtual 0042 0043 protected Q_SLOTS: 0044 void retrieveCollections() override; 0045 void retrieveItems(const Akonadi::Collection &col) override; 0046 bool retrieveItems(const Akonadi::Item::List &items, const QSet<QByteArray> &parts) override; 0047 bool retrieveItem(const Akonadi::Item &item, const QSet<QByteArray> &parts) override; 0048 0049 protected: 0050 void aboutToQuit() override; 0051 void doSetOnline(bool online) override; 0052 0053 private Q_SLOTS: 0054 0055 void slotAbortRequested(); 0056 void intervalCheckTriggered(); 0057 void configurationChanged(); 0058 0059 // For state FetchTargetCollection 0060 void targetCollectionFetchJobFinished(KJob *job); 0061 void localFolderRequestJobFinished(KJob *job); 0062 0063 // For state Precommand 0064 void precommandResult(KJob *job); 0065 0066 // For state RequestPassword 0067 void walletOpenedForLoading(QKeychain::Job *baseJob); 0068 0069 // For state Login 0070 void loginJobResult(KJob *job); 0071 0072 // For state List 0073 void listJobResult(KJob *job); 0074 0075 // For state UIDList 0076 void uidListJobResult(KJob *job); 0077 0078 // For state Download 0079 void messageFinished(int messageId, KMime::Message::Ptr message); 0080 void fetchJobResult(KJob *job); 0081 void messageDownloadProgress(KJob *job, KJob::Unit unit, qulonglong totalBytes); 0082 0083 // For state Save 0084 void itemCreateJobResult(KJob *job); 0085 0086 // For state Delete 0087 void deleteJobResult(KJob *job); 0088 0089 // For state Quit 0090 void quitJobResult(KJob *job); 0091 0092 private: 0093 enum State { 0094 Idle, 0095 FetchTargetCollection, 0096 Precommand, 0097 RequestPassword, 0098 Connect, 0099 Login, 0100 List, 0101 UIDList, 0102 Download, 0103 Save, 0104 Quit, 0105 SavePassword, 0106 CheckRemovingMessage 0107 }; 0108 0109 void resetState(); 0110 void doStateStep(); 0111 void advanceState(State nextState); 0112 void cancelSync(const QString &errorMessage, bool error = true); 0113 void saveSeenUIDList(); 0114 QList<int> shouldDeleteId(int downloadedId) const; 0115 int idToTime(int id) const; 0116 int idOfOldestMessage(const QSet<int> &idList) const; 0117 void startMailCheck(); 0118 void updateIntervalTimer(); 0119 void showPasswordDialog(const QString &queryText); 0120 QString buildLabelForPasswordDialog(const QString &detailedError) const; 0121 void checkRemovingMessageFromServer(); 0122 void finish(); 0123 0124 bool shouldAdvanceToQuitState() const; 0125 0126 State mState; 0127 Akonadi::Collection mTargetCollection; 0128 POPSession *mPopSession = nullptr; 0129 bool mAskAgain = false; 0130 QTimer *mIntervalTimer = nullptr; 0131 bool mIntervalCheckInProgress = false; 0132 QString mPassword; 0133 bool mSavePassword = false; 0134 bool mTestLocalInbox = false; 0135 0136 // Maps IDs on the server to message sizes on the server 0137 QMap<int, int> mIdsToSizeMap; 0138 0139 // Maps IDs on the server to UIDs on the server. 0140 // This can be empty, if the server doesn't support UIDL 0141 QMap<int, QString> mIdsToUidsMap; 0142 0143 // Maps UIDs on the server to IDs on the server. 0144 // This can be empty, if the server doesn't support UIDL 0145 QMap<QString, int> mUidsToIdsMap; 0146 0147 // Whether we actually received a valid UID list from the server 0148 bool mUidListValid; 0149 0150 // IDs of messages that we have successfully downloaded. This does _not_ mean 0151 // that the messages corresponding to the IDs are stored in Akonadi yet 0152 QList<int> mDownloadedIDs; 0153 0154 // IDs of messages that we want to download and that we have started the 0155 // FetchJob with. After the FetchJob, this should be empty, except if there 0156 // was some error 0157 QList<int> mIdsToDownload; 0158 0159 // After downloading a message, we store it in Akonadi by using an ItemCreateJob. 0160 // This map stores the currently running ItemCreateJob's and their corresponding 0161 // POP3 IDs. 0162 // When an ItemCreateJob finished, it is removed from this map. 0163 // The Save state waits until this map becomes empty. 0164 QMap<Akonadi::ItemCreateJob *, int> mPendingCreateJobs; 0165 0166 // List of message IDs that were successfully stored in Akonadi 0167 QList<int> mIDsStored; 0168 0169 // List of message IDs that were successfully deleted 0170 QList<int> mDeletedIDs; 0171 0172 // List of message IDs that we want to delete with the next delete job 0173 QList<int> mIdsWaitingToDelete; 0174 0175 // List of message IDs that we want to keep on the server 0176 mutable QSet<int> mIdsToSave; 0177 mutable bool mIdsToSaveValid; 0178 0179 // Current deletion job in process 0180 DeleteJob *mDeleteJob = nullptr; 0181 0182 Settings mSettings; 0183 };