X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fsummaryview.c;h=fa34635ede7bf2711abc46d48e9edbed05d700ab;hp=fd849fa4436e1e227bf8234b17000645fca7bb72;hb=3d8e51875c27c3ab6454632e66acfbda72bbfb53;hpb=033e698a9bdbe7d662dcc357ebaa8877a19f43f2 diff --git a/src/summaryview.c b/src/summaryview.c index fd849fa44..fa34635ed 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -84,6 +84,7 @@ #include "pixmaps/replied.xpm" #include "pixmaps/forwarded.xpm" #include "pixmaps/clip.xpm" +#include "pixmaps/ignorethread.xpm" #define STATUSBAR_PUSH(mainwin, str) \ { \ @@ -120,6 +121,8 @@ static GdkPixmap *repliedxpm; static GdkBitmap *repliedxpmmask; static GdkPixmap *forwardedxpm; static GdkBitmap *forwardedxpmmask; +static GdkPixmap *ignorethreadxpm; +static GdkBitmap *ignorethreadxpmmask; static GdkPixmap *clipxpm; static GdkBitmap *clipxpmmask; @@ -204,6 +207,8 @@ static void summary_execute_delete (SummaryView *summaryview); static void summary_execute_delete_func (GtkCTree *ctree, GtkCTreeNode *node, gpointer data); +static void summary_ignore_thread(SummaryView *summaryview); +static void summary_unignore_thread(SummaryView *summaryview); /* thread functions */ static void summary_thread_func (GtkCTree *ctree, @@ -266,6 +271,8 @@ static void summary_from_clicked (GtkWidget *button, SummaryView *summaryview); static void summary_subject_clicked (GtkWidget *button, SummaryView *summaryview); +static void summary_mark_clicked (GtkWidget *button, + SummaryView *summaryview); static void summary_start_drag (GtkWidget *widget, int button, @@ -298,6 +305,9 @@ static gint summary_cmp_by_subject (GtkCList *clist, static gint summary_cmp_by_score (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2); +static gint summary_cmp_by_label (GtkCList *clist, + gconstpointer ptr1, + gconstpointer ptr2); GtkTargetEntry summary_drag_types[1] = { @@ -315,8 +325,21 @@ static GtkItemFactoryEntry summary_popup_entries[] = {N_("/_Mark/_Unmark"), NULL, summary_unmark, 0, NULL}, {N_("/_Mark/---"), NULL, NULL, 0, ""}, {N_("/_Mark/Mark as unr_ead"), NULL, summary_mark_as_unread, 0, NULL}, - {N_("/_Mark/Mark as rea_d"), - NULL, summary_mark_as_read, 0, NULL}, + {N_("/_Mark/Mark as rea_d"), NULL, summary_mark_as_read, 0, NULL}, + {N_("/_Mark/Ignore thread"), NULL, summary_ignore_thread, 0, NULL}, + {N_("/_Mark/Unignore thread"), NULL, summary_unignore_thread, 0, NULL}, + + {N_("/_Label"), NULL, NULL, 0, ""}, + {N_("/_Label/None"), NULL, summary_set_label, MSG_LABEL_NONE, NULL}, + {N_("/_Label/---"), NULL, NULL, 0, ""}, + {N_("/_Label/Orange"), NULL, summary_set_label, MSG_LABEL_ORANGE, NULL}, + {N_("/_Label/Red"), NULL, summary_set_label, MSG_LABEL_RED, NULL}, + {N_("/_Label/Pink"), NULL, summary_set_label, MSG_LABEL_PINK, NULL}, + {N_("/_Label/SkyBlue"), NULL, summary_set_label, MSG_LABEL_SKYBLUE, NULL}, + {N_("/_Label/Blue"), NULL, summary_set_label, MSG_LABEL_BLUE, NULL}, + {N_("/_Label/Green"), NULL, summary_set_label, MSG_LABEL_GREEN, NULL}, + {N_("/_Label/Brown"), NULL, summary_set_label, MSG_LABEL_BROWN, NULL}, + {N_("/---"), NULL, NULL, 0, ""}, {N_("/_Reply"), NULL, summary_reply_cb, COMPOSE_REPLY, NULL}, {N_("/Repl_y to sender"), NULL, summary_reply_cb, COMPOSE_REPLY_TO_SENDER, NULL}, @@ -337,6 +360,95 @@ static GtkItemFactoryEntry summary_popup_entries[] = {N_("/Select _all"), NULL, summary_select_all, 0, NULL} }; +void summary_set_label_color(GtkCTree *ctree, GtkCTreeNode *node, + guint labelcolor) +{ + GdkColor color; + GtkStyle *style, *prev_style, *ctree_style; + MsgInfo *msginfo; + + ctree_style = gtk_widget_get_style(GTK_WIDGET(ctree)); + + prev_style = gtk_ctree_node_get_row_style(ctree, node); + + if (!prev_style) + prev_style = ctree_style; + + style = gtk_style_copy(prev_style); + + switch (labelcolor) { + case MSG_LABEL_ORANGE: + color.red = 0xffff; + color.green = (0x99<<8); + color.blue = 0x0; + break; + case MSG_LABEL_RED: + color.red = 0xffff; + color.green = color.blue = 0x0; + break; + case MSG_LABEL_PINK: + color.red = 0xffff; + color.green = (0x66<<8); + color.blue = 0xffff; + break; + case MSG_LABEL_SKYBLUE: + color.red = 0x0; + color.green = (0xcc<<8); + color.blue = 0xffff; + break; + case MSG_LABEL_BLUE: + color.red = 0x0; + color.green = 0x0; + color.blue = 0xffff; + break; + case MSG_LABEL_GREEN: + color.red = 0x0; + color.green = (0x99<<8); + color.blue = 0x0; + break; + case MSG_LABEL_BROWN: + color.red = (0x66<<8); + color.green = (0x33<<8); + color.blue = (0x33<<8); + break; + case MSG_LABEL_NONE: + default: + labelcolor = MSG_LABEL_NONE; + color.red = ctree_style->fg[GTK_STATE_NORMAL].red; + color.green = ctree_style->fg[GTK_STATE_NORMAL].green; + color.blue = ctree_style->fg[GTK_STATE_NORMAL].blue; + style->fg[GTK_STATE_NORMAL] = color; + + color.red = ctree_style->fg[GTK_STATE_SELECTED].red; + color.green = ctree_style->fg[GTK_STATE_SELECTED].green; + color.blue = ctree_style->fg[GTK_STATE_SELECTED].blue; + style->fg[GTK_STATE_SELECTED] = color; + gtk_ctree_node_set_row_style(ctree, node, style); + break; + } + + msginfo = gtk_ctree_node_get_row_data(ctree, node); + + MSG_UNSET_FLAGS(msginfo->flags, MSG_LABEL); + MSG_SET_FLAGS(msginfo->flags, labelcolor); + + if ( style ) { + style->fg[GTK_STATE_NORMAL] = color; + style->fg[GTK_STATE_SELECTED] = color; + gtk_ctree_node_set_row_style(ctree, node, style); + } +} + +void summary_set_label(SummaryView *summaryview, guint labelcolor, GtkWidget *widget) +{ + GtkCTree *ctree = GTK_CTREE(summaryview->ctree); + GtkCList *clist = GTK_CLIST(summaryview->ctree); + GList *cur; + + for (cur = clist->selection; cur != NULL; cur = cur->next) + summary_set_label_color(ctree, GTK_CTREE_NODE(cur->data), labelcolor); +} + SummaryView *summary_create(void) { SummaryView *summaryview; @@ -467,6 +579,11 @@ SummaryView *summary_create(void) "clicked", GTK_SIGNAL_FUNC(summary_subject_clicked), summaryview); + gtk_signal_connect + (GTK_OBJECT(GTK_CLIST(ctree)->column[S_COL_MARK].button), + "clicked", + GTK_SIGNAL_FUNC(summary_mark_clicked), + summaryview); /* create status label */ hbox = gtk_hbox_new(FALSE, 0); @@ -548,6 +665,8 @@ void summary_init(SummaryView *summaryview) replied_xpm); PIXMAP_CREATE(summaryview->ctree, forwardedxpm, forwardedxpmmask, forwarded_xpm); + PIXMAP_CREATE(summaryview->ctree, ignorethreadxpm, ignorethreadxpmmask, + ignorethread_xpm); PIXMAP_CREATE(summaryview->ctree, clipxpm, clipxpmmask, clip_xpm); PIXMAP_CREATE(summaryview->hbox, folderxpm, folderxpmmask, DIRECTORY_OPEN_XPM); @@ -586,7 +705,7 @@ GtkCTreeNode * summary_find_next_important_score(SummaryView *summaryview, GtkCTreeNode *best_node = NULL; if (current_node) - //node = current_node; + /*node = current_node;*/ node = GTK_CTREE_NODE_NEXT(current_node); else node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); @@ -617,7 +736,7 @@ GtkCTreeNode * summary_find_prev_important_score(SummaryView *summaryview, GtkCTreeNode *best_node = NULL; if (current_node) - //node = current_node; + /*node = current_node;*/ node = GTK_CTREE_NODE_PREV(current_node); else node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); @@ -687,7 +806,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item, messageview_clear(summaryview->messageview); buf = NULL; - if (!item || !item->path || !item->parent || + if (!item || !item->path || !item->parent || item->no_select || (item->folder->type == F_MH && ((buf = folder_item_get_path(item)) == NULL || change_dir(buf) < 0))) { @@ -936,9 +1055,8 @@ static void summary_set_menu_sensitive(SummaryView *summaryview) menu_set_sensitive(ifactory, "/Reply", sens); menu_set_sensitive(ifactory, "/Reply to sender", sens); menu_set_sensitive(ifactory, "/Reply to all", sens); - - menu_set_sensitive(ifactory, "/Forward", TRUE); - menu_set_sensitive(ifactory, "/Forward as attachment", TRUE); + menu_set_sensitive(ifactory, "/Forward", TRUE); + menu_set_sensitive(ifactory, "/Forward as attachment", TRUE); menu_set_sensitive(ifactory, "/Open in new window", sens); menu_set_sensitive(ifactory, "/View source", sens); @@ -956,8 +1074,12 @@ static void summary_set_menu_sensitive(SummaryView *summaryview) menu_set_sensitive(ifactory, "/Mark/Mark", TRUE); menu_set_sensitive(ifactory, "/Mark/Unmark", TRUE); - menu_set_sensitive(ifactory, "/Mark/Mark as unread", TRUE); - menu_set_sensitive(ifactory, "/Mark/Mark as read", TRUE); + menu_set_sensitive(ifactory, "/Mark/Mark as unread", TRUE); + menu_set_sensitive(ifactory, "/Mark/Mark as read", TRUE); + menu_set_sensitive(ifactory, "/Mark/Ignore thread", TRUE); + menu_set_sensitive(ifactory, "/Mark/Unignore thread", TRUE); + + menu_set_sensitive(ifactory, "/Label", TRUE); menu_set_sensitive(ifactory, "/Select all", TRUE); @@ -980,6 +1102,8 @@ void summary_select_next_unread(SummaryView *summaryview) if (node) { gtk_sctree_unselect_all(GTK_SCTREE(ctree)); gtk_sctree_select(GTK_SCTREE(ctree), node); + gtk_ctree_node_moveto(ctree, node, -1, 0.5, 0.0); + if (summaryview->displayed == node) summaryview->displayed = NULL; summary_display_msg(summaryview, node, FALSE); @@ -1101,13 +1225,13 @@ static GtkCTreeNode *summary_find_next_unread_msg(SummaryView *summaryview, if (current_node) node = current_node; - //node = GTK_CTREE_NODE_NEXT(current_node); + /*node = GTK_CTREE_NODE_NEXT(current_node);*/ else node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list); for (; node != NULL; node = GTK_CTREE_NODE_NEXT(node)) { msginfo = gtk_ctree_node_get_row_data(ctree, node); - if (MSG_IS_UNREAD(msginfo->flags)) break; + if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) break; } return node; @@ -1180,7 +1304,7 @@ static GtkCTreeNode *summary_find_prev_unread_msg(SummaryView *summaryview, if (current_node) node = current_node; - //node = GTK_CTREE_NODE_PREV(current_node); + /*node = GTK_CTREE_NODE_PREV(current_node);*/ else node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list_end); @@ -1297,9 +1421,9 @@ static void summary_set_marks_func(GtkCTree *ctree, GtkCTreeNode *node, msginfo = gtk_ctree_node_get_row_data(ctree, node); - if (MSG_IS_NEW(msginfo->flags)) + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->newmsgs++; - if (MSG_IS_UNREAD(msginfo->flags)) + if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->unread++; if (MSG_IS_DELETED(msginfo->flags)) summaryview->deleted++; @@ -1324,9 +1448,9 @@ static void summary_update_status(SummaryView *summaryview) node != NULL; node = GTK_CTREE_NODE_NEXT(node)) { msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node); - if (MSG_IS_NEW(msginfo->flags)) + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->newmsgs++; - if (MSG_IS_UNREAD(msginfo->flags)) + if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->unread++; if (MSG_IS_DELETED(msginfo->flags)) summaryview->deleted++; @@ -1460,6 +1584,9 @@ void summary_sort(SummaryView *summaryview, SummarySortType type) case SORT_BY_SCORE: cmp_func = (GtkCListCompareFunc)summary_cmp_by_score; break; + case SORT_BY_LABEL: + cmp_func = (GtkCListCompareFunc)summary_cmp_by_label; + break; default: return; } @@ -1484,7 +1611,7 @@ void summary_sort(SummaryView *summaryview, SummarySortType type) gtk_ctree_sort_node(ctree, NULL); gtk_ctree_node_moveto(ctree, summaryview->selected, -1, 0.5, 0); - //gtkut_ctree_set_focus_row(ctree, summaryview->selected); + /*gtkut_ctree_set_focus_row(ctree, summaryview->selected);*/ prefs_folder_item_set_config(summaryview->folder_item, summaryview->sort_type, @@ -1575,6 +1702,18 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, parent = subject_table_lookup (subject_table, msginfo->subject); } + if(parent) { + parentinfo = gtk_ctree_node_get_row_data(ctree, parent); + if(parentinfo && MSG_IS_IGNORE_THREAD(parentinfo->flags)) { +/* + if (MSG_IS_NEW(msginfo->flags)) + summaryview->newmsgs--; + if (MSG_IS_UNREAD(msginfo->flags)) + summaryview->unread--; +*/ + MSG_SET_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + } + } node = gtk_ctree_insert_node (ctree, parent, NULL, text, 2, @@ -1582,6 +1721,9 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, GTKUT_CTREE_NODE_SET_ROW_DATA(node, msginfo); summary_set_marks_func(ctree, node, summaryview); + + if ( MSG_GET_LABEL(msginfo->flags) ) + summary_set_label_color(ctree, node, (msginfo->flags & MSG_LABEL)); /* preserve previous node if the message is duplicated */ @@ -1642,6 +1784,9 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, GTKUT_CTREE_NODE_SET_ROW_DATA(node, msginfo); summary_set_marks_func(ctree, node, summaryview); + if ( MSG_GET_LABEL(msginfo->flags) ) + summary_set_label_color(ctree, node, (msginfo->flags & MSG_LABEL)); + if (msginfo->msgid && *msginfo->msgid && g_hash_table_lookup(msgid_table, msginfo->msgid) == NULL) @@ -1862,9 +2007,9 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row, } g_free(filename); - if (MSG_IS_NEW(msginfo->flags)) + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->newmsgs--; - if (MSG_IS_UNREAD(msginfo->flags)) + if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->unread--; if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD); @@ -2019,7 +2164,10 @@ static void summary_set_row_marks(SummaryView *summaryview, GtkCTreeNode *row) gtk_ctree_node_set_foreground(ctree, row, &summaryview->color_normal); /* set new/unread column */ - if (MSG_IS_NEW(flags)) { + if (MSG_IS_IGNORE_THREAD(flags)) { + gtk_ctree_node_set_pixmap(ctree, row, S_COL_UNREAD, + ignorethreadxpm, ignorethreadxpmmask); + } else if (MSG_IS_NEW(flags)) { gtk_ctree_node_set_pixmap(ctree, row, S_COL_UNREAD, newxpm, newxpmmask); } else if (MSG_IS_UNREAD(flags)) { @@ -2119,9 +2267,9 @@ static void summary_mark_row_as_read(SummaryView *summaryview, MsgInfo *msginfo; msginfo = gtk_ctree_node_get_row_data(ctree, row); - if (MSG_IS_NEW(msginfo->flags)) + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->newmsgs--; - if (MSG_IS_UNREAD(msginfo->flags)) + if (MSG_IS_UNREAD(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) summaryview->unread--; if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { @@ -2162,7 +2310,6 @@ static void summary_mark_row_as_unread(SummaryView *summaryview, MSG_UNSET_FLAGS(msginfo->flags, MSG_REPLIED | MSG_FORWARDED); if (!MSG_IS_UNREAD(msginfo->flags)) { MSG_SET_FLAGS(msginfo->flags, MSG_UNREAD); - gtk_ctree_node_set_pixmap(ctree, row, S_COL_UNREAD, unreadxpm, unreadxpmmask); summaryview->unread++; @@ -2734,6 +2881,13 @@ static void summary_execute_delete_func(GtkCTree *ctree, GtkCTreeNode *node, msginfo->msgid)) g_hash_table_remove(summaryview->msgid_table, msginfo->msgid); + + if (msginfo->subject && + node == subject_table_lookup(summaryview->subject_table, + msginfo->subject)) { + gchar *s = msginfo->subject + (g_strncasecmp(msginfo->subject, "Re: ", 4) == 0 ? 4 : 0); + g_hash_table_remove(summaryview->subject_table, s); + } } } @@ -3056,6 +3210,7 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, gtk_widget_grab_focus(summaryview->folderview->ctree); return; default: + break; } if (!summaryview->selected) { @@ -3162,6 +3317,7 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, summary_save_as(summaryview); break; default: + break; } } @@ -3218,6 +3374,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row, } break; default: + break; } if (summaryview->display_msg) @@ -3258,6 +3415,7 @@ static void summary_col_resized(GtkCList *clist, gint column, gint width, prefs_common.summary_col_subject = width; break; default: + break; } } @@ -3427,6 +3585,12 @@ static void summary_subject_clicked(GtkWidget *button, summary_sort(summaryview, SORT_BY_SUBJECT); } +static void summary_mark_clicked(GtkWidget *button, + SummaryView *summaryview) +{ + summary_sort(summaryview, SORT_BY_LABEL); +} + void summary_change_display_item(SummaryView *summaryview) { GtkCList *clist = GTK_CLIST(summaryview->ctree); @@ -3568,6 +3732,15 @@ static gint summary_cmp_by_subject(GtkCList *clist, return strcasecmp(msginfo1->subject, msginfo2->subject); } +static gint summary_cmp_by_label(GtkCList *clist, + gconstpointer ptr1, gconstpointer ptr2) +{ + MsgInfo *msginfo1 = ((GtkCListRow *)ptr1)->data; + MsgInfo *msginfo2 = ((GtkCListRow *)ptr2)->data; + + return MSG_GET_LABEL(msginfo1->flags) - MSG_GET_LABEL(msginfo2->flags); +} + static gint summary_cmp_by_score(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) { @@ -3583,3 +3756,66 @@ static gint summary_cmp_by_score(GtkCList *clist, else return summary_cmp_by_date(clist, ptr1, ptr2); } + +static void summary_ignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data) +{ + SummaryView *summaryview = (SummaryView *) data; + MsgInfo *msginfo; + + msginfo = gtk_ctree_node_get_row_data(ctree, row); + if (MSG_IS_NEW(msginfo->flags)) + summaryview->newmsgs--; + if (MSG_IS_UNREAD(msginfo->flags)) + summaryview->unread--; + MSG_SET_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + + CHANGE_FLAGS(msginfo); + + summary_set_row_marks(summaryview, row); + debug_print(_("Message %d is marked as ignore thread\n"), + msginfo->msgnum); +} + +static void summary_ignore_thread(SummaryView *summaryview) +{ + GtkCTree *ctree = GTK_CTREE(summaryview->ctree); + GList *cur; + + for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next) { + gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), GTK_CTREE_FUNC(summary_ignore_thread_func), summaryview); + } + + summary_status_show(summaryview); +} + +static void summary_unignore_thread_func(GtkCTree *ctree, GtkCTreeNode *row, gpointer data) +{ + SummaryView *summaryview = (SummaryView *) data; + MsgInfo *msginfo; + + msginfo = gtk_ctree_node_get_row_data(ctree, row); + if (MSG_IS_NEW(msginfo->flags)) + summaryview->newmsgs++; + if (MSG_IS_UNREAD(msginfo->flags)) + summaryview->unread++; + MSG_UNSET_FLAGS(msginfo->flags, MSG_IGNORE_THREAD); + + CHANGE_FLAGS(msginfo); + + summary_set_row_marks(summaryview, row); + debug_print(_("Message %d is marked as unignore thread\n"), + msginfo->msgnum); +} + +static void summary_unignore_thread(SummaryView *summaryview) +{ + GtkCTree *ctree = GTK_CTREE(summaryview->ctree); + GList *cur; + + for (cur = GTK_CLIST(ctree)->selection; cur != NULL; cur = cur->next) { + gtk_ctree_pre_recursive(ctree, GTK_CTREE_NODE(cur->data), GTK_CTREE_FUNC(summary_unignore_thread_func), summaryview); + } + + summary_status_show(summaryview); +} +