#include "prefs_account.h"
static GList *folder_list = NULL;
+static GSList *class_list = NULL;
+static GSList *folder_unloaded_list = NULL;
void folder_init (Folder *folder,
const gchar *name);
void folder_item_free_cache (FolderItem *item);
gint folder_item_scan_full (FolderItem *item, gboolean filtering);
-static GSList *classlist;
-
void folder_system_init(void)
{
folder_register_class(mh_get_class());
GSList *folder_get_class_list(void)
{
- return classlist;
+ return class_list;
}
void folder_register_class(FolderClass *klass)
{
+ GSList *xmllist, *cur;
+
debug_print("registering folder class %s\n", klass->idstr);
- classlist = g_slist_append(classlist, klass);
+
+ class_list = g_slist_append(class_list, klass);
+
+ xmllist = g_slist_copy(folder_unloaded_list);
+ for (cur = xmllist; cur != NULL; cur = g_slist_next(cur)) {
+ GNode *node = (GNode *) cur->data;
+ XMLNode *xmlnode = (XMLNode *) node->data;
+ GList *cur = xmlnode->tag->attr;
+
+ for (; cur != NULL; cur = g_list_next(cur)) {
+ XMLAttr *attr = (XMLAttr *) cur->data;
+
+ if (!attr || !attr->name || !attr->value) continue;
+ if (!strcmp(attr->name, "type") && !strcmp(attr->value, klass->idstr)) {
+ Folder *folder;
+
+ folder = folder_get_from_xml(node);
+ folder_add(folder);
+ folder_unloaded_list = g_slist_remove(folder_unloaded_list, node);
+
+ cur = NULL;
+ continue;
+ }
+ }
+ }
+ g_slist_free(xmllist);
+}
+
+void folder_unregister_class(FolderClass *klass)
+{
+ GList *folderlist, *cur;
+
+ debug_print("unregistering folder class %s\n", klass->idstr);
+
+ class_list = g_slist_remove(class_list, klass);
+
+ folderlist = g_list_copy(folder_get_list());
+ for (cur = folderlist; cur != NULL; cur = g_list_next(cur)) {
+ Folder *folder = (Folder *) cur->data;
+
+ if (folder->klass == klass) {
+ GNode *xmlnode = folder_get_xml_node(folder);
+ folder_unloaded_list = g_slist_append(folder_unloaded_list, xmlnode);
+ folder_destroy(folder);
+ }
+ }
+ g_list_free(folderlist);
}
Folder *folder_new(FolderClass *klass, const gchar *name, const gchar *path)
g_free(folder->name);
g_free(folder);
-
- folder_write_list();
}
void folder_set_xml(Folder *folder, XMLTag *tag)
{
XMLTag *tag;
- tag = g_new0(XMLTag, 1);
- tag->tag = g_strdup("folder");
+ tag = xml_new_tag("folder");
if (folder->name)
xml_tag_add_attr(tag, "name", g_strdup(folder->name));
"locked"};
XMLTag *tag;
- tag = g_new0(XMLTag, 1);
- tag->tag = g_strdup("folderitem");
+ tag = xml_new_tag("folderitem");
xml_tag_add_attr(tag, "type", g_strdup(folder_item_stype_str[item->stype]));
if (item->name)
}
}
+ folder_list = g_list_insert(folder_list, folder, i);
+
hookdata.folder = folder;
hookdata.update_flags = FOLDER_NEW_FOLDER;
hookdata.item = NULL;
hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
-
- folder_list = g_list_insert(folder_list, folder, i);
}
GList *folder_get_list(void)
folder = folder_get_from_xml(cur);
if (folder != NULL)
folder_add(folder);
+ else
+ folder_unloaded_list = g_slist_append(folder_unloaded_list,
+ (gpointer) xml_copy_tree(cur));
cur = cur->next;
}
void folder_write_list(void)
{
GList *list;
+ GSList *slist;
Folder *folder;
gchar *path;
PrefFile *pfile;
fprintf(pfile->fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
conv_get_current_charset_str());
- tag = g_new0(XMLTag, 1);
- tag->tag = g_strdup("folderlist");
- tag->attr = NULL;
+ tag = xml_new_tag("folderlist");
xmlnode = g_new0(XMLNode, 1);
xmlnode->tag = tag;
g_node_append(rootnode, node);
}
- xml_write_node(rootnode, pfile->fp);
+ for (slist = folder_unloaded_list; slist != NULL; slist = g_slist_next(slist)) {
+ GNode *node = (GNode *) slist->data;
+
+ g_node_append(rootnode, (gpointer) xml_copy_tree(node));
+ }
+
+ xml_write_tree(rootnode, pfile->fp);
if (prefs_file_close(pfile) < 0)
g_warning("failed to write folder list.\n");
return d[1];
}
+FolderItem *folder_find_child_item_by_name(FolderItem *item, const gchar *name)
+{
+ GNode *node;
+ FolderItem *child;
+
+ for (node = item->node->children; node != NULL; node = node->next) {
+ child = FOLDER_ITEM(node->data);
+ if (strcmp2(g_basename(child->path), name) == 0)
+ return child;
+ }
+
+ return NULL;
+}
+
FolderClass *folder_get_class_from_string(const gchar *str)
{
GSList *classlist;
gint folder_item_open(FolderItem *item)
{
+ gchar *buf;
if((item->folder->klass->scan_required != NULL) && (item->folder->klass->scan_required(item->folder, item))) {
folder_item_scan_full(item, TRUE);
}
-
+ folder_item_syncronize_flags(item);
+
/* Processing */
- if(item->prefs->processing != NULL) {
- gchar *buf;
-
- buf = g_strdup_printf(_("Processing (%s)...\n"), item->path);
- debug_print("%s\n", buf);
- g_free(buf);
+ buf = g_strdup_printf(_("Processing (%s)...\n"), item->path);
+ debug_print("%s\n", buf);
+ g_free(buf);
- folder_item_apply_processing(item);
+ folder_item_apply_processing(item);
- debug_print("done.\n");
- }
+ debug_print("done.\n");
return 0;
}
return 0;
}
+gint folder_item_syncronize_flags(FolderItem *item)
+{
+ MsgInfoList *msglist = NULL;
+ GSList *cur;
+ GRelation *relation;
+ gint ret = 0;
+
+ g_return_val_if_fail(item != NULL, -1);
+ g_return_val_if_fail(item->folder != NULL, -1);
+ g_return_val_if_fail(item->folder->klass != NULL, -1);
+ if(item->folder->klass->get_flags == NULL)
+ return 0;
+
+ if (item->cache == NULL)
+ folder_item_read_cache(item);
+
+ msglist = msgcache_get_msg_list(item->cache);
+
+ relation = g_relation_new(2);
+ g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+ if ((ret = item->folder->klass->get_flags(
+ item->folder, item, msglist, relation)) == 0) {
+ GTuples *tuples;
+ MsgInfo *msginfo;
+ MsgPermFlags permflags;
+ gboolean skip;
+
+ for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
+ msginfo = (MsgInfo *) cur->data;
+
+ tuples = g_relation_select(relation, msginfo, 0);
+ skip = tuples->len < 1;
+ if (!skip)
+ permflags = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
+ g_tuples_destroy(tuples);
+ if (skip)
+ continue;
+
+ if (msginfo->flags.perm_flags != permflags) {
+ procmsg_msginfo_set_flags(msginfo,
+ permflags & ~msginfo->flags.perm_flags, 0);
+ procmsg_msginfo_unset_flags(msginfo,
+ ~permflags & msginfo->flags.perm_flags, 0);
+ }
+ }
+ }
+ g_relation_destroy(relation);
+
+ for (cur = msglist; cur != NULL; cur = g_slist_next(cur))
+ procmsg_msginfo_free((MsgInfo *) cur->data);
+
+ return ret;
+}
+
gint folder_item_scan(FolderItem *item)
{
return folder_item_scan_full(item, TRUE);
return folder->klass->fetch_msg(folder, item, num);
}
+gint folder_item_fetch_all_msg(FolderItem *item)
+{
+ Folder *folder;
+ GSList *mlist;
+ GSList *cur;
+ gint num = 0;
+ gint ret = 0;
+
+ g_return_val_if_fail(item != NULL, -1);
+
+ debug_print("fetching all messages in %s ...\n", item->path);
+
+ folder = item->folder;
+
+ if (folder->ui_func)
+ folder->ui_func(folder, item, folder->ui_func_data ?
+ folder->ui_func_data : GINT_TO_POINTER(num));
+
+ mlist = folder_item_get_msg_list(item);
+
+ for (cur = mlist; cur != NULL; cur = cur->next) {
+ MsgInfo *msginfo = (MsgInfo *)cur->data;
+ gchar *msg;
+
+ num++;
+ if (folder->ui_func)
+ folder->ui_func(folder, item,
+ folder->ui_func_data ?
+ folder->ui_func_data :
+ GINT_TO_POINTER(num));
+
+ msg = folder_item_fetch_msg(item, msginfo->msgnum);
+ if (!msg) {
+ g_warning("Can't fetch message %d. Aborting.\n",
+ msginfo->msgnum);
+ ret = -1;
+ break;
+ }
+ g_free(msg);
+ }
+
+ procmsg_msg_list_free(mlist);
+
+ return ret;
+}
+
static gint folder_item_get_msg_num_by_file(FolderItem *dest, const gchar *file)
{
static HeaderEntry hentry[] = {{"Message-ID:", NULL, TRUE},
}
}
- if (folder->klass->finished_copy)
- folder->klass->finished_copy(folder, dest);
-
g_relation_destroy(relation);
return lastnum;
}
if (!item->cache) folder_item_read_cache(item);
+ folder_item_update_freeze();
while (msglist != NULL) {
MsgInfo *msginfo = (MsgInfo *)msglist->data;
msgcache_remove_msg(item->cache, msginfo->msgnum);
msglist = msglist->next;
}
+ folder_item_update_thaw();
return ret;
}
result = folder->klass->remove_all_msg(folder, item);
if (result == 0) {
- if (folder->klass->finished_remove)
- folder->klass->finished_remove(folder, item);
-
folder_item_free_cache(item);
item->cache = msgcache_new();
if (!strcmp(attr->name, "type"))
klass = folder_get_class_from_string(attr->value);
}
+ if (klass == NULL)
+ return NULL;
folder = folder_new(klass, "", "");
g_return_val_if_fail(folder != NULL, NULL);