fix bug 2979, 'claws fails to load (empty) folderlist.xml and shows account wizard'
[claws.git] / src / folder.h
index 834320ecca7db140a9a0568852dc017b51b30ba8..44f69bb2c25d30a015a5ff8b676eb86780826179 100644 (file)
@@ -2,11 +2,11 @@
 
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -15,8 +15,8 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * 
  */
 
 #ifndef __FOLDER_H__
@@ -80,7 +80,9 @@ typedef enum
        SORT_BY_STATUS,
        SORT_BY_MIME,
        SORT_BY_TO,
-       SORT_BY_LOCKED
+       SORT_BY_LOCKED,
+       SORT_BY_TAGS,
+       SORT_BY_THREAD_DATE
 } FolderSortKey;
 
 typedef enum
@@ -104,7 +106,8 @@ typedef enum
        FOLDER_REMOVE_FOLDER            = 1 << 1,
        FOLDER_TREE_CHANGED             = 1 << 2,
        FOLDER_ADD_FOLDERITEM           = 1 << 3,
-       FOLDER_REMOVE_FOLDERITEM        = 1 << 4
+       FOLDER_REMOVE_FOLDERITEM        = 1 << 4,
+       FOLDER_RENAME_FOLDERITEM        = 1 << 5
 } FolderUpdateFlags;
 
 typedef enum
@@ -126,12 +129,12 @@ typedef void (*FolderItemFunc)    (FolderItem     *item,
                                         gpointer        data);
 
 
-#include "folder_item_prefs.h"
-
-#include "procmsg.h"
-#include "msgcache.h"
+#include "proctypes.h"
 #include "xml.h"
 #include "prefs_account.h"
+#include "matchertypes.h"
+
+struct _MsgCache;
 
 struct _Folder
 {
@@ -157,6 +160,23 @@ struct _Folder
        GHashTable *newsart;
 };
 
