b54c9f4f4c95968455d093840a46f661149bd2a8
[claws.git] / src / folder.h
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /*
4  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
5  * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  * 
20  */
21
22 #ifndef __FOLDER_H__
23 #define __FOLDER_H__
24
25 #include <glib.h>
26 #include <time.h>
27
28 typedef struct _Folder          Folder;
29 typedef struct _FolderClass     FolderClass;
30
31 typedef struct _FolderItem      FolderItem;
32 typedef struct _FolderUpdateData        FolderUpdateData;
33 typedef struct _FolderItemUpdateData    FolderItemUpdateData;
34 typedef struct _PersistPrefs            PersistPrefs;
35
36 #define FOLDER(obj)             ((Folder *)obj)
37 #define FOLDER_CLASS(obj)       (FOLDER(obj)->klass)
38 #define FOLDER_TYPE(obj)        (FOLDER(obj)->klass->type)
39
40 #define FOLDER_IS_LOCAL(obj)    (FOLDER_TYPE(obj) == F_MH      || \
41                                  FOLDER_TYPE(obj) == F_MBOX    || \
42                                  FOLDER_TYPE(obj) == F_MAILDIR)
43
44 #define FOLDER_ITEM(obj)        ((FolderItem *)obj)
45
46 #define FOLDER_UPDATE_HOOKLIST "folder_update"
47 #define FOLDER_ITEM_UPDATE_HOOKLIST "folder_item_update"
48
49 typedef enum
50 {
51         F_MH,
52         F_MBOX,
53         F_MAILDIR,
54         F_IMAP,
55         F_NEWS,
56         F_UNKNOWN
57 } FolderType;
58
59 typedef enum
60 {
61         F_NORMAL,
62         F_INBOX,
63         F_OUTBOX,
64         F_DRAFT,
65         F_QUEUE,
66         F_TRASH
67 } SpecialFolderItemType;
68
69 typedef enum
70 {
71         SORT_BY_NONE,
72         SORT_BY_NUMBER,
73         SORT_BY_SIZE,
74         SORT_BY_DATE,
75         SORT_BY_FROM,
76         SORT_BY_SUBJECT,
77         SORT_BY_SCORE,
78         SORT_BY_LABEL,
79         SORT_BY_MARK,
80         SORT_BY_STATUS,
81         SORT_BY_MIME,
82         SORT_BY_TO,
83         SORT_BY_LOCKED,
84         SORT_BY_TAGS,
85         SORT_BY_THREAD_DATE
86 } FolderSortKey;
87
88 typedef enum
89 {
90         SORT_ASCENDING,
91         SORT_DESCENDING
92 } FolderSortType;
93
94 typedef enum
95 {
96         F_MOVE_OK = 0,
97         F_MOVE_FAILED_DEST_IS_PARENT = -1,
98         F_MOVE_FAILED_DEST_IS_CHILD = -2,
99         F_MOVE_FAILED_DEST_OUTSIDE_MAILBOX = -3,
100         F_MOVE_FAILED = -4
101 } FolderItemMoveResult;
102
103 typedef enum
104 {
105         FOLDER_ADD_FOLDER               = 1 << 0,
106         FOLDER_REMOVE_FOLDER            = 1 << 1,
107         FOLDER_TREE_CHANGED             = 1 << 2,
108         FOLDER_ADD_FOLDERITEM           = 1 << 3,
109         FOLDER_REMOVE_FOLDERITEM        = 1 << 4,
110         FOLDER_RENAME_FOLDERITEM        = 1 << 5
111 } FolderUpdateFlags;
112
113 typedef enum
114 {
115         F_ITEM_UPDATE_MSGCNT = 1 << 0,
116         F_ITEM_UPDATE_CONTENT = 1 << 1,
117         F_ITEM_UPDATE_ADDMSG = 1 << 2,
118         F_ITEM_UPDATE_REMOVEMSG = 1 << 3,
119         F_ITEM_UPDATE_NAME = 1 << 4
120 } FolderItemUpdateFlags;
121
122 typedef void (*FolderUIFunc)            (Folder         *folder,
123                                          FolderItem     *item,
124                                          gpointer        data);
125 typedef void (*FolderDestroyNotify)     (Folder         *folder,
126                                          FolderItem     *item,
127                                          gpointer        data);
128 typedef void (*FolderItemFunc)  (FolderItem     *item,
129                                          gpointer        data);
130
131
132 #include "proctypes.h"
133 #include "xml.h"
134 #include "prefs_account.h"
135 #include "matchertypes.h"
136
137 struct _MsgCache;
138
139 struct _Folder
140 {
141         FolderClass *klass;
142
143         gchar *name;
144         PrefsAccount *account;
145         guint sort;
146
147         FolderItem *inbox;
148         FolderItem *outbox;
149         FolderItem *draft;
150         FolderItem *queue;
151         FolderItem *trash;
152
153         FolderUIFunc ui_func;
154         gpointer     ui_func_data;
155
156         GNode *node;
157
158         gpointer data;
159
160         GHashTable *newsart;
161 };
162
163 /**
164  * Callback used to convey progress information of a specific search.
165  *
166  * \param data User-provided data
167  * \param on_server Whether or not the current progress information originated from the
168  *                  server
169  * \param at Number of the last message processed
170  * \param matched Number of messages with definitive matches found so far
171  * \param total Number of messages to be processed
172  *
173  * \note
174  * Even if the mailserver does not support progress reports, an instance of this type
175  * should be invoked when serverside search starts and ends, with \c at set to \c 0 and
176  * \c total, respectively.
177  */
178 typedef gboolean (*SearchProgressNotify)(gpointer data, gboolean on_server, guint at, guint matched, guint total);
179
180 struct _FolderClass
181 {
182         /**
183          * A numeric identifier for the FolderClass. Will be removed in the future
184          */
185         FolderType  type;
186         /**
187          * A string identifier for the FolderClass. Currently used in folderlist.xml.
188          * Should be lowercase.
189          */
190         gchar      *idstr;
191         /**
192          * A string for the User Interface that identifies the FolderClass to the
193          * user. Can be upper and lowercase unlike the idstr.
194          */
195         gchar      *uistr;
196         /**
197         * A boolean to indicate whether or not the FolderClass supports search on the
198         * server. If \c TRUE, setting \c on_server in \c search_msgs offloads search to
199         * the server.
200         */
201         gboolean    supports_server_search;
202
203         /**
204          * Klass-specific prefs pages
205          */
206         
207         GSList *prefs_pages;
208
209         /* virtual functions */
210
211         /* Folder funtions */
212         /**
213          * Create a new \c Folder of this \c FolderClass.
214          *
215          * \param name The name of the new Folder
216          * \param path The path of the new Folder
217          * \return The new \c Folder, or \c NULL when creating the \c Folder 
218          *         failed
219          */
220         Folder          *(*new_folder)          (const gchar    *name,
221                                                  const gchar    *path);
222         /**
223          * Destroy a \c Folder of this \c FolderClass, frees all resources
224          * allocated by the Folder
225          *
226          * \param folder The \c Folder that should be destroyed.
227          */
228         void            (*destroy_folder)       (Folder         *folder);
229         /**
230          * Set the Folder's internal attributes from an \c XMLTag. Also sets the
231          * parameters of the root-FolderItem of the \c Folder. If \c NULL
232          * the default function of the basic \ยข FolderClass is used, so it
233          * must not be \c NULL if one of the parent \c FolderClasses has a \c set_xml
234          * function. In that case the parent \c FolderClass' \c set_xml function
235          * can be used or it has to be called with the \c folder and \c tag by
236          * the implementation.
237          *
238          * \param folder The \c Folder which's attributes should be updated
239          * \param tag The \c XMLTag containing the \c XMLAttrs for the attributes
240          */
241         void             (*set_xml)             (Folder         *folder,
242                                                  XMLTag         *tag);
243         /**
244          * Get an \c XMLTag for the attributes of the \c Folder and the root-FolderItem
245          * of the \c Folder. If \c NULL the default implementation for the basic
246          * FolderClass will be used, so it must not be \c NULL if one of the
247          * parent \c FolderClasses has it's own implementation for \c get_xml.
248          * In that case the parent FolderClass' \c get_xml function can be
249          * used or the \c XMLTag has to be fetched from the parent's \c get_xml
250          * function and then the \c FolderClass specific attributes can be
251          * added to it.
252          *
253          * \param Folder The \c Folder which's attributes should be set in the
254          *               \c XMLTag's \c XMLAttrs
255          * \return XMLTag An \c XMLTag with \c XMLAttrs containing the \c Folder's
256          *                attributes.
257          */
258         XMLTag          *(*get_xml)             (Folder         *folder);
259         /**
260          * Rebuild the folder tree from the folder's data
261          * \todo New implementations of MH and IMAP are actually syncronizing
262          *       the tree with the folder by reusing the old \c FolderItems.
263          *       Claws still destroys the old tree before calling this function.
264          *
265          * \param folder The folder which's tree should be rebuild
266          * \return 0 on success, a negative number otherwise
267          */
268         gint            (*scan_tree)            (Folder         *folder);
269
270         gint            (*create_tree)          (Folder         *folder);
271
272         /* FolderItem functions */
273         /**
274          * Create a new \c FolderItem structure for the \c FolderClass.
275          * \c FolderClasses can have their own \c FolderItem structure with
276          * extra attributes.
277          *
278          * \param folder The \c Folder for that a \c FolderItem should be
279          *               created
280          * \return The new \c FolderItem or NULL in case of an error
281          */
282         FolderItem      *(*item_new)            (Folder         *folder);
283         /**
284          * Destroy a \c FolderItem from this \c FolderClass. The \c FolderClass
285          * has to free all private resources used by the \c FolderItem.
286          *
287          * \param folder The \c Folder of the \c FolderItem
288          * \param item The \c FolderItem that should be destroyed
289          */
290         void             (*item_destroy)        (Folder         *folder,
291                                                  FolderItem     *item);
292         /**
293          * Set the \c FolderItem's internal attributes from an \c XMLTag. If
294          * \c NULL the default function of the basic \c FolderClass is used, so it
295          * must not be \c NULL if one of the parent \c FolderClasses has a \c item_set_xml
296          * function. In that case the parent \c FolderClass' \c item_set_xml function
297          * can be used or it has to be called with the \c folder, \c item and \c tag by
298          * the implementation.
299          *
300          * \param folder The \c Folder of the \c FolderItem
301          * \param item The \c FolderItems which's attributes should be set
302          * \param tag The \c XMLTag with \c XMLAttrs for the \c FolderItem's
303          *            attributes
304          */
305         void             (*item_set_xml)        (Folder         *folder,
306                                                  FolderItem     *item,
307                                                  XMLTag         *tag);
308         /**
309          * Get an \c XMLTag for the attributes of the \c FolderItem If \c NULL
310          * the default implementation for the basic \c FolderClass will be used,
311          * so it must not be \c NULL if one of the parent \c FolderClasses has
312          * it's own implementation for \c item_get_xml. In that case the parent 
313          * FolderClass' \c item_get_xml function can be used or the \c XMLTag
314          * has to be fetched from the parent's \c item_get_xml function and 
315          * then the \c FolderClass specific attributes can be added to it.
316          *
317          * \param folder The \c Folder of the \c FolderItem
318          * \parem item The \c FolderItem which's attributes should be set in
319          *             the \c XMLTag's \c XMLAttrs
320          * \return An \c XMLTag with \c XMLAttrs containing the \c FolderItem's
321          *         attributes.
322          */
323         XMLTag          *(*item_get_xml)        (Folder         *folder,
324                                                  FolderItem     *item);
325         /**
326          * Get a local path for the \c FolderItem where Sylpheed can save
327          * it's cache data. For local directory based folders this can be the
328          * real path. For other folders it can be the local cache directory.
329          *
330          * \param folder The \c Folder of the \c FolderItem
331          * \param item The \c FolderItem for that a path should be returned
332          * \return A path for the \c FolderItem
333          */
334         gchar           *(*item_get_path)       (Folder         *folder,
335                                                  FolderItem     *item);
336         /**
337          * Create a new \c FolderItem. The function must use folder_item_append
338          * to add the new \c FolderItem to the folder tree
339          *
340          * \param folder The \c Folder in which a new \c FolderItem should be
341          *               created
342          * \param parent \c The parent \c FolderItem for the new \c FolderItem
343          * \parem name The name for the new \c FolderItem
344          * \return The new \c FolderItem
345          */
346         FolderItem      *(*create_folder)       (Folder         *folder,
347                                                  FolderItem     *parent,
348                                                  const gchar    *name);
349         /**
350          * Rename a \c FolderItem
351          *
352          * \param folder The \c Folder of the \c FolderItem that should be
353          *               renamed
354          * \param item The \c FolderItem that should be renamed
355          * \param name The new name of the \c FolderItem
356          * \return 0 on success, a negative number otherwise
357          */
358         gint             (*rename_folder)       (Folder         *folder,
359                                                  FolderItem     *item,
360                                                  const gchar    *name);
361         /**
362          * Remove a \c FolderItem from the \c Folder
363          *
364          * \param folder The \c Folder that contains the \c FolderItem
365          * \param item The \c FolderItem that should be removed
366          * \return 0 on sucess, a negative number otherwise
367          */
368         gint             (*remove_folder)       (Folder         *folder,
369                                                  FolderItem     *item);
370         /**
371          * Close a \c FolderItem. Called when the user deselects a
372          * \c FolderItem.
373          * 
374          * \attention In Sylpheed-Main operations can only be done on the
375          *            \c FolderItem that is opened in the SummaryView. This
376          *            \c FolderItem will be closed when you select a new
377          *            \c FolderItem in the FolderView. In Claws operations can
378          *            be done any time on any folder and you should not expect
379          *            that all \c FolderItems get closed after operations
380          *
381          * \param folder The \c Folder that contains the \c FolderItem
382          * \param item The \c FolderItem that should be closed
383          * \return 0 on success, a negative number otherwise
384          */
385         gint             (*close)               (Folder         *folder,
386                                                  FolderItem     *item);
387         /**
388          * Get the list of message numbers for the messages in the \c FolderItem
389          *
390          * \param folder The \c Folder that contains the \c FolderItem
391          * \param item The \c FolderItem for which the message numbers should
392          *             be fetched
393          * \param list Pointer to a GSList where message numbers have to be
394          *             added. Because of the implementation of the GSList that
395          *             changes the pointer of the GSList itself when the first
396          *             item is added this is a pointer to a pointer to a
397          *             GSList structure. Use *item = g_slist_...(*item, ...)
398          *             operations to modify the list.
399          * \param old_uids_valid In some \c Folders the old UIDs can be invalid.
400          *                       Set this pointer to a gboolean to TRUE if the
401          *                       old UIDs are still valid, otherwise set it to
402          *                       FALSE and the folder system will discard it's
403          *                       cache data of the previously know UIDs
404          * \return The number of message numbers add to the list on success,
405          *         a negative number otherwise.
406          */
407         gint             (*get_num_list)        (Folder         *folder,
408                                                  FolderItem     *item,
409                                                  GSList        **list,
410                                                  gboolean       *old_uids_valid);
411         /**
412          * Tell the folder system if a \c FolderItem should be scanned
413          * (cache data syncronized with the folder content) when it is required
414          * because the \c FolderItem's content changed. If NULL the folder
415          * system will not do automatic scanning of \c FolderItems
416          *
417          * \param folder The \c Folder that contains the \c FolderItem
418          * \param item The \c FolderItem which's content should be checked
419          * \return TRUE if the \c FolderItem should be scanned, FALSE otherwise
420          */
421         gboolean        (*scan_required)        (Folder         *folder,
422                                                  FolderItem     *item);
423
424         /**
425          * Updates the known mtime of a folder
426          */
427         void            (*set_mtime)            (Folder         *folder,
428                                                  FolderItem     *item);
429
430         /* Message functions */
431         /**
432          * Get a MsgInfo for a message in a \c FolderItem
433          *
434          * \param folder The \c Folder containing the message
435          * \param item The \c FolderItem containing the message
436          * \param num The message number of the message
437          * \return A pointer to a \c MsgInfo decribing the message or \c 
438          *         NULL in case of an error
439          */
440         MsgInfo         *(*get_msginfo)         (Folder         *folder,
441                                                  FolderItem     *item,
442                                                  gint            num);
443         /**
444          * Get \c MsgInfos for a list of message numbers
445          *
446          * \param folder The \c Folder containing the message
447          * \param item The \c FolderItem containing the message
448          * \param msgnum_list A list of message numbers for which the
449          *                    \c MsgInfos should be fetched
450          * \return A list of \c MsgInfos for the messages in the \c msgnum_list
451          *         that really exist. Messages that are not found can simply
452          *         be left out.
453          */
454         MsgInfoList     *(*get_msginfos)        (Folder         *folder,
455                                                  FolderItem     *item,
456                                                  MsgNumberList  *msgnum_list);
457         /**
458          * Get the filename for a message. This can either be the real message
459          * file for local folders or a temporary file for remote folders.
460          *
461          * \param folder The \c Folder containing the message
462          * \param item The \c FolderItem containing the message
463          * \param num The message number of the message
464          * \return A string with the filename of the message file. The returned
465          *         string has to be freed with \c g_free(). If message is not
466          *         available return NULL.
467          */
468         gchar           *(*fetch_msg)           (Folder         *folder,
469                                                  FolderItem     *item,
470                                                  gint            num);
471         gchar           *(*fetch_msg_full)      (Folder         *folder,
472                                                  FolderItem     *item,
473                                                  gint            num,
474                                                  gboolean        headers,
475                                                  gboolean        body);
476         /**
477          * Add a single message file to a folder with the given flags (if
478          * flag handling is supported by the folder)
479          *
480          * \param folder The target \c Folder for the message
481          * \param dest the target \c FolderItem for the message
482          * \param file The file that contains the message
483          * \param flags The flags the new message should have in the folder
484          * \return 0 on success, a negative number otherwise
485          */
486         gint            (*add_msg)              (Folder         *folder,
487                                                  FolderItem     *dest,
488                                                  const gchar    *file,
489                                                  MsgFlags       *flags);
490         /**
491          * Add multiple messages to a \c FolderItem. If NULL the folder
492          * system will add messages with \c add_msg one by one
493          *
494          * \param folder The target \c Folder for the messages
495          * \param dest the target \c FolderItem for the messages
496          * \param file_list A list of \c MsgFileInfos which contain the
497          *                  filenames and flags for the new messages
498          * \param relation Insert tuples of (MsgFileInfo, new message number) to
499          *                 provide feedback for the folder system which new
500          *                 message number a \c MsgFileInfo got in dest. Insert
501          *                 0 if the new message number is unknown.
502          */
503         gint            (*add_msgs)             (Folder         *folder,
504                                                  FolderItem     *dest,
505                                                  GSList         *file_list,
506                                                  GHashTable     *relation);
507         /**
508          * Copy a message to a FolderItem
509          *
510          * \param folder The \c Folder of the destination FolderItem
511          * \param dest The destination \c FolderItem for the message
512          * \param msginfo The message that should be copied
513          * \return The message number the copied message got, 0 if it is
514          *         unknown because message numbers are assigned by an external
515          *         system and not available after copying or a negative number
516          *         if an error occuried
517          */
518         gint            (*copy_msg)             (Folder         *folder,
519                                                  FolderItem     *dest,
520                                                  MsgInfo        *msginfo);
521         /**
522          * Copy multiple messages to a \c FolderItem. If \c NULL the folder
523          * system will use \c copy_msg to copy messages one by one.
524          *
525          * \param folder The \c Folder of the destination FolderItem
526          * \param dest The destination \c FolderItem for the message
527          * \param msglist A list of \c MsgInfos which should be copied to dest
528          * \param relation Insert tuples of (MsgInfo, new message number) to
529          *                 provide feedback for the folder system which new
530          *                 message number a \c MsgInfo got in dest. Insert
531          *                 0 if the new message number is unknown.
532          * \return 0 on success, a negative number otherwise
533          */
534         gint            (*copy_msgs)            (Folder         *folder,
535                                                  FolderItem     *dest,
536                                                  MsgInfoList    *msglist,
537                                                  GHashTable     *relation);
538
539         /**
540          * Search the given FolderItem for messages matching \c predicate.
541          * The search may be offloaded to the server if the \c folder
542          * supports server side search, as indicated by \c supports_server_search.
543          *
544          * \param folder The \c Folder of the container FolderItem
545          * \param container The \c FolderItem containing the messages to be searched
546          * \param msgs The \c MsgNumberList results will be saved to.
547          *             If <tt>*msgs != NULL</tt>, the search will be restricted to
548          *             messages whose numbers are contained therein.
549          *             If \c on_server is considered \c FALSE, messages are guaranteed to
550          *             be processed in the order they are listed in \c msgs.
551          *             On error, \c msgs will not be changed.
552          * \param on_server Whether or not the search should be offloaded to the server.
553          *                  If \c on_server is not \c NULL and points to a \c TRUE value,
554          *                  search will be done on the server. If \c predicate contains
555          *                  one or more atoms the server does not support, the value
556          *                  pointed to by \c on_server will be set to \c FALSE upon return.
557          *                  In this case, \c msgs must still contain a valid superset of
558          *                  messages actually matched by \c predicate, or this method must
559          *                  return an error.
560          *                  \c on_server may only point to a \c TRUE value if
561          *                  \c supports_server_search is also \c TRUE.
562          *                  \c NULL and pointer to \c FALSE are considered equivalent and
563          *                  will start a client-only search.
564          * \param predicate The \c MatcherList to use in the search
565          * \param progress_cb Called for every message searched.
566          *                    When search is offloaded to the server, this function
567          *                    may or may not be called, depending on the implementation.
568          *                    The second argument of this function will be the number of
569          *                    messages already processed.
570          *                    Return \c FALSE from this function to end the search.
571          *                    May be \c NULL, no calls will be made in this case.
572          * \param progress_data First argument value for \c progress_cb
573          * \return Number of messages that matched \c predicate on success, a negative
574          *         number otherwise.
575          *
576          * \note
577          * When search is stopped by returning \c FALSE from \c progress_cb, \c msgs will
578          * contain all messages found until the point of cancellation. The number of
579          * messages found will be returned as indicated above.
580          */
581         gint            (*search_msgs)          (Folder                 *folder,
582                                                  FolderItem             *container,
583                                                  MsgNumberList          **msgs,
584                                                  gboolean               *on_server,
585                                                  MatcherList            *predicate,
586                                                  SearchProgressNotify   progress_cb,
587                                                  gpointer               progress_data);
588
589
590         /**
591          * Remove a message from a \c FolderItem.
592          *
593          * \param folder The \c Folder of the message
594          * \param item The \c FolderItem containing the message
595          * \param num The message number of the message
596          * \return 0 on success, a negative number otherwise
597          */
598         gint            (*remove_msg)           (Folder         *folder,
599                                                  FolderItem     *item,
600                                                  gint            num);
601         gint            (*remove_msgs)          (Folder         *folder,
602                                                  FolderItem     *item,
603                                                  MsgInfoList    *msglist,
604                                                  GHashTable     *relation);
605         gint            (*expunge)              (Folder         *folder,
606                                                  FolderItem     *item);
607         /**
608          * Remove all messages in a \ c FolderItem
609          *
610          * \param folder The \c Folder of the \c FolderItem
611          * \param item The \FolderItem which's messages should be deleted
612          * \return 0 on succes, a negative number otherwise
613          */
614         gint            (*remove_all_msg)       (Folder         *folder,
615                                                  FolderItem     *item);
616         /**
617          * Check if a message has been modified by someone else
618          *
619          * \param folder The \c Folder of the message
620          * \param item The \c FolderItem containing the message
621          * \param msginfo The \c MsgInfo for the message that should be checked
622          * \return \c TRUE if the message was modified, \c FALSE otherwise
623          */
624         gboolean        (*is_msg_changed)       (Folder         *folder,
625                                                  FolderItem     *item,
626                                                  MsgInfo        *msginfo);
627         /**
628          * Update a message's flags in the folder data. If NULL only the
629          * internal flag management will be used. The function has to set
630          * \c msginfo->flags.perm_flags. It does not have to set the flags
631          * that it got as \c newflags. If a flag can not be set in this
632          * \c FolderClass the function can refuse to set it. Flags that are not
633          * supported by the \c FolderClass should not be refused. They will be
634          * managed by the internal cache in this case.
635          *
636          * \param folder The \c Folder of the message
637          * \param item The \c FolderItem of the message
638          * \param msginfo The \c MsgInfo for the message which's flags should be
639          *                updated
640          * \param newflags The flags the message should get
641          */
642         void            (*change_flags)         (Folder         *folder,
643                                                  FolderItem     *item,
644                                                  MsgInfo        *msginfo,
645                                                  MsgPermFlags    newflags);
646         /**
647          * Get the flags for a list of messages. Flags that are not supported
648          * by the folder should be preserved. They can be copied from
649          * \c msginfo->flags.perm_flags
650          *
651          * \param folder The \c Folder of the messages
652          * \param item The \c FolderItem of the messages
653          * \param msglist The list of \c MsgInfos for which the flags should
654          *                   be returned
655          * \param msgflags A \c GRelation for tuples of (MsgInfo, new permanent
656          *        flags for MsgInfo). Add tuples for the messages in msglist
657          * \return 0 on success, a negative number otherwise
658          */
659         gint            (*get_flags)            (Folder         *folder,
660                                                  FolderItem     *item,
661                                                  MsgInfoList    *msglist,
662                                                  GHashTable     *msgflags);
663         
664         /* Sets batch mode for a FolderItem. It means that numerous flags updates
665          * could follow, and the FolderClass implementation can cache them in order
666          * to process them later when set_false will be called again with the
667          * batch parameter set to FALSE. 
668          */
669         void            (*set_batch)            (Folder         *folder,
670                                                  FolderItem     *item,
671                                                  gboolean        batch);
672         /* Called when switching offline or asking for synchronisation. the imple
673          * mentation should do what's necessary to be able to read mails present
674          * in the FolderItem at this time with no network connectivity. 
675          * Days: max number of days of mail to fetch.
676          */
677         void            (*synchronise)          (FolderItem     *item,
678                                                  gint            days);
679         
680         /* Passed from claws-mail --subscribe scheme://uri. Implementations
681          * should check if they handle this type of URI, and return TRUE in this
682          * case after having subscribed it.
683          */
684         gboolean        (*subscribe)            (Folder         *folder,
685                                                  const gchar    *uri);
686         
687         /* Gets the preferred sort key and type for a folderclass. */
688         void            (*get_sort_type)        (Folder         *folder,
689                                                  FolderSortKey  *sort_key,
690                                                  FolderSortType *sort_type);
691         
692         /* Copies internal FolderItem data from one folderItem to another. Used
693          * when moving folders (this move is in reality a folder creation, content
694          * move, folder delettion).
695          */
696         void            (*copy_private_data)    (Folder         *folder,
697                                                  FolderItem     *src,
698                                                  FolderItem     *dest);
699
700         void            (*remove_cached_msg)    (Folder         *folder,
701                                                  FolderItem     *item,
702                                                  MsgInfo        *msginfo);
703         void            (*commit_tags)          (FolderItem     *item,
704                                                  MsgInfo        *msginfo,
705                                                  GSList         *tags_set,
706                                                  GSList         *tags_unset);
707         void            (*item_opened)          (FolderItem     *item);
708         void            (*item_closed)          (FolderItem     *item);
709 };
710
711 enum {
712         ITEM_NOT_SCANNING,
713         ITEM_SCANNING_WITH_FLAGS,
714         ITEM_SCANNING
715 };
716
717 struct _FolderItemPrefs;
718
719 struct _FolderItem
720 {
721         SpecialFolderItemType stype;
722
723         gchar *name; /* UTF-8 */
724         gchar *path; /* UTF-8 */
725
726         time_t mtime;
727
728         gint new_msgs;
729         gint unread_msgs;
730         gint total_msgs;
731         gint unreadmarked_msgs;
732         gint marked_msgs;
733         gint replied_msgs;
734         gint forwarded_msgs;
735         gint locked_msgs;
736         gint ignored_msgs;
737         gint watched_msgs;
738
739         gint order;
740
741         gint last_num;
742
743         struct _MsgCache *cache;
744         gboolean cache_dirty;
745         gboolean mark_dirty;
746         gboolean tags_dirty;
747
748         /* special flags */
749         guint no_sub         : 1; /* no child allowed?    */
750         guint no_select      : 1; /* not selectable?      */
751         guint collapsed      : 1; /* collapsed item       */
752         guint thread_collapsed      : 1; /* collapsed item       */
753         guint threaded       : 1; /* threaded folder view */
754         guint hide_read_msgs : 1; /* hide read messages   */
755         guint ret_rcpt       : 1; /* return receipt       */
756         guint search_match   : 1;
757         guint hide_del_msgs : 1; /* hide deleted messages   */
758         guint hide_read_threads : 1; /* hide threads with only read messages   */
759
760         gint op_count;
761         guint opened         : 1; /* opened by summary view */
762         FolderItemUpdateFlags update_flags; /* folderview for this folder should be updated */
763
764         FolderSortKey sort_key;
765         FolderSortType sort_type;
766
767         GNode *node;
768
769         Folder *folder;
770
771         PrefsAccount *account;
772
773         gboolean apply_sub;
774         
775         GSList *mark_queue;
776
777         gpointer data;
778
779         struct _FolderItemPrefs * prefs;
780         
781         /* for faster search of special parents */
782         SpecialFolderItemType parent_stype;
783         gboolean processing_pending;
784         gint scanning;
785         guint last_seen;
786 };
787
788 struct _PersistPrefs
789 {
790         FolderSortKey   sort_key;
791         FolderSortType  sort_type;
792         guint           collapsed       : 1;
793         guint           thread_collapsed        : 1;
794         guint           threaded        : 1;
795         guint           hide_read_msgs  : 1; /* CLAWS */
796         guint           ret_rcpt        : 1; /* CLAWS */
797         guint           hide_del_msgs   : 1; /* CLAWS */
798         guint           hide_read_threads       : 1;
799 };
800
801 struct _FolderUpdateData
802 {
803         Folder                  *folder;
804         FolderUpdateFlags        update_flags;
805         FolderItem              *item;
806 };
807
808 struct _FolderItemUpdateData
809 {
810         FolderItem              *item;
811         FolderItemUpdateFlags    update_flags;
812         MsgInfo                 *msg;
813 };
814
815 void        folder_system_init          (void);
816 void        folder_register_class       (FolderClass    *klass);
817 void        folder_unregister_class     (FolderClass    *klass);
818 Folder     *folder_new                  (FolderClass    *type,
819                                          const gchar    *name,
820                                          const gchar    *path);
821 void        folder_init                 (Folder         *folder,
822                                          const gchar    *name);
823
824 void        folder_destroy              (Folder         *folder);
825
826 void        folder_set_xml              (Folder          *folder,
827                                          XMLTag          *tag);
828 XMLTag     *folder_get_xml              (Folder          *folder);
829
830 FolderItem *folder_item_new             (Folder         *folder,
831                                          const gchar    *name,
832                                          const gchar    *path);
833 void        folder_item_append          (FolderItem     *parent,
834                                          FolderItem     *item);
835 void        folder_item_remove          (FolderItem     *item);
836 void        folder_item_remove_children (FolderItem     *item);
837 void        folder_item_destroy         (FolderItem     *item);
838 FolderItem *folder_item_parent          (FolderItem     *item);
839
840 void        folder_item_set_xml         (Folder          *folder,
841                                          FolderItem      *item,
842                                          XMLTag          *tag);
843 XMLTag     *folder_item_get_xml         (Folder          *folder,
844                                          FolderItem      *item);
845
846 void        folder_set_ui_func  (Folder         *folder,
847                                  FolderUIFunc    func,
848                                  gpointer        data);
849 void        folder_set_name     (Folder         *folder,
850                                  const gchar    *name);
851 void        folder_set_sort     (Folder         *folder,
852                                  guint           sort);
853 void        folder_tree_destroy (Folder         *folder);
854
855 void   folder_add               (Folder         *folder);
856 void   folder_remove            (Folder         *folder);
857
858 GList *folder_get_list          (void);
859 gint   folder_read_list         (void);
860 void   folder_write_list        (void);
861 void   folder_scan_tree         (Folder *folder, gboolean rebuild);
862 FolderItem *folder_create_folder(FolderItem     *parent, const gchar *name);
863 gint   folder_item_rename       (FolderItem *item, gchar *newname);
864 void   folder_update_op_count           (void);
865 void   folder_func_to_all_folders       (FolderItemFunc function,
866                                          gpointer data);
867 void folder_count_total_msgs(guint *new_msgs, guint *unread_msgs, 
868                              guint *unreadmarked_msgs, guint *marked_msgs,
869                              guint *total_msgs, guint *replied_msgs,
870                              guint *forwarded_msgs, guint *locked_msgs,
871                              guint *ignored_msgs, guint *watched_msgs);
872 gchar *folder_get_status        (GPtrArray      *folders,
873                                  gboolean        full);
874
875 Folder     *folder_find_from_identifier         (const gchar *identifier);
876 Folder     *folder_find_from_path               (const gchar    *path);
877 Folder     *folder_find_from_name               (const gchar    *name,
878                                                  FolderClass    *klass);
879 FolderItem *folder_find_item_from_path          (const gchar    *path);
880 FolderItem *folder_find_item_from_real_path     (const gchar    *path);
881 FolderClass *folder_get_class_from_string       (const gchar    *str);
882 FolderItem *folder_find_child_item_by_name      (FolderItem     *item,
883                                                  const gchar    *name);
884 /* return value is locale charset */
885 gchar      *folder_get_identifier               (Folder *folder);
886 /* return value is locale charset */
887 gchar      *folder_item_get_identifier          (FolderItem     *item);
888 FolderItem *folder_find_item_from_identifier    (const gchar    *identifier);
889 FolderItem *folder_get_item_from_identifier     (const gchar    *identifier);
890 gchar      *folder_item_get_name                (FolderItem     *item);
891
892 FolderItem *folder_get_default_inbox    (void);
893 FolderItem *folder_get_default_inbox_for_class(FolderType type);
894 FolderItem *folder_get_default_outbox   (void);
895 FolderItem *folder_get_default_outbox_for_class(FolderType type);
896 FolderItem *folder_get_default_draft    (void);
897 FolderItem *folder_get_default_draft_for_class(FolderType type);
898 FolderItem *folder_get_default_queue    (void);
899 FolderItem *folder_get_default_queue_for_class(FolderType type);
900 FolderItem *folder_get_default_trash    (void);
901 FolderItem *folder_get_default_trash_for_class(FolderType type);
902 FolderItem *folder_get_default_processing (int account_id);
903 void folder_set_missing_folders         (void);
904 void folder_unref_account_all           (PrefsAccount   *account);
905
906 /* return value is locale encoded file name */
907 gchar *folder_item_get_path             (FolderItem     *item);
908
909 gint   folder_item_open                 (FolderItem     *item);
910 gint   folder_item_close                (FolderItem     *item);
911 gint   folder_item_scan                 (FolderItem     *item);
912 gint   folder_item_scan_full            (FolderItem     *item, 
913                                          gboolean        filtering);
914 MsgInfo *folder_item_get_msginfo        (FolderItem     *item,
915                                          gint            num);
916 MsgInfo *folder_item_get_msginfo_by_msgid(FolderItem    *item,
917                                          const gchar    *msgid);
918 GSList *folder_item_get_msg_list        (FolderItem     *item);
919 MsgNumberList *folder_item_get_number_list(FolderItem *item);
920
921 /* return value is locale charset */
922 gchar *folder_item_fetch_msg            (FolderItem     *item,
923                                          gint            num);
924 gchar *folder_item_fetch_msg_full       (FolderItem     *item,
925                                          gint            num, 
926                                          gboolean        get_headers,
927                                          gboolean        get_body);
928 gint   folder_item_add_msg              (FolderItem     *dest,
929                                          const gchar    *file,
930                                          MsgFlags       *flags,
931                                          gboolean        remove_source);
932 gint   folder_item_add_msgs             (FolderItem     *dest,
933                                          GSList         *file_list,
934                                          gboolean        remove_source);
935 gint   folder_item_move_to              (FolderItem     *src,
936                                          FolderItem     *dest,
937                                          FolderItem    **new_item,
938                                          gboolean        copy);
939 gint   folder_item_move_msg             (FolderItem     *dest,
940                                          MsgInfo        *msginfo);
941 gint   folder_item_move_msgs            (FolderItem     *dest,
942                                          GSList         *msglist);
943 gint   folder_item_copy_msg             (FolderItem     *dest,
944                                          MsgInfo        *msginfo);
945 gint   folder_item_copy_msgs            (FolderItem     *dest,
946                                          GSList         *msglist);
947 gint   folder_item_search_msgs          (Folder                 *folder,
948                                          FolderItem             *container,
949                                          MsgNumberList          **msgs,
950                                          gboolean               *on_server,
951                                          MatcherList            *predicate,
952                                          SearchProgressNotify   progress_cb,
953                                          gpointer               progress_data);
954 gint   folder_item_remove_msg           (FolderItem     *item,
955                                          gint            num);
956 gint   folder_item_remove_msgs          (FolderItem     *item,
957                                          GSList         *msglist);
958 gint   folder_item_expunge              (FolderItem     *item);
959 gint   folder_item_remove_all_msg       (FolderItem     *item);
960 void    folder_item_change_msg_flags    (FolderItem     *item,
961                                          MsgInfo        *msginfo,
962                                          MsgPermFlags    newflags);
963 gboolean folder_item_is_msg_changed     (FolderItem     *item,
964                                          MsgInfo        *msginfo);
965
966 void folder_clean_cache_memory          (FolderItem *protected_item);
967 void folder_clean_cache_memory_force    (void);
968 void folder_item_write_cache            (FolderItem *item);
969
970 void folder_item_apply_processing       (FolderItem *item);
971
972 void folder_item_update                 (FolderItem *item,
973                                          FolderItemUpdateFlags update_flags);
974 void folder_item_update_recursive       (FolderItem *item,
975                                          FolderItemUpdateFlags update_flags);
976 void folder_item_update_freeze          (void);
977 void folder_item_update_thaw            (void);
978 void folder_item_set_batch              (FolderItem *item, gboolean batch);
979 gboolean folder_has_parent_of_type      (FolderItem *item, SpecialFolderItemType type);
980 gboolean folder_is_child_of             (FolderItem *item, FolderItem *possibleChild);
981 void folder_synchronise                 (Folder *folder);
982 gboolean folder_want_synchronise        (Folder *folder);
983 gboolean folder_subscribe               (const gchar *uri);
984 gboolean folder_have_mailbox            (void);
985 gboolean folder_item_free_cache         (FolderItem *item, gboolean force);
986 void folder_item_change_type            (FolderItem *item,
987                                          SpecialFolderItemType newtype);
988 gboolean folder_get_sort_type           (Folder         *folder,
989                                          FolderSortKey  *sort_key,
990                                          FolderSortType *sort_type);
991 void folder_item_synchronise            (FolderItem *item);
992 void folder_item_discard_cache          (FolderItem *item);
993 void folder_item_commit_tags(FolderItem *item, MsgInfo *msginfo, GSList *tags_set, GSList *tags_unset);
994
995
996
997 gint folder_item_search_msgs_local      (Folder                 *folder,
998                                          FolderItem             *container,
999                                          MsgNumberList          **msgs,
1000                                          gboolean               *on_server,
1001                                          MatcherList            *predicate,
1002                                          SearchProgressNotify   progress_cb,
1003                                          gpointer               progress_data);
1004
1005 gchar *folder_get_list_path     (void);
1006 #endif /* __FOLDER_H__ */