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