+/**
+ * Callback used to convey progress information of a specific search.
+ *
+ * \param data User-provided data
+ * \param on_server Whether or not the current progress information originated from the
+ *                  server
+ * \param at Number of the last message processed
+ * \param matched Number of messages with definitive matches found so far
+ * \param total Number of messages to be processed
+ *
+ * \note
+ * Even if the mailserver does not support progress reports, an instance of this type
+ * should be invoked when serverside search starts and ends, with \c at set to \c 0 and
+ * \c total, respectively.
+ */
+typedef gboolean (*SearchProgressNotify)(gpointer data, gboolean on_server, guint at, guint matched, guint total);
+
 struct _FolderClass
 {
        /**
@@ -173,6 +193,13 @@ struct _FolderClass
         * user. Can be upper and lowercase unlike the idstr.
         */
        gchar      *uistr;
+       /**
+       * A boolean to indicate whether or not the FolderClass supports search on the
+       * server. If \c TRUE, setting \c on_server in \c search_msgs offloads search to
+       * the server.
+       */
+       gboolean    supports_server_search;
+
        
        /* virtual functions */
 
@@ -389,6 +416,12 @@ struct _FolderClass
        gboolean        (*scan_required)        (Folder         *folder,
                                                 FolderItem     *item);
 
+       /**
+        * Updates the known mtime of a folder
+        */
+       void            (*set_mtime)            (Folder         *folder,
+                                                FolderItem     *item);
+
        /* Message functions */
        /**
         * Get a MsgInfo for a message in a \c FolderItem
@@ -465,7 +498,7 @@ struct _FolderClass
        gint            (*add_msgs)             (Folder         *folder,
                                                 FolderItem     *dest,
                                                 GSList         *file_list,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
        /**
         * Copy a message to a FolderItem
         *
@@ -496,7 +529,59 @@ struct _FolderClass
        gint            (*copy_msgs)            (Folder         *folder,
                                                 FolderItem     *dest,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
+
+       /**
+        * Search the given FolderItem for messages matching \c predicate.
+        * The search may be offloaded to the server if the \c folder
+        * supports server side search, as indicated by \c supports_server_search.
+        *
+        * \param folder The \c Folder of the container FolderItem
+        * \param container The \c FolderItem containing the messages to be searched
+        * \param msgs The \c MsgNumberList results will be saved to.
+        *             If <tt>*msgs != NULL</tt>, the search will be restricted to
+        *             messages whose numbers are contained therein.
+        *             If \c on_server is considered \c FALSE, messages are guaranteed to
+        *             be processed in the order they are listed in \c msgs.
+        *             On error, \c msgs will not be changed.
+        * \param on_server Whether or not the search should be offloaded to the server.
+        *                  If \c on_server is not \c NULL and points to a \c TRUE value,
+        *                  search will be done on the server. If \c predicate contains
+        *                  one or more atoms the server does not support, the value
+        *                  pointed to by \c on_server will be set to \c FALSE upon return.
+        *                  In this case, \c msgs must still contain a valid superset of
+        *                  messages actually matched by \c predicate, or this method must
+        *                  return an error.
+        *                  \c on_server may only point to a \c TRUE value if
+        *                  \c supports_server_search is also \c TRUE.
+        *                  \c NULL and pointer to \c FALSE are considered equivalent and
+        *                  will start a client-only search.
+        * \param predicate The \c MatcherList to use in the search
+        * \param progress_cb Called for every message searched.
+        *                    When search is offloaded to the server, this function
+        *                    may or may not be called, depending on the implementation.
+        *                    The second argument of this function will be the number of
+        *                    messages already processed.
+        *                    Return \c FALSE from this function to end the search.
+        *                    May be \c NULL, no calls will be made in this case.
+        * \param progress_data First argument value for \c progress_cb
+        * \return Number of messages that matched \c predicate on success, a negative
+        *         number otherwise.
+        *
+        * \note
+        * When search is stopped by returning \c FALSE from \c progress_cb, \c msgs will
+        * contain all messages found until the point of cancellation. The number of
+        * messages found will be returned as indicated above.
+        */
+       gint            (*search_msgs)          (Folder                 *folder,
+                                                FolderItem             *container,
+                                                MsgNumberList          **msgs,
+                                                gboolean               *on_server,
+                                                MatcherList            *predicate,
+                                                SearchProgressNotify   progress_cb,
+                                                gpointer               progress_data);
+
+
        /**
         * Remove a message from a \c FolderItem.
         *
@@ -511,7 +596,9 @@ struct _FolderClass
        gint            (*remove_msgs)          (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
+       gint            (*expunge)              (Folder         *folder,
+                                                FolderItem     *item);
        /**
         * Remove all messages in a \ c FolderItem
         *
@@ -567,14 +654,63 @@ struct _FolderClass
        gint            (*get_flags)            (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *msgflags);
+                                                GHashTable     *msgflags);
        
+       /* Sets batch mode for a FolderItem. It means that numerous flags updates
+        * could follow, and the FolderClass implementation can cache them in order
+        * to process them later when set_false will be called again with the
+        * batch parameter set to FALSE. 
+        */
        void            (*set_batch)            (Folder         *folder,
                                                 FolderItem     *item,
                                                 gboolean        batch);
-       void            (*synchronise)          (FolderItem     *item);
+       /* Called when switching offline or asking for synchronisation. the imple
+        * mentation should do what's necessary to be able to read mails present
+        * in the FolderItem at this time with no network connectivity. 
+        * Days: max number of days of mail to fetch.
+        */
+       void            (*synchronise)          (FolderItem     *item,
+                                                gint            days);
+       
+       /* Passed from claws-mail --subscribe scheme://uri. Implementations
+        * should check if they handle this type of URI, and return TRUE in this
+        * case after having subscribed it.
+        */
+       gboolean        (*subscribe)            (Folder         *folder,
+                                                const gchar    *uri);
+       
+       /* Gets the preferred sort key and type for a folderclass. */
+       void            (*get_sort_type)        (Folder         *folder,
+                                                FolderSortKey  *sort_key,
+                                                FolderSortType *sort_type);
+       
+       /* Copies internal FolderItem data from one folderItem to another. Used
+        * when moving folders (this move is in reality a folder creation, content
+        * move, folder delettion).
+        */
+       void            (*copy_private_data)    (Folder         *folder,
+                                                FolderItem     *src,
+                                                FolderItem     *dest);
+
+       void            (*remove_cached_msg)    (Folder         *folder,
+                                                FolderItem     *item,
+                                                MsgInfo        *msginfo);
+       void            (*commit_tags)          (FolderItem     *item,
+                                                MsgInfo        *msginfo,
+                                                GSList         *tags_set,
+                                                GSList         *tags_unset);
+       void            (*item_opened)          (FolderItem     *item);
+       void            (*item_closed)          (FolderItem     *item);
 };
 
