From fb91bed5b9753d03cf1086f57d9a18f19ae60e67 Mon Sep 17 00:00:00 2001 From: Christoph Hohmann Date: Thu, 14 Aug 2003 19:16:22 +0000 Subject: [PATCH] 0.9.4claws19 * src/procmsg.c * src/common/utils.h add possibility to check all nodes with the same subject for subject threading, not only the oldest node. Should not break threads anymore if the oldest node is thread_by_subject_max_age days older then parent, because it can now find a child of oldest node as new parent. --- ChangeLog.claws | 10 ++++ configure.ac | 2 +- src/common/utils.h | 18 ------- src/procmsg.c | 127 +++++++++++++++++++++++++++++---------------- 4 files changed, 92 insertions(+), 65 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index a823f9086..a1c543258 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,13 @@ +2003-08-14 [christoph] 0.9.4claws19 + + * src/procmsg.c + * src/common/utils.h + add possibility to check all nodes with the same subject for + subject threading, not only the oldest node. Should not break + threads anymore if the oldest node is thread_by_subject_max_age + days older then parent, because it can now find a child of + oldest node as new parent. + 2003-08-11 [christoph] 0.9.4claws18 * src/plugins/spamassassin/spamassassin.c diff --git a/configure.ac b/configure.ac index 395b42d3c..9d2f68164 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=4 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=18 +EXTRA_VERSION=19 if test $EXTRA_VERSION -eq 0; then VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}claws else diff --git a/src/common/utils.h b/src/common/utils.h index 8ce95a99e..118cda31d 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -413,24 +413,6 @@ void subject_table_insert(GHashTable *subject_table, gchar * subject, void subject_table_remove(GHashTable *subject_table, gchar * subject); gint subject_get_prefix_length (const gchar *subject); -/* The following macros have the same preconditions as the cleanless - * functions above, but work with clean subjects (subject lines already - * corrected for the reply prefixes */ -#define subject_table_lookup_clean(t, s) \ - g_hash_table_lookup((t), (s) ? (s) : "") - -#define subject_table_insert_clean(t, s, d) \ - do { \ - if ((s) != NULL && (*(s)) != 0) \ - g_hash_table_insert((t), (s), (d)); \ - } while (0) - -#define subject_table_remove_clean(t, s) \ - do { \ - if ((s) != NULL) \ - g_hash_table_remove((t), (s)); \ - } while (0) - /* quoting recognition */ const gchar * line_has_quote_char (const gchar *str, const gchar *quote_chars); diff --git a/src/procmsg.c b/src/procmsg.c index d89b35ef2..2b0034229 100644 --- a/src/procmsg.c +++ b/src/procmsg.c @@ -152,20 +152,94 @@ static gboolean procmsg_ignore_node(GNode *node, gpointer data) later than its child.) */ +static void subject_relation_insert(GRelation *relation, GNode *node) +{ + gchar *subject; + MsgInfo *msginfo; + + g_return_if_fail(relation != NULL); + g_return_if_fail(node != NULL); + msginfo = (MsgInfo *) node->data; + g_return_if_fail(msginfo != NULL); + + subject = msginfo->subject; + if (subject == NULL) + return; + subject += subject_get_prefix_length(subject); + + g_relation_insert(relation, subject, node); +} + +static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo) +{ + gchar *subject; + GTuples *tuples; + GNode *node = NULL; + + g_return_val_if_fail(relation != NULL, NULL); + + subject = msginfo->subject; + if (subject == NULL) + return NULL; + subject += subject_get_prefix_length(subject); + + tuples = g_relation_select(relation, subject, 0); + if (tuples == NULL) + return NULL; + + if (tuples->len > 0) { + int i; + GNode *relation_node; + MsgInfo *relation_msginfo, *best_msginfo; + gboolean match; + + /* check all nodes with the same subject to find the best parent */ + for (i = 0; i < tuples->len; i++) { + relation_node = (GNode *) g_tuples_index(tuples, i, 1); + relation_msginfo = (MsgInfo *) relation_node->data; + match = FALSE; + + /* best node should be the oldest in the found nodes */ + /* parent node must not be older then msginfo */ + if (best_msginfo->date_t < relation_msginfo->date_t && + relation_msginfo->date_t < msginfo->date_t) + match = TRUE; + + /* parent node must not be more then thread_by_subject_max_age + days older then msginfo */ + if (abs(difftime(msginfo->date_t, relation_msginfo->date_t)) > + prefs_common.thread_by_subject_max_age * 3600 * 24) + match = FALSE; + + /* can add new tests for all matching + nodes found by subject */ + + if (match) { + node = relation_node; + best_msginfo = relation_msginfo; + } + } + } + + g_tuples_destroy(tuples); + return node; +} + /* return the reversed thread tree */ GNode *procmsg_get_thread_tree(GSList *mlist) { GNode *root, *parent, *node, *next, *last; GNode *prev; /* CLAWS */ GHashTable *msgid_table; - GHashTable *subject_table; + GRelation *subject_relation; MsgInfo *msginfo; const gchar *msgid; const gchar *subject; root = g_node_new(NULL); msgid_table = g_hash_table_new(g_str_hash, g_str_equal); - subject_table = g_hash_table_new(g_str_hash, g_str_equal); + subject_relation = g_relation_new(2); + g_relation_index(subject_relation, 0, g_str_hash, g_str_equal); for (; mlist != NULL; mlist = mlist->next) { msginfo = (MsgInfo *)mlist->data; @@ -175,39 +249,17 @@ GNode *procmsg_get_thread_tree(GSList *mlist) parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto); if (parent == NULL) { parent = root; - } else { - if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { - procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0); - procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0); - } } } node = g_node_insert_data_before (parent, parent == root ? parent->children : NULL, msginfo); - if ((msgid = msginfo->msgid) && - g_hash_table_lookup(msgid_table, msgid) == NULL) + if ((msgid = msginfo->msgid) && g_hash_table_lookup(msgid_table, msgid) == NULL) g_hash_table_insert(msgid_table, (gchar *)msgid, node); - /* CLAWS: add subject to table (without prefix) */ + /* CLAWS: add subject to relation (without prefix) */ if (prefs_common.thread_by_subject) { - GNode *found_subject = NULL; - - subject = msginfo->subject; - subject += subject_get_prefix_length(subject); - found_subject = subject_table_lookup_clean - (subject_table, (gchar *) subject); - - if (found_subject == NULL) - subject_table_insert_clean(subject_table, (gchar *) subject, - node); - else if ( ((MsgInfo*)(found_subject->data))->date_t > - ((MsgInfo*)(node->data))->date_t ) { - /* replace if msg in table is older than current one - TODO: should create a list of messages with same subject */ - subject_table_remove_clean(subject_table, (gchar *) subject); - subject_table_insert_clean(subject_table, (gchar *) subject, node); - } + subject_relation_insert(subject_relation, node); } } @@ -226,9 +278,6 @@ GNode *procmsg_get_thread_tree(GSList *mlist) g_node_unlink(node); g_node_insert_before (parent, parent->children, node); - /* CLAWS: ignore thread */ - if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) - g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, procmsg_ignore_node, NULL); } } last = (next == NULL) ? prev : node; @@ -239,11 +288,10 @@ GNode *procmsg_get_thread_tree(GSList *mlist) for (node = last; node && node != NULL;) { next = node->prev; msginfo = (MsgInfo *) node->data; - subject = msginfo->subject + subject_get_prefix_length(msginfo->subject); /* may not parentize if parent was delivered after childs */ if (subject != msginfo->subject) - parent = subject_table_lookup_clean(subject_table, (gchar *) subject); + parent = subject_relation_lookup(subject_relation, msginfo); else parent = NULL; @@ -254,31 +302,18 @@ GNode *procmsg_get_thread_tree(GSList *mlist) parent = NULL; if (parent == node) parent = NULL; - /* make new thread parent if too old compared to previous one; probably - breaks ignoring threads for subject threading. not accurate because - the tree isn't sorted by date. */ - if (parent && abs(difftime(msginfo->date_t, ((MsgInfo *)parent->data)->date_t)) > - prefs_common.thread_by_subject_max_age * 3600 * 24) { - subject_table_remove_clean(subject_table, (gchar *) subject); - subject_table_insert_clean(subject_table, (gchar *) subject, node); - parent = NULL; - } } if (parent) { g_node_unlink(node); g_node_append(parent, node); - /* CLAWS: ignore thread */ - if (MSG_IS_IGNORE_THREAD(((MsgInfo *)parent->data)->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) { - g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1, procmsg_ignore_node, NULL); - } } node = next; } } - g_hash_table_destroy(subject_table); + g_relation_destroy(subject_relation); g_hash_table_destroy(msgid_table); return root; -- 2.25.1