From: Christoph Hohmann Date: Tue, 23 Dec 2003 16:31:46 +0000 (+0000) Subject: 0.9.8claws8 X-Git-Tag: rel_0_9_9~78 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=dfa9d4e2f596c30c1757fcbd04f3a46b193cd39f 0.9.8claws8 * src/folder.[ch] * src/folderview.c * src/mainwindow.c * src/procmsg.c o use callback for notifications about added and destroyed folders o rewrite folderlist saving (new functions to create folder from XML tree, and XML tree from folder) * src/common/xml.[ch] add function to save XML trees * src/prefs_filtering.c code cleanup --- diff --git a/ChangeLog.claws b/ChangeLog.claws index 2864c3f87..aadb39cc3 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,20 @@ +2003-12-23 [christoph] 0.9.8claws8 + + * src/folder.[ch] + * src/folderview.c + * src/mainwindow.c + * src/procmsg.c + o use callback for notifications about added and + destroyed folders + o rewrite folderlist saving (new functions to create + folder from XML tree, and XML tree from folder) + + * src/common/xml.[ch] + add function to save XML trees + + * src/prefs_filtering.c + code cleanup + 2003-12-22 [christoph] 0.9.8claws7 * src/prefs_account.[ch] diff --git a/configure.ac b/configure.ac index 6f1041aa2..faafb5f1c 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=8 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=7 +EXTRA_VERSION=8 if test $EXTRA_VERSION -eq 0; then VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}claws else diff --git a/src/common/xml.c b/src/common/xml.c index ac76e1c02..3dc940cfd 100644 --- a/src/common/xml.c +++ b/src/common/xml.c @@ -559,3 +559,52 @@ void xml_tag_add_attr(XMLTag *tag, const gchar *name, gchar *value) tag->attr = g_list_append(tag->attr, attr); } + +static void xml_write_node_recursive(GNode *node, FILE *fp) +{ + gint i, depth; + XMLTag *tag; + GList *cur; + + g_return_if_fail(node != NULL); + g_return_if_fail(fp != NULL); + + depth = g_node_depth(node) - 1; + for (i = 0; i < depth; i++) + fputs(" ", fp); + tag = ((XMLNode *) node->data)->tag; + + fprintf(fp, "<%s", tag->tag); + for (cur = tag->attr; cur != NULL; cur = g_list_next(cur)) { + XMLAttr *attr = (XMLAttr *) cur->data; + + fprintf(fp, " %s=\"", attr->name); + xml_file_put_escape_str(fp, attr->value); + fputs("\"", fp); + } + + if (node->children) { + GNode *child; + fputs(">\n", fp); + + child = node->children; + while (child) { + GNode *cur; + + cur = child; + child = cur->next; + xml_write_node_recursive(cur, fp); + } + + for (i = 0; i < depth; i++) + fputs(" ", fp); + fprintf(fp, "\n", tag->tag); + } else + fputs(" />\n", fp); +} + +void xml_write_node(GNode *node, FILE *fp) +{ + xml_write_node_recursive(node, fp); +} + diff --git a/src/common/xml.h b/src/common/xml.h index dadded553..f4893a16d 100644 --- a/src/common/xml.h +++ b/src/common/xml.h @@ -95,5 +95,7 @@ void xml_free_tag (XMLTag *tag); void xml_tag_add_attr (XMLTag *tag, const gchar *name, gchar *value); +void xml_write_node (GNode *node, + FILE *fp); #endif /* __XML_H__ */ diff --git a/src/folder.c b/src/folder.c index 0bf812459..ed54712ed 100644 --- a/src/folder.c +++ b/src/folder.c @@ -58,11 +58,9 @@ static GList *folder_list = NULL; void folder_init (Folder *folder, const gchar *name); -static gboolean folder_read_folder_func (GNode *node, - gpointer data); static gchar *folder_get_list_path (void); -static void folder_write_list_recursive (GNode *node, - gpointer data); +static GNode *folder_get_xml_node (Folder *folder); +static Folder *folder_get_from_xml (GNode *node); static void folder_update_op_count_rec (GNode *node); @@ -129,17 +127,26 @@ void folder_init(Folder *folder, const gchar *name) void folder_destroy(Folder *folder) { + FolderUpdateData hookdata; + g_return_if_fail(folder != NULL); g_return_if_fail(folder->klass->destroy_folder != NULL); folder_list = g_list_remove(folder_list, folder); + hookdata.folder = folder; + hookdata.update_flags = FOLDER_DESTROY_FOLDER; + hookdata.item = NULL; + hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata); + folder_tree_destroy(folder); folder->klass->destroy_folder(folder); g_free(folder->name); g_free(folder); + + folder_write_list(); } void folder_set_xml(Folder *folder, XMLTag *tag) @@ -542,6 +549,7 @@ void folder_add(Folder *folder) Folder *cur_folder; GList *cur; gint i; + FolderUpdateData hookdata; g_return_if_fail(folder != NULL); @@ -564,6 +572,11 @@ void folder_add(Folder *folder) } } + 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); } @@ -574,7 +587,7 @@ GList *folder_get_list(void) gint folder_read_list(void) { - GNode *node; + GNode *node, *cur; XMLNode *xmlnode; gchar *path; @@ -590,8 +603,15 @@ gint folder_read_list(void) return -1; } - g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, 2, - folder_read_folder_func, NULL); + cur = node->children; + while (cur != NULL) { + Folder *folder; + + folder = folder_get_from_xml(cur); + if (folder != NULL) + folder_add(folder); + cur = cur->next; + } xml_free_tree(node); if (folder_list) @@ -606,23 +626,40 @@ void folder_write_list(void) Folder *folder; gchar *path; PrefFile *pfile; + GNode *rootnode; + XMLNode *xmlnode; + XMLTag *tag; path = folder_get_list_path(); if ((pfile = prefs_write_open(path)) == NULL) return; fprintf(pfile->fp, "\n", conv_get_current_charset_str()); - fputs("\n\n", pfile->fp); + tag = g_new0(XMLTag, 1); + tag->tag = g_strdup("folderlist"); + tag->attr = NULL; + + xmlnode = g_new0(XMLNode, 1); + xmlnode->tag = tag; + xmlnode->element = NULL; + + rootnode = g_node_new(xmlnode); for (list = folder_list; list != NULL; list = list->next) { + GNode *node; + folder = list->data; - folder_write_list_recursive(folder->node, pfile->fp); + node = folder_get_xml_node(folder); + if (node != NULL) + g_node_append(rootnode, node); } - fputs("\n", pfile->fp); + xml_write_node(rootnode, pfile->fp); if (prefs_file_close(pfile) < 0) g_warning("failed to write folder list.\n"); + + xml_free_tree(rootnode); } gboolean folder_scan_tree_func(GNode *node, gpointer data) @@ -2462,19 +2499,21 @@ gchar *folder_item_get_mark_file(FolderItem *item) return file; } -static gboolean folder_build_tree(GNode *node, gpointer data) +static void build_folder_items_recursive(GNode *node, GNode *parentnode) { - Folder *folder = FOLDER(data); + FolderItem *parentitem = (FolderItem *) parentnode->data; + Folder *folder = FOLDER(parentitem->folder); FolderItem *item; + GNode *itemnode, *cur; XMLNode *xmlnode; - g_return_val_if_fail(node->data != NULL, FALSE); - if (!node->parent) return FALSE; - + g_return_if_fail(node != NULL); xmlnode = node->data; + g_return_if_fail(xmlnode != NULL); + if (strcmp2(xmlnode->tag->tag, "folderitem") != 0) { g_warning("tag name != \"folderitem\"\n"); - return FALSE; + return; } item = folder_item_new(folder, "", ""); @@ -2482,9 +2521,13 @@ static gboolean folder_build_tree(GNode *node, gpointer data) folder->klass->item_set_xml(folder, item, xmlnode->tag); else folder_item_set_xml(folder, item, xmlnode->tag); - item->node = node; - item->parent = FOLDER_ITEM(node->parent->data); + + itemnode = g_node_new(item); + item->node = itemnode; + item->parent = parentitem; item->folder = folder; + g_node_append(parentnode, itemnode); + switch (item->stype) { case F_INBOX: folder->inbox = item; break; case F_OUTBOX: folder->outbox = item; break; @@ -2495,29 +2538,28 @@ static gboolean folder_build_tree(GNode *node, gpointer data) } folder_item_prefs_read_config(item); - node->data = item; - xml_free_node(xmlnode); - - return FALSE; + cur = node->children; + while (cur != NULL) { + build_folder_items_recursive(cur, itemnode); + cur = cur->next; + } } -static gboolean folder_read_folder_func(GNode *node, gpointer data) +static Folder *folder_get_from_xml(GNode *node) { Folder *folder; - FolderItem *item; XMLNode *xmlnode; GList *list; FolderClass *klass = NULL; + GNode *cur; - if (g_node_depth(node) != 2) return FALSE; - g_return_val_if_fail(node->data != NULL, FALSE); + g_return_val_if_fail(node->data != NULL, NULL); xmlnode = node->data; if (strcmp2(xmlnode->tag->tag, "folder") != 0) { g_warning("tag name != \"folder\"\n"); - return TRUE; + return NULL; } - g_node_unlink(node); list = xmlnode->tag->attr; for (; list != NULL; list = list->next) { XMLAttr *attr = list->data; @@ -2528,24 +2570,20 @@ static gboolean folder_read_folder_func(GNode *node, gpointer data) } folder = folder_new(klass, "", ""); - g_return_val_if_fail(folder != NULL, FALSE); + g_return_val_if_fail(folder != NULL, NULL); - item = FOLDER_ITEM(folder->node->data); - - node->data = item; - item->node = node; - g_node_destroy(folder->node); - folder->node = node; if (klass->set_xml) klass->set_xml(folder, xmlnode->tag); else folder_set_xml(folder, xmlnode->tag); - folder_add(folder); - g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, - folder_build_tree, folder); - - return FALSE; + cur = node->children; + while (cur != NULL) { + build_folder_items_recursive(cur, folder->node); + cur = cur->next; + } + + return folder; } static gchar *folder_get_list_path(void) @@ -2566,67 +2604,79 @@ static gchar *folder_get_list_path(void) fputs("\"", fp); \ } -static void folder_write_list_recursive(GNode *node, gpointer data) +static void folder_get_xml_node_recursive(GNode *itemnode, GNode *xmlnode) { - FILE *fp = (FILE *)data; - FolderItem *item; - gint i, depth; XMLTag *tag; - GList *cur; + XMLNode *newxmlnode; + GNode *node; + FolderItem *item; - g_return_if_fail(node != NULL); - g_return_if_fail(fp != NULL); + g_return_if_fail(itemnode != NULL); + g_return_if_fail(xmlnode != NULL); - item = FOLDER_ITEM(node->data); + item = (FolderItem *) itemnode->data; g_return_if_fail(item != NULL); - depth = g_node_depth(node); - for (i = 0; i < depth; i++) - fputs(" ", fp); - if (depth == 1) { - if (item->folder->klass->get_xml != NULL) - tag = item->folder->klass->get_xml(item->folder); - else - tag = folder_get_xml(item->folder); + if (item->folder->klass->item_get_xml != NULL) + tag = item->folder->klass->item_get_xml(item->folder, item); + else + tag = folder_item_get_xml(item->folder, item); - xml_tag_add_attr(tag, "type", g_strdup(item->folder->klass->idstr)); - } else { + newxmlnode = g_new0(XMLNode, 1); + newxmlnode->tag = tag; + newxmlnode->element = NULL; - if (item->folder->klass->item_get_xml != NULL) - tag = item->folder->klass->item_get_xml(item->folder, item); - else - tag = folder_item_get_xml(item->folder, item); + node = g_node_new(newxmlnode); + g_node_append(xmlnode, node); - } + if (itemnode->children) { + GNode *child; - fprintf(fp, "<%s", tag->tag); - for (cur = tag->attr; cur != NULL; cur = g_list_next(cur)) { - XMLAttr *attr = (XMLAttr *) cur->data; + child = itemnode->children; + while (child) { + GNode *cur; - fprintf(fp, " %s=\"", attr->name); - xml_file_put_escape_str(fp, attr->value); - fputs("\"", fp); + cur = child; + child = cur->next; + folder_get_xml_node_recursive(cur, node); + } } +} - if (node->children) { +static GNode *folder_get_xml_node(Folder *folder) +{ + GNode *node; + XMLNode *xmlnode; + XMLTag *tag; + + g_return_val_if_fail(folder != NULL, NULL); + + if (folder->klass->get_xml != NULL) + tag = folder->klass->get_xml(folder); + else + tag = folder_get_xml(folder); + + xml_tag_add_attr(tag, "type", g_strdup(folder->klass->idstr)); + + xmlnode = g_new0(XMLNode, 1); + xmlnode->tag = tag; + xmlnode->element = NULL; + + node = g_node_new(xmlnode); + if (folder->node->children) { GNode *child; - fputs(">\n", fp); - child = node->children; + child = folder->node->children; while (child) { GNode *cur; cur = child; child = cur->next; - folder_write_list_recursive(cur, data); + folder_get_xml_node_recursive(cur, node); } + } - for (i = 0; i < depth; i++) - fputs(" ", fp); - fprintf(fp, "\n", tag->tag); - } else - fputs(" />\n", fp); - xml_free_tag(tag); + return node; } static void folder_update_op_count_rec(GNode *node) @@ -2791,7 +2841,7 @@ void folder_item_restore_persist_prefs(FolderItem *item, GHashTable *pptable) * folderlist.xml, we need to call the old stuff first before * setting things that apply both to Main and Claws. */ folder_item_prefs_read_config(item); - + item->collapsed = pp->collapsed; item->thread_collapsed = pp->thread_collapsed; item->threaded = pp->threaded; diff --git a/src/folder.h b/src/folder.h index 739e3fdcd..3586762ad 100644 --- a/src/folder.h +++ b/src/folder.h @@ -98,9 +98,11 @@ typedef enum typedef enum { - FOLDER_TREE_CHANGED = 1 << 0, - FOLDER_NEW_FOLDERITEM = 1 << 1, - FOLDER_REMOVE_FOLDERITEM = 1 << 2, + FOLDER_NEW_FOLDER = 1 << 0, + FOLDER_DESTROY_FOLDER = 1 << 1, + FOLDER_TREE_CHANGED = 1 << 2, + FOLDER_NEW_FOLDERITEM = 1 << 3, + FOLDER_REMOVE_FOLDERITEM = 1 << 4, } FolderUpdateFlags; typedef enum diff --git a/src/folderview.c b/src/folderview.c index 06c5a0272..fc636a3f3 100644 --- a/src/folderview.c +++ b/src/folderview.c @@ -2187,10 +2187,8 @@ static void folderview_remove_mailbox_cb(FolderView *folderview, guint action, folderview_unselect(folderview); summary_clear_all(folderview->summaryview); - gtk_ctree_remove_node(ctree, node); folder_destroy(item->folder); - folder_write_list(); } static void folderview_new_imap_folder_cb(FolderView *folderview, guint action, @@ -2751,7 +2749,7 @@ gboolean folderview_update_folder(gpointer source, gpointer userdata) node = gtk_ctree_find_by_row_data(GTK_CTREE(ctree), NULL, hookdata->item); if (node != NULL) gtk_ctree_remove_node(GTK_CTREE(ctree), node); - } else if (hookdata->update_flags & FOLDER_TREE_CHANGED) + } else if (hookdata->update_flags & (FOLDER_TREE_CHANGED | FOLDER_NEW_FOLDER | FOLDER_DESTROY_FOLDER)) folderview_set(folderview); return FALSE; diff --git a/src/mainwindow.c b/src/mainwindow.c index 8a61066df..aa270b15e 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -1513,8 +1513,6 @@ void main_window_add_mailbox(MainWindow *mainwin) folder_set_ui_func(folder, scan_tree_func, mainwin); folder_scan_tree(folder); folder_set_ui_func(folder, NULL, NULL); - - folderview_set(mainwin->folderview); } SensitiveCond main_window_get_current_state(MainWindow *mainwin) diff --git a/src/prefs_filtering.c b/src/prefs_filtering.c index 9a9225085..79d333002 100644 --- a/src/prefs_filtering.c +++ b/src/prefs_filtering.c @@ -405,7 +405,6 @@ static void rename_path(GSList * filters, gint destlen; gint prefixlen; gint oldpathlen; - FolderItem *item; GSList * action_cur; GSList * cur; @@ -522,7 +521,6 @@ static void delete_path(GSList ** p_filters, const gchar * path) gint destlen; gint prefixlen; gint pathlen; - FolderItem *item; GSList * action_cur; GSList * cur; diff --git a/src/procmsg.c b/src/procmsg.c index 22b50d4d7..47b0a87d8 100644 --- a/src/procmsg.c +++ b/src/procmsg.c @@ -915,8 +915,6 @@ void procmsg_msginfo_free(MsgInfo *msginfo) if (msginfo->refcnt > 0) return; - debug_print("freeing msginfo %d in %s\n", msginfo->msgnum, msginfo->folder ? msginfo->folder->path : "(nil)"); - if (msginfo->to_folder) { msginfo->to_folder->op_count--; folder_item_update(msginfo->to_folder, F_ITEM_UPDATE_MSGCNT);