+enum {
+       ITEM_NOT_SCANNING,
+       ITEM_SCANNING_WITH_FLAGS,
+       ITEM_SCANNING
+};
+
+struct _FolderItemPrefs;
+
 struct _FolderItem
 {
        SpecialFolderItemType stype;
@@ -589,10 +725,20 @@ struct _FolderItem
        gint total_msgs;
        gint unreadmarked_msgs;
        gint marked_msgs;
+       gint replied_msgs;
+       gint forwarded_msgs;
+       gint locked_msgs;
+       gint ignored_msgs;
+       gint watched_msgs;
+
+       gint order;
 
        gint last_num;
 
-       MsgCache *cache;
+       struct _MsgCache *cache;
+       gboolean cache_dirty;
+       gboolean mark_dirty;
+       gboolean tags_dirty;
 
        /* special flags */
        guint no_sub         : 1; /* no child allowed?    */
@@ -603,6 +749,8 @@ struct _FolderItem
        guint hide_read_msgs : 1; /* hide read messages   */
        guint ret_rcpt       : 1; /* return receipt       */
        guint search_match   : 1;
+       guint hide_del_msgs : 1; /* hide deleted messages   */
+       guint hide_read_threads : 1; /* hide threads with only read messages   */
 
        gint op_count;
        guint opened         : 1; /* opened by summary view */
@@ -623,11 +771,13 @@ struct _FolderItem
 
        gpointer data;
 
-       FolderItemPrefs * prefs;
+       struct _FolderItemPrefs * prefs;
        
        /* for faster search of special parents */
        SpecialFolderItemType parent_stype;
        gboolean processing_pending;
+       gint scanning;
+       guint last_seen;
 };
 
 struct _PersistPrefs
@@ -639,6 +789,8 @@ struct _PersistPrefs
        guint           threaded        : 1;
        guint           hide_read_msgs  : 1; /* CLAWS */
        guint           ret_rcpt        : 1; /* CLAWS */
+       guint           hide_del_msgs   : 1; /* CLAWS */
+       guint           hide_read_threads       : 1;
 };
 
 struct _FolderUpdateData
@@ -702,6 +854,7 @@ GList *folder_get_list              (void);
 gint   folder_read_list                (void);
 void   folder_write_list       (void);
 void   folder_scan_tree                (Folder *folder, gboolean rebuild);
+void   folder_fast_scan_tree   (Folder *folder);
 FolderItem *folder_create_folder(FolderItem    *parent, const gchar *name);
 gint   folder_item_rename      (FolderItem *item, gchar *newname);
 void   folder_update_op_count          (void);
@@ -709,28 +862,39 @@ void   folder_func_to_all_folders (FolderItemFunc function,
                                         gpointer data);
 void folder_count_total_msgs(guint *new_msgs, guint *unread_msgs, 
                             guint *unreadmarked_msgs, guint *marked_msgs,
-                            guint *total_msgs);
+                            guint *total_msgs, guint *replied_msgs,
+                            guint *forwarded_msgs, guint *locked_msgs,
+                            guint *ignored_msgs, guint *watched_msgs);
 gchar *folder_get_status       (GPtrArray      *folders,
                                 gboolean        full);
 
