talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

folder.h (31680B)


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