talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 8b44bf1715adf6a18e24fb421e40a299acbc1476
parent b4814bb34f53dc42476d6748cd88b4d2663aa5e6
Author: Paweł Pękala <c0rn@gazeta.pl>
Date:   Sat, 19 Nov 2011 15:14:02 +0000

2011-11-19 [pawel]	3.7.10cvs90

	* src/folder.c
	* src/folder.h
	* src/folder_item_prefs.c
	* src/folderview.c
	* src/mainwindow.c
	* src/mainwindow.h
	* src/summaryview.c
	* src/summaryview.h
	* src/gtk/authors.h
		Fix bug #1563 'Folder view: show complete threads if they
		contain unread messages'
		Add option to show only threads with unread messages
		initial patch by Paul Ollis, my small additions:
		- when checking thread for unread finish on first unread
		- make thread options unavailable when threading is off
		- hide_unread_msgs and hide_unread_threads are mutually
		  exclusive options, set menus sensitivity accordingly
		- set folder item icon type similiar to hide_unread_msgs

Diffstat:
MChangeLog | 21+++++++++++++++++++++
MPATCHSETS | 1+
Mconfigure.ac | 2+-
Msrc/folder.c | 6++++++
Msrc/folder.h | 2++
Msrc/folder_item_prefs.c | 1+
Msrc/folderview.c | 10+++++-----
Msrc/gtk/authors.h | 1+
Msrc/mainwindow.c | 27+++++++++++++++++++++++++++
Msrc/mainwindow.h | 3++-
Msrc/summaryview.c | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/summaryview.h | 2++
12 files changed, 138 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,24 @@ +2011-11-19 [pawel] 3.7.10cvs90 + + * src/folder.c + * src/folder.h + * src/folder_item_prefs.c + * src/folderview.c + * src/mainwindow.c + * src/mainwindow.h + * src/summaryview.c + * src/summaryview.h + * src/gtk/authors.h + Fix bug #1563 'Folder view: show complete threads if they + contain unread messages' + Add option to show only threads with unread messages + initial patch by Paul Ollis, my small additions: + - when checking thread for unread finish on first unread + - make thread options unavailable when threading is off + - hide_unread_msgs and hide_unread_threads are mutually + exclusive options, set menus sensitivity accordingly + - set folder item icon type similiar to hide_unread_msgs + 2011-11-19 [colin] 3.7.10cvs89 * src/procheader.c diff --git a/PATCHSETS b/PATCHSETS @@ -4293,3 +4293,4 @@ ( cvs diff -u -r 1.382.2.594 -r 1.382.2.595 src/compose.c; cvs diff -u -r 1.47.2.54 -r 1.47.2.55 src/procheader.c; cvs diff -u -r 1.11.2.12 -r 1.11.2.13 src/procheader.h; ) > 3.7.10cvs87.patchset ( cvs diff -u -r 1.382.2.595 -r 1.382.2.596 src/compose.c; cvs diff -u -r 1.274.2.336 -r 1.274.2.337 src/mainwindow.c; cvs diff -u -r 1.83.2.181 -r 1.83.2.182 src/mimeview.c; cvs diff -u -r 1.20.2.35 -r 1.20.2.36 src/mimeview.h; cvs diff -u -r 1.204.2.205 -r 1.204.2.206 src/prefs_common.c; cvs diff -u -r 1.103.2.134 -r 1.103.2.135 src/prefs_common.h; ) > 3.7.10cvs88.patchset ( cvs diff -u -r 1.47.2.55 -r 1.47.2.56 src/procheader.c; ) > 3.7.10cvs89.patchset +( cvs diff -u -r 1.213.2.202 -r 1.213.2.203 src/folder.c; cvs diff -u -r 1.87.2.64 -r 1.87.2.65 src/folder.h; cvs diff -u -r 1.2.2.37 -r 1.2.2.38 src/folder_item_prefs.c; cvs diff -u -r 1.207.2.225 -r 1.207.2.226 src/folderview.c; cvs diff -u -r 1.274.2.337 -r 1.274.2.338 src/mainwindow.c; cvs diff -u -r 1.39.2.61 -r 1.39.2.62 src/mainwindow.h; cvs diff -u -r 1.395.2.438 -r 1.395.2.439 src/summaryview.c; cvs diff -u -r 1.68.2.57 -r 1.68.2.58 src/summaryview.h; cvs diff -u -r 1.1.2.75 -r 1.1.2.76 src/gtk/authors.h; ) > 3.7.10cvs90.patchset diff --git a/configure.ac b/configure.ac @@ -12,7 +12,7 @@ MINOR_VERSION=7 MICRO_VERSION=10 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=89 +EXTRA_VERSION=90 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/folder.c b/src/folder.c @@ -572,6 +572,8 @@ void folder_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag) item->hide_read_msgs = *attr->value == '1' ? TRUE : FALSE; else if (!strcmp(attr->name, "hidedelmsgs")) item->hide_del_msgs = *attr->value == '1' ? TRUE : FALSE; + else if (!strcmp(attr->name, "hidereadthreads")) + item->hide_read_threads = *attr->value == '1' ? TRUE : FALSE; else if (!strcmp(attr->name, "reqretrcpt")) item->ret_rcpt = *attr->value == '1' ? TRUE : FALSE; else if (!strcmp(attr->name, "sort_key")) { @@ -656,6 +658,7 @@ XMLTag *folder_item_get_xml(Folder *folder, FolderItem *item) xml_tag_add_attr(tag, xml_attr_new("threaded", item->threaded ? "1" : "0")); xml_tag_add_attr(tag, xml_attr_new("hidereadmsgs", item->hide_read_msgs ? "1" : "0")); xml_tag_add_attr(tag, xml_attr_new("hidedelmsgs", item->hide_del_msgs ? "1" : "0")); + xml_tag_add_attr(tag, xml_attr_new("hidereadthreads", item->hide_read_threads ? "1" : "0")); if (item->ret_rcpt) xml_tag_add_attr(tag, xml_attr_new("reqretrcpt", "1")); @@ -3278,6 +3281,7 @@ static FolderItem *folder_item_move_recursive(FolderItem *src, FolderItem *dest, new_item->ret_rcpt = src->ret_rcpt; new_item->hide_read_msgs = src->hide_read_msgs; new_item->hide_del_msgs = src->hide_del_msgs; + new_item->hide_read_threads = src->hide_read_threads; new_item->sort_key = src->sort_key; new_item->sort_type = src->sort_type; @@ -4350,6 +4354,7 @@ static void folder_item_restore_persist_prefs(FolderItem *item, GHashTable *ppta item->ret_rcpt = pp->ret_rcpt; item->hide_read_msgs = pp->hide_read_msgs; item->hide_del_msgs = pp->hide_del_msgs; + item->hide_read_threads = pp->hide_read_threads; item->sort_key = pp->sort_key; item->sort_type = pp->sort_type; } @@ -4376,6 +4381,7 @@ static void folder_get_persist_prefs_recursive(GNode *node, GHashTable *pptable) pp->ret_rcpt = item->ret_rcpt; pp->hide_read_msgs = item->hide_read_msgs; pp->hide_del_msgs = item->hide_del_msgs; + pp->hide_read_threads = item->hide_read_threads; pp->sort_key = item->sort_key; pp->sort_type = item->sort_type; g_hash_table_insert(pptable, id, pp); diff --git a/src/folder.h b/src/folder.h @@ -672,6 +672,7 @@ struct _FolderItem 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 */ @@ -711,6 +712,7 @@ struct _PersistPrefs guint hide_read_msgs : 1; /* CLAWS */ guint ret_rcpt : 1; /* CLAWS */ guint hide_del_msgs : 1; /* CLAWS */ + guint hide_read_threads : 1; }; struct _FolderUpdateData diff --git a/src/folder_item_prefs.c b/src/folder_item_prefs.c @@ -331,6 +331,7 @@ void folder_item_prefs_copy_prefs(FolderItem * src, FolderItem * dest) dest->ret_rcpt = src->ret_rcpt; dest->hide_read_msgs = src->hide_read_msgs; dest->hide_del_msgs = src->hide_del_msgs; + dest->hide_read_threads = src->hide_read_threads; dest->sort_key = src->sort_key; dest->sort_type = src->sort_type; diff --git a/src/folderview.c b/src/folderview.c @@ -1461,7 +1461,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) } switch (stype) { case F_INBOX: - if (item->hide_read_msgs) { + if (item->hide_read_msgs || item->hide_read_threads) { xpm = mark?m_inboxhrmxpm:inboxhrmxpm; openxpm = mark?m_inboxopenhrmxpm:inboxopenhrmxpm; } else { @@ -1470,7 +1470,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) } break; case F_OUTBOX: - if (item->hide_read_msgs) { + if (item->hide_read_msgs || item->hide_read_threads) { xpm = mark?m_outboxhrmxpm:outboxhrmxpm; openxpm = mark?m_outboxopenhrmxpm:outboxopenhrmxpm; } else { @@ -1479,7 +1479,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) } break; case F_QUEUE: - if (item->hide_read_msgs) { + if (item->hide_read_msgs || item->hide_read_threads) { xpm = mark?m_queuehrmxpm:queuehrmxpm; openxpm = mark?m_queueopenhrmxpm:queueopenhrmxpm; } else { @@ -1488,7 +1488,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) } break; case F_TRASH: - if (item->hide_read_msgs) { + if (item->hide_read_msgs || item->hide_read_threads) { xpm = mark?m_trashhrmxpm:trashhrmxpm; openxpm = mark?m_trashopenhrmxpm:trashopenhrmxpm; } else { @@ -1501,7 +1501,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node) openxpm = mark?m_draftsopenxpm:draftsopenxpm; break; default: - if (item->hide_read_msgs) { + if (item->hide_read_msgs || item->hide_read_threads) { xpm = mark?m_folderhrmxpm:folderhrmxpm; openxpm = mark?m_folderopenhrmxpm:folderopenhrmxpm; } else { diff --git a/src/gtk/authors.h b/src/gtk/authors.h @@ -207,6 +207,7 @@ static char *CONTRIBS_LIST[] = { "Jens Oberender", "Ofer", "Ohmasa", +"Paul Ollis", "Fredrik Olofssen", "Reza Pakdel", "Martin Pool", diff --git a/src/mainwindow.c b/src/mainwindow.c @@ -247,6 +247,8 @@ static void set_decode_cb (GtkAction *action, GtkRadioAction *current, gpointer static void hide_read_messages (GtkAction *action, gpointer data); +static void hide_read_threads (GtkAction *action, + gpointer data); static void hide_del_messages (GtkAction *action, gpointer data); @@ -763,6 +765,7 @@ static GtkToggleActionEntry mainwin_toggle_entries[] = { #endif {"View/ShowHide/ColumnHeaders", NULL, N_("Column headers"), NULL, NULL, G_CALLBACK(toggle_col_headers_cb) }, /* toggle */ {"View/ThreadView", NULL, N_("Th_read view"), "<control>T", NULL, G_CALLBACK(thread_cb) }, /* toggle */ + {"View/HideReadThreads", NULL, N_("Hide read threads"), NULL, NULL, G_CALLBACK(hide_read_threads) }, /* toggle */ {"View/HideReadMessages", NULL, N_("_Hide read messages"), NULL, NULL, G_CALLBACK(hide_read_messages) }, /* toggle */ {"View/HideDelMessages", NULL, N_("Hide deleted messages"), NULL, NULL, G_CALLBACK(hide_del_messages) }, /* toggle */ #ifndef MAEMO @@ -1718,6 +1721,7 @@ MainWindow *main_window_create() MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "ThreadView", "View/ThreadView", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "ExpandThreads", "View/ExpandThreads", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "CollapseThreads", "View/CollapseThreads", GTK_UI_MANAGER_MENUITEM) + MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "HideReadThreads", "View/HideReadThreads", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "HideReadMessages", "View/HideReadMessages", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "HideDelMessages", "View/HideDelMessages", GTK_UI_MANAGER_MENUITEM) MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "Separator3", "View/---", GTK_UI_MANAGER_SEPARATOR) @@ -3080,6 +3084,10 @@ SensitiveCond main_window_get_current_state(MainWindow *mainwin) if ((selection == SUMMARY_NONE && item->hide_read_msgs) || selection != SUMMARY_NONE) state |= M_HIDE_READ_MSG; + + if ((selection == SUMMARY_NONE && item->hide_read_threads) + || selection != SUMMARY_NONE) + state |= M_HIDE_READ_THREADS; } if (mainwin->summaryview->threaded) state |= M_THREADED; @@ -3208,6 +3216,7 @@ void main_window_set_menu_sensitive(MainWindow *mainwin) {"Menu/View/ThreadView" , M_EXEC|M_SUMMARY_ISLIST}, {"Menu/View/ExpandThreads" , M_MSG_EXIST|M_SUMMARY_ISLIST}, {"Menu/View/CollapseThreads" , M_MSG_EXIST|M_SUMMARY_ISLIST}, + {"Menu/View/HideReadThreads" , M_HIDE_READ_THREADS|M_SUMMARY_ISLIST}, {"Menu/View/HideReadMessages" , M_HIDE_READ_MSG|M_SUMMARY_ISLIST}, {"Menu/View/HideDelMessages" , M_SUMMARY_ISLIST}, {"Menu/View/Goto/Prev" , M_MSG_EXIST}, @@ -3370,10 +3379,18 @@ void main_window_set_menu_sensitive(MainWindow *mainwin) cm_toggle_menu_set_active_full(mainwin->ui_manager, "Menu/View/AllHeaders", mainwin->messageview->mimeview->textview->show_all_headers); cm_toggle_menu_set_active_full(mainwin->ui_manager, "Menu/View/ThreadView", (state & M_THREADED) != 0); + cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/ExpandThreads", (state & M_THREADED) != 0); + cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/CollapseThreads", (state & M_THREADED) != 0); + cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadThreads", (state & M_THREADED) != 0); cm_toggle_menu_set_active_full(mainwin->ui_manager, "Menu/View/Quotes/CollapseAll", (prefs_common.hide_quotes == 1)); cm_toggle_menu_set_active_full(mainwin->ui_manager, "Menu/View/Quotes/Collapse2", (prefs_common.hide_quotes == 2)); cm_toggle_menu_set_active_full(mainwin->ui_manager, "Menu/View/Quotes/Collapse3", (prefs_common.hide_quotes == 3)); + if (mainwin->summaryview->folder_item && mainwin->summaryview->folder_item->hide_read_msgs) + cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadThreads", FALSE); + if (mainwin->summaryview->folder_item && mainwin->summaryview->folder_item->hide_read_threads) + cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadMessages", FALSE); + main_window_menu_callback_unblock(mainwin); } @@ -4543,6 +4560,16 @@ static void hide_del_messages (GtkAction *action, gpointer data) summary_toggle_show_del_messages(mainwin->summaryview); } +static void hide_read_threads (GtkAction *action, gpointer data) +{ + MainWindow *mainwin = (MainWindow *)data; + GtkWidget *menuitem = gtk_ui_manager_get_widget(mainwin->ui_manager, "/Menu/View/HideReadThreads"); + if (!mainwin->summaryview->folder_item + || g_object_get_data(G_OBJECT(menuitem), "dont_toggle")) + return; + summary_toggle_show_read_threads(mainwin->summaryview); +} + static void thread_cb(GtkAction *action, gpointer data) { MainWindow *mainwin = (MainWindow *)data; diff --git a/src/mainwindow.h b/src/mainwindow.h @@ -66,7 +66,8 @@ typedef enum M_FOLDER_SELECTED = 1 << 25, M_SESSION_PASSWORDS = 1 << 26, M_DELETED_EXISTS = 1 << 27, - M_NOT_TRASH = 1 << 28 + M_NOT_TRASH = 1 << 28, + M_HIDE_READ_THREADS = 1 << 29 } SensitiveCond; typedef enum diff --git a/src/summaryview.c b/src/summaryview.c @@ -125,6 +125,8 @@ static void summary_set_hide_read_msgs_menu (SummaryView *summaryview, guint action); static void summary_set_hide_del_msgs_menu (SummaryView *summaryview, guint action); +static void summary_set_hide_read_threads_menu (SummaryView *summaryview, + guint action); static GtkCMCTreeNode *summary_find_prev_msg (SummaryView *summaryview, @@ -1212,6 +1214,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item) item?item->no_select:FALSE); summary_set_hide_read_msgs_menu(summaryview, FALSE); summary_set_hide_del_msgs_menu(summaryview, FALSE); + summary_set_hide_read_threads_menu(summaryview, FALSE); summary_clear_all(summaryview); summaryview->folder_item = item; summary_thaw(summaryview); @@ -1252,12 +1255,15 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item) mlist = folder_item_get_msg_list(item); } - if ((summaryview->folder_item->hide_read_msgs || summaryview->folder_item->hide_del_msgs) && + if ((summaryview->folder_item->hide_read_msgs + || summaryview->folder_item->hide_del_msgs + || summaryview->folder_item->hide_read_threads) && quicksearch_is_active(summaryview->quicksearch) == FALSE) { GSList *not_killed; summary_set_hide_read_msgs_menu(summaryview, summaryview->folder_item->hide_read_msgs); summary_set_hide_del_msgs_menu(summaryview, summaryview->folder_item->hide_del_msgs); + summary_set_hide_read_threads_menu(summaryview, summaryview->folder_item->hide_read_threads); not_killed = NULL; for(cur = mlist ; cur != NULL && cur->data != NULL ; cur = g_slist_next(cur)) { MsgInfo * msginfo = (MsgInfo *) cur->data; @@ -1292,6 +1298,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item) } else { summary_set_hide_read_msgs_menu(summaryview, FALSE); summary_set_hide_del_msgs_menu(summaryview, FALSE); + summary_set_hide_read_threads_menu(summaryview, FALSE); } if (quicksearch_is_active(summaryview->quicksearch)) { @@ -2472,6 +2479,7 @@ static void summary_status_show(SummaryView *summaryview) if (summaryview->folder_item->hide_read_msgs || summaryview->folder_item->hide_del_msgs + || summaryview->folder_item->hide_read_threads || quicksearch_is_active(summaryview->quicksearch)) { rowlist = GTK_CMCLIST(summaryview->ctree)->row_list; for (cur = rowlist; cur != NULL && cur->data != NULL; cur = cur->next) { @@ -2918,6 +2926,30 @@ static void summary_find_thread_age(GNode *gnode) msginfo->thread_date = most_recent; } +static gboolean summary_update_is_read(GNode *node, gpointer data) +{ + MsgInfo *msginfo = node->data; + gboolean *all_read = (gboolean *)data; + + if (MSG_IS_UNREAD(msginfo->flags)) { + *all_read = FALSE; + return TRUE; + } + return FALSE; +} + +static gboolean summary_thread_is_read(GNode *gnode) +{ + MsgInfo *msginfo = (MsgInfo *)gnode->data; + gboolean all_read = TRUE; + + if (!msginfo) + return all_read; + + g_node_traverse(gnode, G_IN_ORDER, G_TRAVERSE_ALL, -1, summary_update_is_read, &all_read); + return all_read; +} + static gboolean summary_insert_gnode_func(GtkCMCTree *ctree, guint depth, GNode *gnode, GtkCMCTreeNode *cnode, gpointer data) { @@ -3011,10 +3043,14 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, for (gnode = root->children; gnode != NULL; gnode = gnode->next) { - summary_find_thread_age(gnode); - node = gtk_sctree_insert_gnode - (ctree, NULL, node, gnode, - summary_insert_gnode_func, summaryview); + if (!summaryview->folder_item->hide_read_threads || + !summary_thread_is_read(gnode)) + { + summary_find_thread_age(gnode); + node = gtk_sctree_insert_gnode + (ctree, NULL, node, gnode, + summary_insert_gnode_func, summaryview); + } } g_node_destroy(root); @@ -7650,6 +7686,21 @@ void summary_toggle_show_del_messages(SummaryView *summaryview) summary_show(summaryview, summaryview->folder_item); } +void summary_toggle_show_read_threads(SummaryView *summaryview) +{ + FolderItemUpdateData source; + if (summaryview->folder_item->hide_read_threads) + summaryview->folder_item->hide_read_threads = 0; + else + summaryview->folder_item->hide_read_threads = 1; + + source.item = summaryview->folder_item; + source.update_flags = F_ITEM_UPDATE_NAME; + source.msg = NULL; + hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &source); + summary_show(summaryview, summaryview->folder_item); +} + static void summary_set_hide_read_msgs_menu (SummaryView *summaryview, guint action) { @@ -7663,6 +7714,19 @@ static void summary_set_hide_read_msgs_menu (SummaryView *summaryview, GINT_TO_POINTER(0)); } +static void summary_set_hide_read_threads_menu (SummaryView *summaryview, + guint action) +{ + GtkWidget *widget; + + widget = gtk_ui_manager_get_widget(summaryview->mainwin->ui_manager, "/Menu/View/HideReadThreads"); + g_object_set_data(G_OBJECT(widget), "dont_toggle", + GINT_TO_POINTER(1)); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(widget), action); + g_object_set_data(G_OBJECT(widget), "dont_toggle", + GINT_TO_POINTER(0)); +} + static void summary_set_hide_del_msgs_menu (SummaryView *summaryview, guint action) { diff --git a/src/summaryview.h b/src/summaryview.h @@ -302,6 +302,8 @@ void summary_set_column_order (SummaryView *summaryview); void summary_toggle_show_read_messages (SummaryView *summaryview); +void summary_toggle_show_read_threads + (SummaryView *summaryview); void summary_toggle_show_del_messages (SummaryView *summaryview);