+Folder            *folder_find_from_identifier         (const gchar *identifier);
 Folder     *folder_find_from_path              (const gchar    *path);
 Folder     *folder_find_from_name              (const gchar    *name,
                                                 FolderClass    *klass);
 FolderItem *folder_find_item_from_path         (const gchar    *path);
+FolderItem *folder_find_item_from_real_path    (const gchar    *path);
 FolderClass *folder_get_class_from_string      (const gchar    *str);
 FolderItem *folder_find_child_item_by_name     (FolderItem     *item,
                                                 const gchar    *name);
-gchar      *folder_get_identifier              (Folder         *folder);
+/* return value is locale charset */
+gchar     *folder_get_identifier               (Folder *folder);
+/* return value is locale charset */
 gchar      *folder_item_get_identifier         (FolderItem     *item);
 FolderItem *folder_find_item_from_identifier   (const gchar    *identifier);
+FolderItem *folder_get_item_from_identifier    (const gchar    *identifier);
 gchar     *folder_item_get_name                (FolderItem     *item);
 
-Folder     *folder_get_default_folder  (void);
 FolderItem *folder_get_default_inbox   (void);
+FolderItem *folder_get_default_inbox_for_class(FolderType type);
 FolderItem *folder_get_default_outbox  (void);
+FolderItem *folder_get_default_outbox_for_class(FolderType type);
 FolderItem *folder_get_default_draft   (void);
+FolderItem *folder_get_default_draft_for_class(FolderType type);
 FolderItem *folder_get_default_queue   (void);
+FolderItem *folder_get_default_queue_for_class(FolderType type);
 FolderItem *folder_get_default_trash   (void);
+FolderItem *folder_get_default_trash_for_class(FolderType type);
 FolderItem *folder_get_default_processing (void);
 void folder_set_missing_folders                (void);
 void folder_unref_account_all          (PrefsAccount   *account);
@@ -741,13 +905,15 @@ gchar *folder_item_get_path               (FolderItem     *item);
 gint   folder_item_open                        (FolderItem     *item);
 gint   folder_item_close               (FolderItem     *item);
 gint   folder_item_scan                        (FolderItem     *item);
-gint   folder_item_syncronize_flags    (FolderItem     *item);
-void   folder_item_scan_foreach                (GHashTable     *table);
+gint   folder_item_scan_full           (FolderItem     *item, 
+                                        gboolean        filtering);
 MsgInfo *folder_item_get_msginfo       (FolderItem     *item,
                                         gint            num);
 MsgInfo *folder_item_get_msginfo_by_msgid(FolderItem   *item,
                                         const gchar    *msgid);
 GSList *folder_item_get_msg_list       (FolderItem     *item);
+MsgNumberList *folder_item_get_number_list(FolderItem *item);
+
 /* return value is locale charset */
 gchar *folder_item_fetch_msg           (FolderItem     *item,
                                         gint            num);
@@ -755,7 +921,6 @@ gchar *folder_item_fetch_msg_full   (FolderItem     *item,
                                         gint            num, 
                                         gboolean        get_headers,
                                         gboolean        get_body);
