X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fsummaryview.c;h=fa34635ede7bf2711abc46d48e9edbed05d700ab;hp=ed8fc8d8d92ec7befdaecb11dd6df0fb5a140598;hb=3d8e51875c27c3ab6454632e66acfbda72bbfb53;hpb=3b12bb90393f542b61f59e41b3dcf37db4ad358c diff --git a/src/summaryview.c b/src/summaryview.c index ed8fc8d8d..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))) { @@ -781,7 +900,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item, GTK_SIGNAL_FUNC (summary_drag_data_get), summaryview); - gtk_clist_thaw(GTK_CLIST(ctree)); + gtk_clist_thaw(GTK_CLIST(ctree)); /* sort before */ sort_mode = prefs_folder_item_get_sort_mode(item); @@ -936,9 +1055,9 @@ 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", sens); - menu_set_sensitive(ifactory, "/Forward as attachment", sens); - + 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); menu_set_sensitive(ifactory, "/Show all header", sens); @@ -955,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); @@ -979,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); @@ -1067,11 +1192,16 @@ void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum) node = summary_find_msg_by_msgnum(summaryview, msgnum); if (node) { + GTK_EVENTS_FLUSH(); + gtk_ctree_node_moveto(ctree, node, -1, 0.5, 0); + gtk_widget_grab_focus(GTK_WIDGET(ctree)); gtk_sctree_unselect_all(GTK_SCTREE(ctree)); gtk_sctree_select(GTK_SCTREE(ctree), node); - if (summaryview->displayed == node) - summaryview->displayed = NULL; - summary_display_msg(summaryview, node, FALSE); + if (summaryview->msg_is_toggled_on) { + if (summaryview->displayed == node) + summaryview->displayed = NULL; + summary_display_msg(summaryview, node, FALSE); + } } } @@ -1095,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; @@ -1174,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); @@ -1291,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++; @@ -1318,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++; @@ -1454,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; } @@ -1478,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, @@ -1558,17 +1691,29 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, msginfo = (MsgInfo *)mlist->data; parent = NULL; + summary_set_header(text, msginfo); + /* search parent node for threading */ if (msginfo->inreplyto && *msginfo->inreplyto) { parent = g_hash_table_lookup (msgid_table, msginfo->inreplyto); } - if (msginfo->subject) { + if (parent == NULL && msginfo->subject) { parent = subject_table_lookup (subject_table, msginfo->subject); } - - summary_set_header(text, msginfo); + 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, @@ -1576,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 */ @@ -1636,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) @@ -1766,7 +1917,7 @@ static void summary_set_header(gchar *text[], MsgInfo *msginfo) text[S_COL_MARK] = NULL; text[S_COL_UNREAD] = NULL; - text[S_COL_MIME] = NULL; + text[S_COL_MIME] = NULL; text[S_COL_NUMBER] = itos_buf(col_number, msginfo->msgnum); text[S_COL_SIZE] = to_human_readable(msginfo->size); #if 0 @@ -1788,14 +1939,13 @@ static void summary_set_header(gchar *text[], MsgInfo *msginfo) text[S_COL_FROM] = msginfo->fromname ? msginfo->fromname : _("(No From)"); if (prefs_common.swap_from && msginfo->from && msginfo->to && - cur_account && cur_account->address && !MSG_IS_NEWS(msginfo->flags)) { gchar *from; Xalloca(from, strlen(msginfo->from) + 1, return); strcpy(from, msginfo->from); extract_address(from); - if (!strcmp(from, cur_account->address)) { + if (account_find_mail_from_address(from)) { g_free(to); to = g_strconcat("-->", msginfo->to, NULL); text[S_COL_FROM] = to; @@ -1857,6 +2007,20 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row, } g_free(filename); + if (MSG_IS_NEW(msginfo->flags) && !MSG_IS_IGNORE_THREAD(msginfo->flags)) + summaryview->newmsgs--; + 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); + + CHANGE_FLAGS(msginfo); + + summary_set_row_marks(summaryview, row); + gtk_clist_thaw(GTK_CLIST(ctree)); + summary_status_show(summaryview); + } + if (new_window) { MessageView *msgview; @@ -1879,20 +2043,6 @@ static void summary_display_msg(SummaryView *summaryview, GtkCTreeNode *row, gtkut_ctree_node_move_if_on_the_edge(ctree, row); } - if (MSG_IS_NEW(msginfo->flags)) - summaryview->newmsgs--; - if (MSG_IS_UNREAD(msginfo->flags)) - summaryview->unread--; - if (MSG_IS_NEW(msginfo->flags) || MSG_IS_UNREAD(msginfo->flags)) { - MSG_UNSET_FLAGS(msginfo->flags, MSG_NEW | MSG_UNREAD); - - CHANGE_FLAGS(msginfo); - - summary_set_row_marks(summaryview, row); - gtk_clist_thaw(GTK_CLIST(ctree)); - summary_status_show(summaryview); - } - if (GTK_WIDGET_VISIBLE(summaryview->headerwin->window)) header_window_show(summaryview->headerwin, msginfo); @@ -2014,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)) { @@ -2114,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)) { @@ -2157,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++; @@ -2374,7 +2526,7 @@ void summary_move_to(SummaryView *summaryview) if (!summaryview->folder_item || summaryview->folder_item->folder->type == F_NEWS) return; - to_folder = foldersel_folder_sel(NULL); + to_folder = foldersel_folder_sel(NULL, NULL); summary_move_selected_to(summaryview, to_folder); } @@ -2437,7 +2589,7 @@ void summary_copy_to(SummaryView *summaryview) if (!summaryview->folder_item || summaryview->folder_item->folder->type == F_NEWS) return; - to_folder = foldersel_folder_sel(NULL); + to_folder = foldersel_folder_sel(NULL, NULL); summary_copy_selected_to(summaryview, to_folder); } @@ -2729,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); + } } } @@ -2800,7 +2959,7 @@ static void summary_thread_func(GtkCTree *ctree, GtkCTreeNode *node, gpointer data) { MsgInfo *msginfo; - GtkCTreeNode *parent; + GtkCTreeNode *parent = NULL; SummaryView * summaryview = (SummaryView *) data; GHashTable *msgid_table = summaryview->msgid_table; @@ -2808,9 +2967,11 @@ static void summary_thread_func(GtkCTree *ctree, GtkCTreeNode *node, msginfo = GTKUT_CTREE_NODE_GET_ROW_DATA(node); - if (!msginfo || !msginfo->inreplyto) return; + if (!msginfo) return; - parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto); + if(msginfo->inreplyto) { + parent = g_hash_table_lookup(msgid_table, msginfo->inreplyto); + } if (parent == NULL && msginfo->subject) { parent = subject_table_lookup(subject_table, msginfo->subject); } @@ -2985,6 +3146,13 @@ void summary_pass_key_press_event(SummaryView *summaryview, GdkEventKey *event) #define BREAK_ON_MODIFIER_KEY() \ if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0) break +#define KEY_PRESS_EVENT_STOP() \ + if (gtk_signal_n_emissions_by_name \ + (GTK_OBJECT(ctree), "key_press_event") > 0) { \ + gtk_signal_emit_stop_by_name(GTK_OBJECT(ctree), \ + "key_press_event"); \ + } + static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, SummaryView *summaryview) { @@ -2998,13 +3166,8 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, case GDK_g: /* Go */ case GDK_G: BREAK_ON_MODIFIER_KEY(); - - if (gtk_signal_n_emissions_by_name - (GTK_OBJECT(ctree), "key_press_event") > 0) - gtk_signal_emit_stop_by_name(GTK_OBJECT(ctree), - "key_press_event"); - - to_folder = foldersel_folder_sel(NULL); + KEY_PRESS_EVENT_STOP(); + to_folder = foldersel_folder_sel(NULL, NULL); if (to_folder) { debug_print(_("Go to %s\n"), to_folder->path); folderview_select(summaryview->folderview, to_folder); @@ -3012,17 +3175,20 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, return; case GDK_w: /* Write new message */ BREAK_ON_MODIFIER_KEY(); - if (summaryview->folder_item) - compose_new(summaryview->folder_item->folder->account); - else + if (summaryview->folder_item) { + PrefsAccount *ac; + ac = summaryview->folder_item->folder->account; + if (ac && ac->protocol == A_NNTP) + compose_new_with_recipient + (ac, summaryview->folder_item->path); + else + compose_new(ac); + } else compose_new(NULL); return; case GDK_D: /* Empty trash */ BREAK_ON_MODIFIER_KEY(); - if (gtk_signal_n_emissions_by_name - (GTK_OBJECT(ctree), "key_press_event") > 0) - gtk_signal_emit_stop_by_name(GTK_OBJECT(ctree), - "key_press_event"); + KEY_PRESS_EVENT_STOP(); main_window_empty_trash(summaryview->mainwin, TRUE); return; case GDK_Q: /* Quit */ @@ -3044,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) { @@ -3124,6 +3291,7 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, case GDK_x: /* Execute */ case GDK_X: BREAK_ON_MODIFIER_KEY(); + KEY_PRESS_EVENT_STOP(); summary_execute(summaryview); break; case GDK_a: /* Reply to the message */ @@ -3149,9 +3317,13 @@ static void summary_key_pressed(GtkWidget *widget, GdkEventKey *event, summary_save_as(summaryview); break; default: + break; } } +#undef BREAK_ON_MODIFIER_KEY +#undef KEY_PRESS_EVENT_STOP + static void summary_open_row(GtkSCTree *sctree, SummaryView *summaryview) { if (summaryview->folder_item->stype == F_DRAFT) @@ -3202,6 +3374,7 @@ static void summary_selected(GtkCTree *ctree, GtkCTreeNode *row, } break; default: + break; } if (summaryview->display_msg) @@ -3242,6 +3415,7 @@ static void summary_col_resized(GtkCList *clist, gint column, gint width, prefs_common.summary_col_subject = width; break; default: + break; } } @@ -3249,6 +3423,7 @@ static void summary_reply_cb(SummaryView *summaryview, guint action, GtkWidget *widget) { MsgInfo *msginfo; + GList *sel = GTK_CLIST(summaryview->ctree)->selection; msginfo = gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree), summaryview->selected); @@ -3291,10 +3466,21 @@ static void summary_reply_cb(SummaryView *summaryview, guint action, compose_reply(msginfo, FALSE, TRUE, FALSE); break; case COMPOSE_FORWARD: - compose_forward(NULL, msginfo, FALSE); - break; + if (!sel->next) { + compose_forward(NULL, msginfo, FALSE); + break; + } + /* if (sel->next) FALL THROUGH */ case COMPOSE_FORWARD_AS_ATTACH: - compose_forward(NULL, msginfo, TRUE); + { + GSList *msginfo_list = NULL; + for ( ; sel != NULL; sel = sel->next) + msginfo_list = g_slist_append(msginfo_list, + gtk_ctree_node_get_row_data(GTK_CTREE(summaryview->ctree), + GTK_CTREE_NODE(sel->data))); + compose_forward_multiple(NULL, msginfo_list); + g_slist_free(msginfo_list); + } break; default: g_warning("summary_reply_cb(): invalid action: %d\n", action); @@ -3399,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); @@ -3540,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) { @@ -3555,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); +} +