+2002-11-25 [colin] 0.8.6claws4
+
+ * src/utils.[ch]
+ Add slist_concat_unique(), function to merge
+ two GSList filtering dups
+ * src/folder.[ch]
+ * src/summaryview.[ch]
+ * src/folderview.c
+ * src/main.c
+ Add detection/update/display of unread answers
+ to marked mails
+ * src/procmsg.[ch]
+ Add procmsg_find_children()
+ Add procmsg_msg_has_marked_parent()
+
2002-11-25 [colin] 0.8.6claws3
* src/ssl_certificate.[ch]
MICRO_VERSION=6
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=claws3
+EXTRA_VERSION=claws4
VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION
dnl set $target
item->mtime = 0;
item->new = 0;
item->unread = 0;
+ item->unreadmarked = 0;
item->total = 0;
item->last_num = -1;
item->cache = NULL;
{
guint new;
guint unread;
+ guint unreadmarked;
guint total;
};
count->new += item->new;
count->unread += item->unread;
+ count->unreadmarked += item->unreadmarked;
count->total += item->total;
}
-void folder_count_total_msgs(guint *new, guint *unread, guint *total)
+void folder_count_total_msgs(guint *new, guint *unread, guint *unreadmarked, guint *total)
{
struct TotalMsgCount count;
- count.new = count.unread = count.total = 0;
+ count.new = count.unread = count.unreadmarked = count.total = 0;
debug_print("Counting total number of messages...\n");
*new = count.new;
*unread = count.unread;
+ *unreadmarked = count.unreadmarked;
*total = count.total;
}
{
Folder *folder;
GSList *folder_list = NULL, *cache_list = NULL, *folder_list_cur, *cache_list_cur, *new_list = NULL;
- guint newcnt = 0, unreadcnt = 0, totalcnt = 0;
+ guint newcnt = 0, unreadcnt = 0, totalcnt = 0, unreadmarkedcnt = 0;
guint cache_max_num, folder_max_num, cache_cur_num, folder_cur_num;
gboolean contentchange = FALSE;
newcnt++;
if (MSG_IS_UNREAD(newmsginfo->flags) && !MSG_IS_IGNORE_THREAD(newmsginfo->flags))
unreadcnt++;
+ if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
+ unreadmarkedcnt++;
procmsg_msginfo_free(newmsginfo);
}
newcnt++;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
unreadcnt++;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ unreadmarkedcnt++;
}
totalcnt++;
procmsg_msginfo_free(msginfo);
newcnt++;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
unreadcnt++;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ unreadmarkedcnt++;
totalcnt++;
procmsg_msginfo_free(msginfo);
}
newcnt++;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
unreadcnt++;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ unreadmarkedcnt++;
totalcnt++;
procmsg_msginfo_free(msginfo);
debug_print("Added newly found message %d to cache.\n", num);
item->new = newcnt;
item->unread = unreadcnt;
item->total = totalcnt;
-
+ item->unreadmarked = unreadmarkedcnt;
g_slist_free(new_list);
folder_update_item(item, contentchange);
dest->new++;
if (MSG_IS_UNREAD(msginfo->flags))
dest->unread++;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ dest->unreadmarked++;
dest->total++;
dest->need_update = TRUE;
dest->new++;
if (MSG_IS_UNREAD(newmsginfo->flags))
dest->unread++;
+ if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
+ dest->unreadmarked++;
dest->total++;
dest->need_update = TRUE;
msginfo->folder->new--;
if (MSG_IS_UNREAD(msginfo->flags))
msginfo->folder->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ msginfo->folder->unreadmarked--;
msginfo->folder->total--;
msginfo->folder->need_update = TRUE;
}
dest->new++;
if (MSG_IS_UNREAD(newmsginfo->flags))
dest->unread++;
+ if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
+ dest->unreadmarked++;
dest->total++;
dest->need_update = TRUE;
msginfo->folder->new--;
if (MSG_IS_UNREAD(msginfo->flags))
msginfo->folder->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ msginfo->folder->unreadmarked--;
msginfo->folder->total--;
msginfo->folder->need_update = TRUE;
}
dest->new++;
if (MSG_IS_UNREAD(newmsginfo->flags))
dest->unread++;
+ if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
+ dest->unreadmarked++;
dest->total++;
dest->need_update = TRUE;
dest->new++;
if (MSG_IS_UNREAD(newmsginfo->flags))
dest->unread++;
+ if (MSG_IS_UNREAD(newmsginfo->flags) && procmsg_msg_has_marked_parent(newmsginfo))
+ dest->unreadmarked++;
dest->total++;
dest->need_update = TRUE;
item->new--;
if (MSG_IS_UNREAD(msginfo->flags))
item->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ item->unreadmarked--;
procmsg_msginfo_free(msginfo);
msgcache_remove_msg(item->cache, num);
}
item->new = 0;
item->unread = 0;
+ item->unreadmarked = 0;
item->total = 0;
item->need_update = TRUE;
}
gboolean ret_rcpt = FALSE, hidereadmsgs = FALSE; /* CLAWS */
FolderSortKey sort_key = SORT_BY_NONE;
FolderSortType sort_type = SORT_ASCENDING;
- gint new = 0, unread = 0, total = 0;
+ gint new = 0, unread = 0, total = 0, unreadmarked = 0;
time_t mtime = 0;
g_return_val_if_fail(node->data != NULL, FALSE);
new = atoi(attr->value);
else if (!strcmp(attr->name, "unread"))
unread = atoi(attr->value);
+ else if (!strcmp(attr->name, "unreadmarked"))
+ unreadmarked = atoi(attr->value);
else if (!strcmp(attr->name, "total"))
total = atoi(attr->value);
else if (!strcmp(attr->name, "no_sub"))
item->mtime = mtime;
item->new = new;
item->unread = unread;
+ item->unreadmarked = unreadmarked;
item->total = total;
item->no_sub = no_sub;
item->no_select = no_select;
}
fprintf(fp,
- " mtime=\"%lu\" new=\"%d\" unread=\"%d\" total=\"%d\"",
- item->mtime, item->new, item->unread, item->total);
+ " mtime=\"%lu\" new=\"%d\" unread=\"%d\" unreadmarked=\"%d\" total=\"%d\"",
+ item->mtime, item->new, item->unread, item->unreadmarked, item->total);
if (item->account)
fprintf(fp, " account_id=\"%d\"",
gint new;
gint unread;
gint total;
+ gint unreadmarked;
gint last_num;
gpointer data);
void folder_count_total_msgs (guint *new,
guint *unread,
+ guint *unreadmarked,
guint *total);
Folder *folder_find_from_path (const gchar *path);
prefs_common.display_folder_unread) {
if (item->unread > 0)
- str = g_strdup_printf("%s (%d%s)", name, item->unread,
- add_unread_mark ? "+" : "");
+ str = g_strdup_printf("%s (%d%s%s)", name, item->unread,
+ add_unread_mark ? "+" : "",
+ item->unreadmarked > 0 ? "!":"");
else
str = g_strdup_printf("%s (+)", name);
gtk_ctree_set_node_info(ctree, node, str, FOLDER_SPACING,
xpm, mask, openxpm, openmask,
FALSE, GTK_CTREE_ROW(node)->expanded);
g_free(str);
- } else
- gtk_ctree_set_node_info(ctree, node, name, FOLDER_SPACING,
+ } else {
+ str = g_strdup_printf("%s%s", name,
+ item->unreadmarked > 0 ? " (!)":"");
+
+ gtk_ctree_set_node_info(ctree, node, str, FOLDER_SPACING,
xpm, mask, openxpm, openmask,
FALSE, GTK_CTREE_ROW(node)->expanded);
+ g_free(str);
+ }
g_free(name);
if (!item->parent) {
use_color =
(item->new > 0) ||
(add_unread_mark &&
- folderview_have_new_children(folderview, node));
+ folderview_have_new_children(folderview, node));
}
gtk_ctree_node_set_foreground(ctree, node, NULL);
} else if (!strncmp(buf, "offline", 7)) {
main_window_toggle_work_offline(mainwin, TRUE);
} else if (!strncmp(buf, "status", 6)) {
- guint new, unread, total;
+ guint new, unread, unreadmarked, total;
- folder_count_total_msgs(&new, &unread, &total);
- g_snprintf(buf, sizeof(buf), "%d %d %d\n", new, unread, total);
+ folder_count_total_msgs(&new, &unread, &unreadmarked, &total);
+ g_snprintf(buf, sizeof(buf), "%d %d %d %d\n", new, unread, unreadmarked, total);
fd_write(sock, buf, strlen(buf));
}
static GHashTable *procmsg_read_mark_file (const gchar *folder);
void procmsg_msginfo_write_flags (MsgInfo *msginfo);
-
+static void procmsg_update_unread_children (MsgInfo *info, gboolean newly_marked);
GHashTable *procmsg_msg_hash_table_create(GSList *mlist)
{
return ret;
}
+
gint procmsg_remove_special_headers(const gchar *in, const gchar *out)
{
FILE *fp, *outfp;
item->need_update = TRUE;
}
+ if (!MSG_IS_UNREAD(msginfo->flags) &&(perm_flags & MSG_UNREAD)
+ && procmsg_msg_has_marked_parent(msginfo)) {
+ item->unreadmarked++;
+ item->need_update = TRUE;
+ }
+
+ if (!MSG_IS_MARKED(msginfo->flags) && (perm_flags & MSG_MARKED)) {
+ procmsg_update_unread_children(msginfo, TRUE);
+ }
+
+
/* if ignore thread flag is set */
if ((perm_flags & MSG_IGNORE_THREAD) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
if (MSG_IS_NEW(msginfo->flags) || (perm_flags & MSG_NEW)) {
item->unread--;
item->need_update = TRUE;
}
+ if ((perm_flags & MSG_UNREAD) || (MSG_IS_UNREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))) {
+ item->unreadmarked--;
+ item->need_update = TRUE;
+ }
+ if ((perm_flags & MSG_MARKED) || MSG_IS_MARKED(msginfo->flags)
+ && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
+ procmsg_update_unread_children(msginfo, FALSE);
+ }
+
}
if (MSG_IS_IMAP(msginfo->flags))
item->unread--;
item->need_update = TRUE;
}
+
+ if (MSG_IS_UNREAD(msginfo->flags) && (perm_flags & MSG_UNREAD)
+ && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo)) {
+ item->unreadmarked--;
+ item->need_update = TRUE;
+ }
+
+ if (MSG_IS_MARKED(msginfo->flags) && (perm_flags & MSG_MARKED)
+ && !MSG_IS_IGNORE_THREAD(msginfo->flags)) {
+ procmsg_update_unread_children(msginfo, FALSE);
+ }
/* if ignore thread flag is unset */
if ((perm_flags & MSG_IGNORE_THREAD) && MSG_IS_IGNORE_THREAD(msginfo->flags)) {
item->unread++;
item->need_update = TRUE;
}
+ if (MSG_IS_UNREAD(msginfo->flags) && !(perm_flags & MSG_UNREAD)
+ && procmsg_msg_has_marked_parent(msginfo)) {
+ item->unreadmarked++;
+ item->need_update = TRUE;
+ }
+ if (MSG_IS_MARKED(msginfo->flags) && !(perm_flags & MSG_MARKED)) {
+ procmsg_update_unread_children(msginfo, TRUE);
+ }
+
}
if (MSG_IS_IMAP(msginfo->flags))
g_free(destdir);
}
+gboolean procmsg_msg_has_marked_parent (MsgInfo *info)
+{
+ MsgInfo *tmp;
+ g_return_val_if_fail(info != NULL, FALSE);
+ if (info != NULL && info->folder != NULL && info->inreplyto != NULL) {
+ tmp = folder_item_get_msginfo_by_msgid(info->folder, info->inreplyto);
+ if (tmp && MSG_IS_MARKED(tmp->flags)) {
+ procmsg_msginfo_free(tmp);
+ return TRUE;
+ } else if (tmp != NULL) {
+ gboolean result = procmsg_msg_has_marked_parent(tmp);
+ procmsg_msginfo_free(tmp);
+ return result;
+ } else {
+ return FALSE;
+ }
+ } else
+ return FALSE;
+}
+
+GSList *procmsg_find_children (MsgInfo *info)
+{
+ GSList *children = NULL;
+ GSList *all, *cur;
+
+ g_return_val_if_fail(info!=NULL, NULL);
+ if (info->msgid == NULL)
+ return NULL;
+ all = folder_item_get_msg_list(info->folder);
+ for (cur = all; cur != NULL; cur = g_slist_next(cur)) {
+ MsgInfo *tmp = (MsgInfo *)cur->data;
+ if (tmp->inreplyto && !strcmp(tmp->inreplyto, info->msgid)) {
+ GSList *grand_children;
+ children = g_slist_prepend(children, tmp);
+ grand_children = procmsg_find_children(tmp);
+ children = slist_concat_unique(children, grand_children);
+ g_slist_free(grand_children);
+ }
+ if (tmp && tmp != info)
+ procmsg_msginfo_free(tmp);
+ }
+
+ return children;
+}
+
+static void procmsg_update_unread_children (MsgInfo *info, gboolean newly_marked)
+{
+ GSList *children = procmsg_find_children(info);
+ GSList *cur;
+ for (cur = children; cur != NULL; cur = g_slist_next(cur)) {
+ MsgInfo *tmp = (MsgInfo *)cur->data;
+ if(MSG_IS_UNREAD(tmp->flags) && !MSG_IS_IGNORE_THREAD(tmp->flags)) {
+ if(newly_marked)
+ info->folder->unreadmarked++;
+ else
+ info->folder->unreadmarked--;
+ info->folder->need_update = TRUE;
+ }
+ procmsg_msginfo_free(tmp);
+ }
+}
+
/*
* callback handling
*/
gint procmsg_remove_special_headers (const gchar *in,
const gchar *out);
+gboolean procmsg_msg_has_marked_parent (MsgInfo *info);
+GSList *procmsg_find_children (MsgInfo *info);
#endif /* __PROCMSG_H__ */
summaryview->newmsgs++;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
summaryview->unread++;
+ if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked++;
+
if (MSG_IS_DELETED(msginfo->flags))
summaryview->deleted++;
summaryview->newmsgs++;
if (MSG_IS_UNREAD(msginfo->flags)&& !MSG_IS_IGNORE_THREAD(msginfo->flags))
summaryview->unread++;
+ if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked++;
if (MSG_IS_DELETED(msginfo->flags))
summaryview->deleted++;
if (MSG_IS_MOVE(msginfo->flags))
summaryview->newmsgs--;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
summaryview->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked--;
if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) {
procmsg_msginfo_unset_flags
(msginfo, MSG_NEW | MSG_UNREAD, 0);
summary_set_row_marks(summaryview, GTK_CTREE_NODE(cur->data));
}
+static gboolean summary_update_unread_children (SummaryView *summaryview, MsgInfo *info, gboolean newly_marked)
+{
+ GSList *children = procmsg_find_children(info);
+ GSList *cur;
+ gboolean changed = FALSE;
+ for (cur = children; cur != NULL; cur = g_slist_next(cur)) {
+ MsgInfo *tmp = (MsgInfo *)cur->data;
+ if(MSG_IS_UNREAD(tmp->flags) && !MSG_IS_IGNORE_THREAD(tmp->flags)) {
+ if(newly_marked)
+ summaryview->unreadmarked++;
+ else
+ summaryview->unreadmarked--;
+ changed = TRUE;
+ }
+ procmsg_msginfo_free(tmp);
+ }
+ return changed;
+}
+
static void summary_mark_row(SummaryView *summaryview, GtkCTreeNode *row)
{
gboolean changed = FALSE;
summaryview->copied--;
changed = TRUE;
}
+ changed |= summary_update_unread_children (summaryview, msginfo, TRUE);
+
if (changed && !prefs_common.immediate_exec) {
msginfo->to_folder->op_count--;
if (msginfo->to_folder->op_count == 0)
summaryview->newmsgs--;
if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
summaryview->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked--;
procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
summary_set_row_marks(summaryview, row);
if (!MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags))
summaryview->unread++;
+ if (!MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)
+ && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked++;
+
procmsg_msginfo_unset_flags(msginfo, MSG_REPLIED | MSG_FORWARDED, 0);
procmsg_msginfo_set_flags(msginfo, MSG_UNREAD, 0);
debug_print("Message %d is marked as unread\n",
summaryview->copied--;
changed = TRUE;
}
+ changed |= summary_update_unread_children (summaryview, msginfo, FALSE);
+
if (changed && !prefs_common.immediate_exec) {
msginfo->to_folder->op_count--;
if (msginfo->to_folder->op_count == 0)
summaryview->copied--;
changed = TRUE;
}
+ changed |= summary_update_unread_children (summaryview, msginfo, FALSE);
+
if (changed && !prefs_common.immediate_exec) {
msginfo->to_folder->op_count--;
if (msginfo->to_folder->op_count == 0)
switch (column < 0 ? column : summaryview->col_state[column].type) {
case S_COL_MARK:
if (MSG_IS_MARKED(msginfo->flags)) {
- procmsg_msginfo_unset_flags(msginfo, MSG_MARKED, 0);
- summary_set_row_marks(summaryview, row);
+ summary_unmark_row(summaryview, row);
} else
summary_mark_row(summaryview, row);
break;
summaryview->newmsgs--;
if (MSG_IS_UNREAD(msginfo->flags))
summaryview->unread--;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked--;
procmsg_msginfo_set_flags(msginfo, MSG_IGNORE_THREAD, 0);
summaryview->newmsgs++;
if (MSG_IS_UNREAD(msginfo->flags))
summaryview->unread++;
+ if (MSG_IS_UNREAD(msginfo->flags) && procmsg_msg_has_marked_parent(msginfo))
+ summaryview->unreadmarked++;
procmsg_msginfo_unset_flags(msginfo, MSG_IGNORE_THREAD, 0);
/* current message status */
gint newmsgs;
gint unread;
+ gint unreadmarked;
gint messages;
off_t total_size;
gint deleted;
}
}
+GSList *slist_concat_unique (GSList *first, GSList *second)
+{
+ GSList *tmp, *ret;
+ if (first == NULL) {
+ if (second == NULL)
+ return NULL;
+ else
+ return second;
+ } else if (second == NULL)
+ return first;
+ ret = first;
+ for (tmp = second; tmp != NULL; tmp = g_slist_next(tmp)) {
+ if (g_slist_find(ret, tmp->data) == NULL)
+ ret = g_slist_prepend(ret, tmp->data);
+ }
+ return ret;
+}
+
static void hash_free_strings_func(gpointer key, gpointer value, gpointer data)
{
g_free(key);
gint c);
void extract_address (gchar *str);
+GSList *slist_concat_unique (GSList *first,
+ GSList *second);
GSList *address_list_append (GSList *addr_list,
const gchar *str);
GSList *references_list_append (GSList *msgid_list,