-gint   folder_item_fetch_all_msg       (FolderItem     *item);
 gint   folder_item_add_msg             (FolderItem     *dest,
                                         const gchar    *file,
                                         MsgFlags       *flags,
@@ -765,7 +930,8 @@ gint   folder_item_add_msgs             (FolderItem     *dest,
                                          gboolean        remove_source);
 gint   folder_item_move_to             (FolderItem     *src,
                                         FolderItem     *dest,
-                                        FolderItem    **new_item);
+                                        FolderItem    **new_item,
+                                        gboolean        copy);
 gint   folder_item_move_msg            (FolderItem     *dest,
                                         MsgInfo        *msginfo);
 gint   folder_item_move_msgs           (FolderItem     *dest,
@@ -774,31 +940,28 @@ gint   folder_item_copy_msg               (FolderItem     *dest,
                                         MsgInfo        *msginfo);
 gint   folder_item_copy_msgs           (FolderItem     *dest,
                                         GSList         *msglist);
+gint   folder_item_search_msgs         (Folder                 *folder,
+                                        FolderItem             *container,
+                                        MsgNumberList          **msgs,
+                                        gboolean               *on_server,
+                                        MatcherList            *predicate,
+                                        SearchProgressNotify   progress_cb,
+                                        gpointer               progress_data);
 gint   folder_item_remove_msg          (FolderItem     *item,
                                         gint            num);
 gint   folder_item_remove_msgs         (FolderItem     *item,
                                         GSList         *msglist);
+gint   folder_item_expunge             (FolderItem     *item);
 gint   folder_item_remove_all_msg      (FolderItem     *item);
 void   folder_item_change_msg_flags    (FolderItem     *item,
                                         MsgInfo        *msginfo,
                                         MsgPermFlags    newflags);
 gboolean folder_item_is_msg_changed    (FolderItem     *item,
                                         MsgInfo        *msginfo);
-/* return value is locale chaset */
-gchar *folder_item_get_cache_file      (FolderItem     *item);
-gchar *folder_item_get_mark_file       (FolderItem     *item);
-gchar * folder_item_get_identifier     (FolderItem * item);
-
-GHashTable *folder_persist_prefs_new   (Folder *folder);
-void folder_persist_prefs_free         (GHashTable *pptable);
-const PersistPrefs *folder_get_persist_prefs
-                                       (GHashTable *pptable, const char *name);
-
-void folder_item_restore_persist_prefs (FolderItem *item, GHashTable *pptable);
-void folder_clean_cache_memory         (void);
+
+void folder_clean_cache_memory         (FolderItem *protected_item);
 void folder_clean_cache_memory_force   (void);
 void folder_item_write_cache           (FolderItem *item);
-void folder_item_set_default_flags     (FolderItem *dest, MsgFlags *flags);
 
 void folder_item_apply_processing      (FolderItem *item);
 
@@ -810,10 +973,30 @@ void folder_item_update_freeze            (void);
 void folder_item_update_thaw           (void);
 void folder_item_set_batch             (FolderItem *item, gboolean batch);
 gboolean folder_has_parent_of_type     (FolderItem *item, SpecialFolderItemType type);
+gboolean folder_is_child_of            (FolderItem *item, FolderItem *possibleChild);
 void folder_synchronise                        (Folder *folder);
 gboolean folder_want_synchronise       (Folder *folder);
-void folder_item_process_open          (FolderItem *item,
-                                        void (*before_proc_func)(gpointer data),
-                                        void (*after_proc_func)(gpointer data),
-                                        gpointer data);
+gboolean folder_subscribe              (const gchar *uri);
+gboolean folder_have_mailbox           (void);
+gboolean folder_item_free_cache                (FolderItem *item, gboolean force);
+void folder_item_change_type           (FolderItem *item,
+                                        SpecialFolderItemType newtype);
+gboolean folder_get_sort_type          (Folder         *folder,
+                                        FolderSortKey  *sort_key,
+                                        FolderSortType *sort_type);
+void folder_item_synchronise           (FolderItem *item);
+void folder_item_discard_cache         (FolderItem *item);
+void folder_item_commit_tags(FolderItem *item, MsgInfo *msginfo, GSList *tags_set, GSList *tags_unset);
+
+
+
+gint folder_item_search_msgs_local     (Folder                 *folder,
+                                        FolderItem             *container,
+                                        MsgNumberList          **msgs,
+                                        gboolean               *on_server,
+                                        MatcherList            *predicate,
+                                        SearchProgressNotify   progress_cb,
+                                        gpointer               progress_data);
+
+gchar *folder_get_list_path    (void);
 #endif /* __FOLDER_H__ */