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:
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);