TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

647 lines
21KB

  1. /* -*- c++ -*-
  2. * imapaccountbase.h
  3. *
  4. * Copyright (c) 2000-2002 Michael Haeckel <haeckel@kde.org>
  5. * Copyright (c) 2002 Marc Mutz <mutz@kde.org>
  6. *
  7. * This file is based on work on pop3 and imap account implementations
  8. * by Don Sanders <sanders@kde.org> and Michael Haeckel <haeckel@kde.org>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; version 2 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, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. */
  23. #ifndef __KMAIL_IMAPACCOUNTBASE_H__
  24. #define __KMAIL_IMAPACCOUNTBASE_H__
  25. #include <set>
  26. #include "networkaccount.h"
  27. #include <tqtimer.h>
  28. #include <tqguardedptr.h>
  29. #include <tdeio/global.h>
  30. class AccountManager;
  31. class KMFolder;
  32. class TDEConfig/*Base*/;
  33. class KMMessagePart;
  34. class DwBodyPart;
  35. class DwMessage;
  36. class FolderStorage;
  37. template <typename T> class TQValueVector;
  38. namespace TDEIO {
  39. class Job;
  40. }
  41. namespace KPIM {
  42. class ProgressItem;
  43. }
  44. namespace KMail {
  45. struct ACLListEntry;
  46. struct QuotaInfo;
  47. typedef TQValueVector<KMail::ACLListEntry> ACLList;
  48. class AttachmentStrategy;
  49. class ImapAccountBase : public KMail::NetworkAccount {
  50. Q_OBJECT
  51. protected:
  52. ImapAccountBase( AccountManager * parent, const TQString & name, uint id );
  53. public:
  54. virtual ~ImapAccountBase();
  55. /** Set the config options to a decent state */
  56. virtual void init();
  57. /** A weak assignment operator */
  58. virtual void pseudoAssign( const KMAccount * a );
  59. /** @return whether to automatically expunge deleted messages when
  60. leaving the folder */
  61. bool autoExpunge() const { return mAutoExpunge; }
  62. virtual void setAutoExpunge( bool expunge );
  63. /** @return whether to show hidden files on the server */
  64. bool hiddenFolders() const { return mHiddenFolders; }
  65. virtual void setHiddenFolders( bool show );
  66. /** @return whether to show only subscribed folders */
  67. bool onlySubscribedFolders() const { return mOnlySubscribedFolders; }
  68. virtual void setOnlySubscribedFolders( bool show );
  69. /** @return whether to show only locally subscribed folders */
  70. bool onlyLocallySubscribedFolders() const { return mOnlyLocallySubscribedFolders; }
  71. virtual void setOnlyLocallySubscribedFolders( bool show );
  72. /** @return whether to load attachments on demand */
  73. bool loadOnDemand() const { return mLoadOnDemand; }
  74. virtual void setLoadOnDemand( bool load );
  75. /** @return whether to list only open folders */
  76. bool listOnlyOpenFolders() const { return mListOnlyOpenFolders; }
  77. virtual void setListOnlyOpenFolders( bool only );
  78. /** Configure the slave by adding to the meta data map */
  79. virtual TDEIO::MetaData slaveConfig() const;
  80. virtual void readConfig( TDEConfig& config );
  81. virtual void writeConfig( TDEConfig& config );
  82. /**
  83. * The state of the tdeioslave connection
  84. */
  85. enum ConnectionState { Error = 0, Connected, Connecting };
  86. // possible list types
  87. enum ListType {
  88. List,
  89. ListSubscribed,
  90. ListSubscribedNoCheck,
  91. ListFolderOnly,
  92. ListFolderOnlySubscribed
  93. };
  94. /**
  95. * Connect to the server, if no connection is active
  96. * Returns Connected (ok), Error (ko) or Connecting - which means
  97. * that one should wait for the slaveConnected signal from TDEIO::Scheduler
  98. * before proceeding.
  99. */
  100. ConnectionState makeConnection();
  101. // namespace defines
  102. enum imapNamespace { PersonalNS=0, OtherUsersNS=1, SharedNS=2 };
  103. // map a namespace type to a list of namespaces
  104. typedef TQMap<imapNamespace, TQStringList> nsMap;
  105. // map a namespace to a delimiter
  106. typedef TQMap<TQString, TQString> namespaceDelim;
  107. // map a namespace type to a map with the namespace and the delimiter
  108. typedef TQMap<imapNamespace, namespaceDelim> nsDelimMap;
  109. /**
  110. * Info Data for the Job
  111. */
  112. struct jobData
  113. {
  114. // Needed by TQMap, don't use
  115. jobData() : url(TQString()), parent(0), current(0), total(1), done(0), offset(0), progressItem(0),
  116. onlySubscribed(false), quiet(false), cancellable(false) {}
  117. // Real constructor
  118. jobData( const TQString& _url, KMFolder *_parent = 0,
  119. int _total = 1, int _done = 0, bool _quiet = false,
  120. bool _cancelable = false )
  121. : url(_url), parent(_parent), current(0), total(_total), done(_done), offset(0),
  122. progressItem(0), quiet(_quiet), cancellable(_cancelable) {}
  123. TQString path;
  124. TQString url;
  125. TQString curNamespace;
  126. TQByteArray data;
  127. TQCString cdata;
  128. TQStringList items;
  129. KMFolder *parent, *current;
  130. TQPtrList<KMMessage> msgList;
  131. int total, done, offset;
  132. KPIM::ProgressItem *progressItem;
  133. bool onlySubscribed, quiet, cancellable;
  134. };
  135. typedef TQMap<TDEIO::Job *, jobData>::Iterator JobIterator;
  136. /**
  137. * Call this when starting a new job
  138. */
  139. void insertJob( TDEIO::Job* job, const jobData& data ) {
  140. mapJobData.insert( job, data );
  141. }
  142. /**
  143. * Look for the jobData related to a given job. Compare with end()
  144. */
  145. JobIterator findJob( TDEIO::Job* job ) { return mapJobData.find( job ); }
  146. JobIterator jobsEnd() { return mapJobData.end(); }
  147. /**
  148. * Call this when a job is finished.
  149. * Don't use @p *it afterwards!
  150. */
  151. void removeJob( JobIterator& it );
  152. void removeJob( TDEIO::Job* job );
  153. /**
  154. * Subscribe (@p subscribe = TRUE) / Unsubscribe the folder
  155. * identified by @p imapPath.
  156. * Emits subscriptionChanged signal on success.
  157. * Emits subscriptionChangeFailed signal when it fails.
  158. * @param quiet if false, an error message will be displayed if the job fails.
  159. */
  160. void changeSubscription(bool subscribe, const TQString& imapPath, bool quiet = false );
  161. /**
  162. * Returns whether the account is locally subscribed to the
  163. * folder @param imapPath. No relation to server side subscription above.
  164. */
  165. bool locallySubscribedTo( const TQString& imapPath );
  166. /**
  167. * Locally subscribe (@p subscribe = TRUE) / Unsubscribe the folder
  168. * identified by @p imapPath.
  169. */
  170. void changeLocalSubscription( const TQString& imapPath, bool subscribe );
  171. /**
  172. * Retrieve the users' right on the folder
  173. * identified by @p folder and @p imapPath.
  174. * Emits receivedUserRights signal on success/error.
  175. */
  176. void getUserRights( KMFolder* folder, const TQString& imapPath );
  177. /**
  178. * Retrieve the complete list of ACLs on the folder
  179. * identified by @p imapPath.
  180. * Emits receivedACL signal on success/error.
  181. */
  182. void getACL( KMFolder* folder, const TQString& imapPath );
  183. /**
  184. * Retrieve the the quota inforamiton on the folder
  185. * identified by @p imapPath.
  186. * Emits receivedQuotaInfo signal on success/error.
  187. */
  188. void getStorageQuotaInfo( KMFolder* folder, const TQString& imapPath );
  189. /**
  190. * Set the status on the server
  191. * Emits imapStatusChanged signal on success/error.
  192. */
  193. void setImapStatus( KMFolder* folder, const TQString& path, const TQCString& flags );
  194. /**
  195. * Set seen status on the server.
  196. * Emits imapStatusChanged signal on success/error.
  197. */
  198. void setImapSeenStatus( KMFolder* folder, const TQString& path, bool seen );
  199. /**
  200. * The TDEIO-Slave died
  201. */
  202. void slaveDied() { mSlave = 0; killAllJobs(); }
  203. /**
  204. * Kill the slave if any jobs are active
  205. */
  206. void killAllJobs( bool disconnectSlave=false ) = 0;
  207. /**
  208. * Abort all running mail checks. Used when exiting.
  209. */
  210. virtual void cancelMailCheck();
  211. /**
  212. * Init a new-mail-check for a single folder, and optionally its subfolders.
  213. */
  214. enum FolderListType { Single, Recursive };
  215. void processNewMailInFolder( KMFolder* folder, FolderListType type = Single );
  216. /**
  217. * Return true if we are processing a mailcheck for a single folder
  218. */
  219. bool checkingSingleFolder() { return mCheckingSingleFolder; }
  220. /**
  221. * Called when we're completely done checking mail for this account
  222. * When @p setStatusMsg is true a status msg is shown
  223. */
  224. void postProcessNewMail( bool setStatusMsg = true );
  225. /**
  226. * Check whether we're checking for new mail
  227. * and the folder is included
  228. */
  229. bool checkingMail( KMFolder *folder );
  230. bool checkingMail() { return NetworkAccount::checkingMail(); }
  231. /**
  232. * Handles the result from a BODYSTRUCTURE fetch
  233. */
  234. void handleBodyStructure( TQDataStream & stream, KMMessage * msg,
  235. const AttachmentStrategy *as );
  236. /**
  237. * Reimplemented. Additionally set the folder label
  238. */
  239. virtual void setFolder(KMFolder*, bool addAccount = false);
  240. /**
  241. * Returns false if the IMAP server for this account doesn't support ACLs.
  242. * (and true if it does, or if we didn't try yet).
  243. */
  244. bool hasACLSupport() const { return mACLSupport; }
  245. /**
  246. * Returns false if the IMAP server for this account doesn't support annotations.
  247. * (and true if it does, or if we didn't try yet).
  248. */
  249. bool hasAnnotationSupport() const { return mAnnotationSupport; }
  250. /**
  251. * Called if the annotation command failed due to 'unsupported'
  252. */
  253. void setHasNoAnnotationSupport() { mAnnotationSupport = false; }
  254. /**
  255. * Returns false if the IMAP server for this account doesn't support quotas.
  256. * (and true if it does, or if we didn't try yet).
  257. */
  258. bool hasQuotaSupport() const { return mQuotaSupport; }
  259. /**
  260. * Called if the quota command failed due to 'unsupported'
  261. */
  262. void setHasNoQuotaSupport() { mQuotaSupport = false; }
  263. /**
  264. * React to an error from the job. Uses job->error and job->errorString and calls
  265. * the protected virtual handleJobError with them. See handleError below for details.
  266. */
  267. bool handleJobError( TDEIO::Job* job, const TQString& context, bool abortSync = false );
  268. /**
  269. * Returns the root folder of this account
  270. */
  271. virtual FolderStorage* rootFolder() const = 0;
  272. /**
  273. * Progress item for listDir
  274. */
  275. KPIM::ProgressItem* listDirProgressItem();
  276. /**
  277. * @return the number of (subscribed, if applicable) folders in this
  278. * account.
  279. */
  280. virtual unsigned int folderCount() const;
  281. /**
  282. * @return defined namespaces
  283. */
  284. nsMap namespaces() const { return mNamespaces; }
  285. /**
  286. * Set defined namespaces
  287. */
  288. virtual void setNamespaces( nsMap map )
  289. { mNamespaces = map; }
  290. /**
  291. * Full blown section - namespace - delimiter map
  292. * Do not call this very often as the map is constructed on the fly
  293. */
  294. nsDelimMap namespacesWithDelimiter();
  295. /**
  296. * @return the namespace for the @p folder
  297. */
  298. TQString namespaceForFolder( FolderStorage* );
  299. /**
  300. * Adds "/" as needed to the given namespace
  301. */
  302. TQString addPathToNamespace( const TQString& ns );
  303. /**
  304. * @return the delimiter for the @p namespace
  305. */
  306. TQString delimiterForNamespace( const TQString& prefix );
  307. /**
  308. * @return the delimiter for the @p folderstorage
  309. */
  310. TQString delimiterForFolder( FolderStorage* );
  311. /**
  312. * @return the namespace - delimiter map
  313. */
  314. namespaceDelim namespaceToDelimiter() const
  315. { return mNamespaceToDelimiter; }
  316. /**
  317. * Set the namespace - delimiter map
  318. */
  319. void setNamespaceToDelimiter( namespaceDelim map )
  320. { mNamespaceToDelimiter = map; }
  321. /**
  322. * Returns true if the given string is a namespace
  323. */
  324. bool isNamespaceFolder( TQString& name );
  325. /**
  326. * Returns true if the account has the given capability
  327. */
  328. bool hasCapability( const TQString& capa ) {
  329. return mCapabilities.contains( capa ); }
  330. /**
  331. * Create an IMAP path for a parent folder and a foldername
  332. * Parent and folder are separated with the delimiter of the account
  333. * The path starts and ends with '/'
  334. */
  335. TQString createImapPath( FolderStorage* parent, const TQString& folderName );
  336. /**
  337. * Create an IMAP path for a parent imapPath and a folderName
  338. */
  339. TQString createImapPath( const TQString& parent, const TQString& folderName );
  340. public slots:
  341. /**
  342. * Call this to get the namespaces
  343. * You are notified by the signal namespacesFetched
  344. */
  345. void getNamespaces();
  346. private slots:
  347. /**
  348. * is called when the changeSubscription has finished
  349. * emits subscriptionChanged
  350. */
  351. void slotSubscriptionResult(TDEIO::Job * job);
  352. protected slots:
  353. virtual void slotCheckQueuedFolders();
  354. /// Handle a message coming from the TDEIO scheduler saying that the slave is now connected
  355. void slotSchedulerSlaveConnected(TDEIO::Slave *aSlave);
  356. /// Handle an error coming from the TDEIO scheduler
  357. void slotSchedulerSlaveError(TDEIO::Slave *aSlave, int, const TQString &errorMsg);
  358. /**
  359. * Only delete information about the job and ignore write errors
  360. */
  361. void slotSetStatusResult(TDEIO::Job * job);
  362. /// Result of getUserRights() job
  363. void slotGetUserRightsResult( TDEIO::Job* _job );
  364. /// Result of getACL() job
  365. void slotGetACLResult( TDEIO::Job* _job );
  366. /// Result of getStorageQuotaInfo() job
  367. void slotGetStorageQuotaInfoResult( TDEIO::Job* _job );
  368. /**
  369. * Send a NOOP command regularly to keep the slave from disconnecting
  370. */
  371. void slotNoopTimeout();
  372. /**
  373. * Log out when idle
  374. */
  375. void slotIdleTimeout();
  376. /**
  377. * Kills all jobs
  378. */
  379. void slotAbortRequested( KPIM::ProgressItem* );
  380. /**
  381. * Only delete information about the job
  382. */
  383. void slotSimpleResult(TDEIO::Job * job);
  384. /** Gets and parses the namespaces */
  385. void slotNamespaceResult( TDEIO::Job*, const TQString& str );
  386. /**
  387. * Saves the fetched namespaces
  388. */
  389. void slotSaveNamespaces( const ImapAccountBase::nsDelimMap& map );
  390. /**
  391. * Saves the capabilities list
  392. */
  393. void slotCapabilitiesResult( TDEIO::Job*, const TQString& result );
  394. protected:
  395. /**
  396. * Handle an error coming from a TDEIO job or from a TDEIO slave (via the scheduler)
  397. * and abort everything (in all cases) if abortSync is true [this is for slotSchedulerSlaveError].
  398. * Otherwise (abortSync==false), dimap will only abort in case of severe errors (connection broken),
  399. * but on "normal" errors (no permission to delete, etc.) it will ask the user.
  400. *
  401. * @param error the error code, usually job->error())
  402. * @param errorMsg the error message, usually job->errorText()
  403. * @param job the tdeio job (can be 0). If set, removeJob will be called automatically.
  404. * This is important! It means you should not call removeJob yourself in case of errors.
  405. * We can't let the caller do that, since it should only be done afterwards, and only if we didn't abort.
  406. *
  407. * @param context a sentence that gives some context to the error, e.g. i18n("Error while uploading message [...]")
  408. * @param abortSync if true, abort sync in all cases (see above). If false, ask the user (when possible).
  409. * @return false when aborting, true when continuing
  410. */
  411. virtual bool handleError( int error, const TQString &errorMsg, TDEIO::Job* job, const TQString& context, bool abortSync = false );
  412. /** Handle an error during TDEIO::put - helper method */
  413. bool handlePutError( TDEIO::Job* job, jobData& jd, KMFolder* folder );
  414. virtual TQString protocol() const;
  415. virtual unsigned short int defaultPort() const;
  416. /**
  417. * Build KMMessageParts and DwBodyParts from the bodystructure-stream
  418. */
  419. void constructParts( TQDataStream & stream, int count, KMMessagePart* parentKMPart,
  420. DwBodyPart * parent, const DwMessage * dwmsg );
  421. /** Migrate the prefix */
  422. void migratePrefix();
  423. // used for writing the blacklist out to the config file
  424. TQStringList locallyBlacklistedFolders() const;
  425. void localBlacklistFromStringList( const TQStringList & );
  426. TQString prettifyQuotaError( const TQString& _error, TDEIO::Job * job );
  427. protected:
  428. TQPtrList<TQGuardedPtr<KMFolder> > mOpenFolders;
  429. TQStringList mSubfolderNames, mSubfolderPaths,
  430. mSubfolderMimeTypes, mSubfolderAttributes;
  431. TQMap<TDEIO::Job *, jobData> mapJobData;
  432. /** used to detect when the slave has not been used for a while */
  433. TQTimer mIdleTimer;
  434. /** used to send a noop to the slave in regular intervals to keep it from disonnecting */
  435. TQTimer mNoopTimer;
  436. int mTotal, mCountUnread, mCountLastUnread;
  437. TQMap<TQString, int> mUnreadBeforeCheck;
  438. bool mAutoExpunge : 1;
  439. bool mHiddenFolders : 1;
  440. bool mOnlySubscribedFolders : 1;
  441. bool mOnlyLocallySubscribedFolders : 1;
  442. bool mLoadOnDemand : 1;
  443. bool mListOnlyOpenFolders : 1;
  444. bool mProgressEnabled : 1;
  445. bool mErrorDialogIsActive : 1;
  446. bool mPasswordDialogIsActive : 1;
  447. bool mACLSupport : 1;
  448. bool mAnnotationSupport : 1;
  449. bool mQuotaSupport : 1;
  450. bool mSlaveConnected : 1;
  451. bool mSlaveConnectionError : 1;
  452. bool mCheckingSingleFolder : 1;
  453. // folders that should be checked for new mails
  454. TQValueList<TQGuardedPtr<KMFolder> > mMailCheckFolders;
  455. // folders that should be checked after the current check is done
  456. TQValueList<TQGuardedPtr<KMFolder> > mFoldersQueuedForChecking;
  457. // holds messageparts from the bodystructure
  458. TQPtrList<KMMessagePart> mBodyPartList;
  459. // the current message for the bodystructure
  460. KMMessage* mCurrentMsg;
  461. TQGuardedPtr<KPIM::ProgressItem> mListDirProgressItem;
  462. // our namespaces in the form section=namespaceList
  463. nsMap mNamespaces;
  464. // namespace - delimiter map
  465. namespaceDelim mNamespaceToDelimiter;
  466. // old prefix for migration
  467. TQString mOldPrefix;
  468. // capabilities
  469. TQStringList mCapabilities;
  470. std::set<TQString> mLocalSubscriptionBlackList;
  471. signals:
  472. /**
  473. * Emitted when the slave managed or failed to connect
  474. * This is always emitted at some point after makeConnection returned Connecting.
  475. * @param errorCode 0 for success, != 0 in case of error
  476. * @param errorMsg if errorCode is != 0, this goes with errorCode to call TDEIO::buildErrorString
  477. */
  478. void connectionResult( int errorCode, const TQString& errorMsg );
  479. /**
  480. * Emitted when the subscription has changed,
  481. * as a result of a changeSubscription call.
  482. */
  483. void subscriptionChanged(const TQString& imapPath, bool subscribed);
  484. /**
  485. * Emitted when changeSubscription() failed.
  486. * @param errorMessage the error message that contains the reason for the failure
  487. */
  488. void subscriptionChangeFailed( const TQString &errorMessage );
  489. /**
  490. * Emitted upon completion of the job for setting the status for a group of UIDs,
  491. * as a result of a setImapStatus call.
  492. * On error, if the user chooses abort (not continue), cont is set to false.
  493. */
  494. void imapStatusChanged( KMFolder*, const TQString& imapPath, bool cont );
  495. /**
  496. * Emitted when the get-user-rights job is done,
  497. * as a result of a getUserRights call.
  498. * Use userRights() to retrieve them after using userRightsState() to see if the results are
  499. * valid.
  500. */
  501. void receivedUserRights( KMFolder* folder );
  502. /**
  503. * Emitted when the get-the-ACLs job is done,
  504. * as a result of a getACL call.
  505. * @param folder the folder for which we were listing the ACLs (can be 0)
  506. * @param job the job that was used for doing so (can be used to display errors)
  507. * @param entries the ACL list. Make your copy of it, it comes from the job.
  508. */
  509. void receivedACL( KMFolder* folder, TDEIO::Job* job, const KMail::ACLList& entries );
  510. /**
  511. * Emitted when the getQuotaInfo job is done,
  512. * as a result of a getQuotaInfo call.
  513. * @param folder The folder for which we were getting quota info (can be 0)
  514. * @param job The job that was used for doing so (can be used to display errors)
  515. * @param info The quota information for this folder. Make your copy of it,
  516. * it comes from the job.
  517. */
  518. void receivedStorageQuotaInfo( KMFolder* folder, TDEIO::Job* job, const KMail::QuotaInfo& entries );
  519. /**
  520. * Emitted when we got the namespaces
  521. */
  522. void namespacesFetched( const ImapAccountBase::nsDelimMap& );
  523. /**
  524. * Emitted when we got the namespaces, and they were set on the object.
  525. */
  526. void namespacesFetched();
  527. };
  528. } // namespace KMail
  529. #endif // __KMAIL_IMAPACCOUNTBASE_H__