rework folderview styles
[claws.git] / src / folderview.c
index 71391ef01b184564fcf1d7c6d4ab212ad69ebdab..31bc048d7f350c2f95aeb862b0045b578590741e 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2013 Hiroyuki Yamamoto and the Claws Mail team
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2019 the Claws Mail team and Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * 
  */
 
 #include "defs.h"
 
 static GList *folderview_list = NULL;
 
-static GtkStyle *normal_style;
-static GtkStyle *normal_color_style;
 static GtkStyle *bold_style;
-static GtkStyle *bold_color_style;
-static GtkStyle *bold_tgtfold_style;
 
 static GdkPixbuf *inboxxpm;
 static GdkPixbuf *inboxhrmxpm;
@@ -238,6 +233,11 @@ static gboolean folderview_update_item_claws        (gpointer          source,
 static void folderview_processing_cb(GtkAction *action, gpointer data);
 static void folderview_set_sens_and_popup_menu(FolderView *folderview, gint row, 
                                GdkEventButton *event);
+static void folderview_header_set_displayed_columns_cb(GtkAction *gaction,
+               gpointer data);
+static gboolean folderview_header_button_pressed(GtkWidget *widget,
+               GdkEvent *_event,
+               gpointer user_data);
 
 GHashTable *folderview_popups;
 
@@ -258,6 +258,12 @@ static GtkActionEntry folderview_common_popup_entries[] =
        
 };
 
+static GtkActionEntry folderview_header_popup_entries[] =
+{
+       {"FolderViewHeaderPopup",                     NULL, "FolderViewHeaderPopup", NULL, NULL, NULL },
+       {"FolderViewHeaderPopup/SetDisplayedColumns", NULL, N_("Set Displayed columns"), NULL, NULL, G_CALLBACK(folderview_header_set_displayed_columns_cb) }
+};
+
 GtkTargetEntry folderview_drag_types[] =
 {
        {"claws-mail/internal", GTK_TARGET_SAME_APP, TARGET_DUMMY},
@@ -462,7 +468,6 @@ static GtkWidget *folderview_ctree_create(FolderView *folderview)
        gtk_cmclist_set_column_justification(GTK_CMCLIST(ctree), 
                                           col_pos[F_COL_TOTAL],
                                           GTK_JUSTIFY_RIGHT);
-       gtk_cmctree_set_line_style(GTK_CMCTREE(ctree), GTK_CMCTREE_LINES_NONE);
        gtk_cmctree_set_expander_style(GTK_CMCTREE(ctree),
                             GTK_CMCTREE_EXPANDER_TRIANGLE);
 
@@ -474,11 +479,16 @@ static GtkWidget *folderview_ctree_create(FolderView *folderview)
 
        /* don't let title buttons take key focus */
        for (i = 0; i < N_FOLDER_COLS; i++) {
-               gtkut_widget_set_can_focus(GTK_CMCLIST(ctree)->column[i].button, FALSE);
+               gtk_widget_set_can_focus(GTK_CMCLIST(ctree)->column[i].button, FALSE);
                gtk_cmclist_set_column_width(GTK_CMCLIST(ctree), col_pos[i],
                                   prefs_common.folder_col_size[i]);
                gtk_cmclist_set_column_visibility
                        (GTK_CMCLIST(ctree), i, col_state[i].visible);
+
+               g_signal_connect(G_OBJECT(GTK_CMCLIST(ctree)->column[i].button),
+                                       "button-press-event",
+                                       G_CALLBACK(folderview_header_button_pressed),
+                                       folderview);
        }
 
        g_signal_connect(G_OBJECT(ctree), "key_press_event",
@@ -588,7 +598,7 @@ void folderview_set_column_order(FolderView *folderview)
        folderview_select(folderview,item);
 }
 
-FolderView *folderview_create(void)
+FolderView *folderview_create(MainWindow *mainwin)
 {
        FolderView *folderview;
        GtkWidget *scrolledwin;
@@ -613,6 +623,18 @@ FolderView *folderview_create(void)
        folderview->popups = g_hash_table_new(g_str_hash, g_str_equal);
        g_hash_table_foreach(folderview_popups, create_action_groups, folderview);
 
+       gtk_action_group_add_actions(mainwin->action_group,
+                       folderview_header_popup_entries,
+                       G_N_ELEMENTS(folderview_header_popup_entries),
+                       (gpointer)folderview);
+
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus", "FolderViewHeaderPopup", "FolderViewHeaderPopup", GTK_UI_MANAGER_MENU)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/FolderViewHeaderPopup", "SetDisplayedColumns", "FolderViewHeaderPopup/SetDisplayedColumns", GTK_UI_MANAGER_MENUITEM)
+
+       folderview->headerpopupmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
+                               gtk_ui_manager_get_widget(mainwin->ui_manager,
+                                       "/Menus/FolderViewHeaderPopup") ));
+
        folderview->ctree        = ctree;
 
        folderview->folder_update_callback_id =
@@ -633,12 +655,40 @@ FolderView *folderview_create(void)
        return folderview;
 }
 
-void folderview_init(FolderView *folderview)
+static void folderview_set_fonts(FolderView *folderview)
 {
+       PangoFontDescription *font_desc;
        GtkWidget *ctree = folderview->ctree;
-       GdkColor gdk_color;
-       PangoFontDescription *normal_font;
 
+       font_desc = pango_font_description_from_string(NORMAL_FONT);
+       if (font_desc) {
+               gtk_widget_modify_font(ctree, font_desc);
+               pango_font_description_free(font_desc);
+       }
+
+       if (!bold_style) {
+               bold_style = gtk_style_copy(gtk_widget_get_style(ctree));
+
+               if (prefs_common.derive_from_normal_font || !BOLD_FONT) {
+                       font_desc = pango_font_description_from_string(NORMAL_FONT);
+                       if (font_desc) {
+                               pango_font_description_free(bold_style->font_desc);
+                               bold_style->font_desc = font_desc;
+                       }
+                       pango_font_description_set_weight
+                               (bold_style->font_desc, PANGO_WEIGHT_BOLD);
+               } else {
+                       font_desc = pango_font_description_from_string(BOLD_FONT);
+                       if (font_desc) {
+                               pango_font_description_free(bold_style->font_desc);
+                               bold_style->font_desc = font_desc;
+                       }
+               }
+       }
+}
+
+void folderview_init(FolderView *folderview)
+{
        stock_pixbuf_gdk(STOCK_PIXMAP_INBOX_CLOSE, &inboxxpm);
        stock_pixbuf_gdk(STOCK_PIXMAP_INBOX_CLOSE_HRM, &inboxhrmxpm);
        stock_pixbuf_gdk(STOCK_PIXMAP_INBOX_OPEN, &inboxopenxpm);
@@ -691,56 +741,7 @@ void folderview_init(FolderView *folderview)
        stock_pixbuf_gdk(STOCK_PIXMAP_DIR_SUBS_CLOSE_MARK, &m_foldersubsxpm);
        stock_pixbuf_gdk(STOCK_PIXMAP_DIR_NOSELECT_CLOSE_MARK, &m_foldernoselectxpm);
 
-       normal_font = pango_font_description_from_string(NORMAL_FONT);
-       if (normal_font) {
-               gtk_widget_modify_font(ctree, normal_font);
-               pango_font_description_free(normal_font);
-       }
-       gtk_cmclist_set_row_height(GTK_CMCLIST(ctree), 0);
-
-       if (!normal_style) {
-               PangoFontDescription *font_desc;
-               normal_style = gtk_style_copy(gtk_widget_get_style(ctree));
-               font_desc = pango_font_description_from_string(NORMAL_FONT);
-               if (font_desc) {
-                       if (normal_style->font_desc)
-                               pango_font_description_free
-                                       (normal_style->font_desc);
-                       normal_style->font_desc = font_desc;
-               }
-               gtkut_convert_int_to_gdk_color(prefs_common.color_new, &gdk_color);
-               normal_color_style = gtk_style_copy(normal_style);
-               normal_color_style->fg[GTK_STATE_NORMAL] = gdk_color;
-       }
-
-       if (!bold_style) {
-               gtkut_convert_int_to_gdk_color(prefs_common.color_new, &gdk_color);
-               bold_style = gtk_style_copy(gtk_widget_get_style(ctree));
-               if (prefs_common.derive_from_normal_font || !BOLD_FONT) {
-                       PangoFontDescription *font_desc;
-                       font_desc = pango_font_description_from_string(NORMAL_FONT);
-                       if (font_desc) {
-                               pango_font_description_free(bold_style->font_desc);
-                               bold_style->font_desc = font_desc;
-                       }
-                       pango_font_description_set_weight
-                               (bold_style->font_desc, PANGO_WEIGHT_BOLD);
-               } else {
-                       PangoFontDescription *font_desc;
-                       font_desc = pango_font_description_from_string(BOLD_FONT);
-                       if (font_desc) {
-                               if (bold_style->font_desc)
-                                       pango_font_description_free
-                                               (bold_style->font_desc);
-                               bold_style->font_desc = font_desc;
-                       }
-               }
-               bold_color_style = gtk_style_copy(bold_style);
-               bold_color_style->fg[GTK_STATE_NORMAL] = gdk_color;
-
-               bold_tgtfold_style = gtk_style_copy(bold_style);
-               bold_tgtfold_style->fg[GTK_STATE_NORMAL] = folderview->color_op;
-       }
+       folderview_set_fonts(folderview);
 }
 
 static gboolean folderview_defer_set(gpointer data)
@@ -876,11 +877,10 @@ static void mark_all_read_unread_handler(GtkAction *action, gpointer data,
                                                        _("Do you really want to mark all mails in this "
                                                        "folder as unread?");
        }
-       if (folderview->summaryview->folder_item != item &&
-           prefs_common.ask_mark_all_read) {
+       if (prefs_common.ask_mark_all_read) {
                val = alertpanel_full(title, message,
-                         GTK_STOCK_NO, GTK_STOCK_YES, NULL,
-                         TRUE, NULL, ALERT_QUESTION, G_ALERTDEFAULT);
+                         GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST,
+                         TRUE, NULL, ALERT_QUESTION);
 
                if ((val & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
                        return;
@@ -896,14 +896,14 @@ static void mark_all_read_unread_handler(GtkAction *action, gpointer data,
                
        if (read) {
                if (recursive)
-                       folderutils_mark_all_read_recursive(item);
+                       folderutils_mark_all_read_recursive(item, TRUE);
                else
-                       folderutils_mark_all_read(item);
+                       folderutils_mark_all_read(item, TRUE);
        } else {
                if (recursive)
-                       folderutils_mark_all_unread_recursive(item);
+                       folderutils_mark_all_read_recursive(item, FALSE);
                else
-                       folderutils_mark_all_unread(item);
+                       folderutils_mark_all_read(item, FALSE);
        }
        if (folderview->summaryview->folder_item != item && !recursive)
                summary_unlock(folderview->summaryview);
@@ -933,7 +933,7 @@ static void folderview_select_node(FolderView *folderview, GtkCMCTreeNode *node)
            folderview->summaryview->folder_item->total_msgs > 0) ||
             prefs_common.layout_mode == SMALL_LAYOUT)
                summary_select_node(folderview->summaryview,
-                                   folderview->summaryview->selected, -1);
+                                   folderview->summaryview->selected, OPEN_SELECTED_ON_FOLDER_OPEN);
        else
                gtk_widget_grab_focus(folderview->ctree);
 }
@@ -996,16 +996,16 @@ void folderview_select_next_with_flag(FolderView *folderview,
        
        switch (flag) {
        case MSG_UNREAD:
-               prefs_common.summary_select_prio[0] = ACTION_UNREAD;
+               prefs_common.summary_select_prio[0] = ACTION_OLDEST_UNREAD;
                break;
        case MSG_NEW:
-               prefs_common.summary_select_prio[0] = ACTION_NEW;
+               prefs_common.summary_select_prio[0] = ACTION_OLDEST_NEW;
                break;
        case MSG_MARKED:
-               prefs_common.summary_select_prio[0] = ACTION_MARKED;
+               prefs_common.summary_select_prio[0] = ACTION_OLDEST_MARKED;
                break;
        default:
-               prefs_common.summary_select_prio[0] = ACTION_FIRST_LIST;
+               prefs_common.summary_select_prio[0] = ACTION_OLDEST_LIST;
                break;
        }
 
@@ -1101,8 +1101,8 @@ void folderview_rescan_tree(Folder *folder, gboolean rebuild)
            alertpanel_full(_("Rebuild folder tree"), 
                         _("Rebuilding the folder tree will remove "
                           "local caches. Do you want to continue?"),
-                        GTK_STOCK_NO, GTK_STOCK_YES, NULL, FALSE,
-                        NULL, ALERT_WARNING, G_ALERTDEFAULT
+                        GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST,
+                                                FALSE, NULL, ALERT_WARNING
                != G_ALERTALTERNATE) {
                return;
        }
@@ -1509,8 +1509,7 @@ static gboolean folderview_have_marked_children(FolderView *folderview,
 static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node)
 {
        GtkCMCTree *ctree = GTK_CMCTREE(folderview->ctree);
-       GtkStyle *style = NULL;
-       GtkStyle *color_style = NULL;
+       GtkStyle *style = NULL, *prev_style;
        FolderItem *item;
        GdkPixbuf *xpm, *openxpm;
        static GdkPixbuf *searchicon;
@@ -1522,6 +1521,7 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node)
        gboolean use_bold, use_color;
        gint *col_pos = folderview->col_pos;
        SpecialFolderItemType stype;
+       GdkColor gdk_color;
        
        item = gtk_cmctree_node_get_row_data(ctree, node);
        cm_return_if_fail(item != NULL);
@@ -1726,38 +1726,37 @@ static void folderview_update_node(FolderView *folderview, GtkCMCTreeNode *node)
        gtk_cmctree_node_set_foreground(ctree, node, NULL);
 
        if (use_bold) {
-               GdkColor gdk_color;
-
-               if (item->prefs->color > 0 && !use_color) {
+               style = bold_style;
+               if (use_color) {
+                       gtk_cmctree_node_set_foreground(ctree, node, &folderview->color_new);
+               } else if (item->op_count > 0) {
+                       gtk_cmctree_node_set_foreground(ctree, node, &folderview->color_op);
+               } else if (item->prefs->color != 0) {
                        gtkut_convert_int_to_gdk_color(item->prefs->color, &gdk_color);
-                       color_style = gtk_style_copy(bold_style);
-                       color_style->fg[GTK_STATE_NORMAL] = gdk_color;
-                       style = color_style;
-               } else if (use_color) {
-                       style = bold_color_style;
-               } else
-                       style = bold_style;
-               if (item->op_count > 0) {
-                       style = bold_tgtfold_style;
+                       gtk_cmctree_node_set_foreground(ctree, node, &gdk_color);
                }
        } else if (use_color) {
-               style = normal_color_style;
-               gtk_cmctree_node_set_foreground(ctree, node,
-                                             &folderview->color_new);
+               gtk_cmctree_node_set_foreground(ctree, node, &folderview->color_new);
        } else if (item->op_count > 0) {
-               style = bold_tgtfold_style;
-       } else if (item->prefs->color > 0) {
-               GdkColor gdk_color;
+               gtk_cmctree_node_set_foreground(ctree, node, &folderview->color_op);
+       } else if (item->prefs->color != 0) {
                gtkut_convert_int_to_gdk_color(item->prefs->color, &gdk_color);
-               color_style = gtk_style_copy(normal_style);
-               color_style->fg[GTK_STATE_NORMAL] = gdk_color;
-               style = color_style;
-       } else {
-               style = normal_style;
+               gtk_cmctree_node_set_foreground(ctree, node, &gdk_color);
        }
 
        gtk_cmctree_node_set_row_style(ctree, node, style);
 
+       prev_style = gtk_cmctree_node_get_row_style(ctree, node);
+       if (prev_style) {
+               GtkStyle *ctree_style = gtk_widget_get_style(GTK_WIDGET(ctree));
+
+               style = gtk_style_copy(prev_style);
+               style->text[GTK_STATE_NORMAL] = ctree_style->text[GTK_STATE_NORMAL];
+               style->text[GTK_STATE_SELECTED] = ctree_style->text[GTK_STATE_SELECTED];
+               gtk_cmctree_node_set_row_style(ctree, node, style);
+               g_object_unref(style);
+       }
+
        if ((node = gtkut_ctree_find_collapsed_parent(ctree, node)) != NULL)
                folderview_update_node(folderview, node);
 }
@@ -2026,6 +2025,7 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        gint prev_row = -1, row = -1, column = -1;
 
        if (!event) return FALSE;
+       if (event->window != clist->clist_window) return FALSE;
 
        if (event->button == 1 || event->button == 2) {
                if (!gtk_sctree_is_hot_spot (GTK_SCTREE(clist), event->x, event->y))
@@ -2154,10 +2154,13 @@ static gboolean folderview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                break;
        case GDK_KEY_Left:
                if (folderview->selected) {
-                       if (GTK_CMCTREE_ROW(folderview->selected)->expanded) {
+                       /* If the folder is expanded and can be collapsed, do that... */
+                       if (GTK_CMCTREE_ROW(folderview->selected)->expanded &&
+                                       GTK_CMCTREE_ROW(folderview->selected)->children != NULL) {
                                gtk_cmctree_collapse(GTK_CMCTREE(folderview->ctree),
                                                folderview->selected);
                        } else {
+                               /* ...otherwise, move cursor to its parent node. */
                                if ((item = gtk_cmctree_node_get_row_data(GTK_CMCTREE(folderview->ctree),
                                                folderview->selected))) {
                                        if ((node = gtk_cmctree_find_by_row_data(GTK_CMCTREE(folderview->ctree),
@@ -2295,8 +2298,8 @@ static void folderview_selected(GtkCMCTree *ctree, GtkCMCTreeNode *row,
        can_select = FALSE;
 
        /* Save cache for old folder */
-       /* We don't want to lose all caches if sylpheed crashed */
-       /* resets folderview->opened to NULL */
+       /* We don't want to lose all caches if app crashes */
+       /* Resets folderview->opened to NULL */
        folderview_close_opened(folderview, FALSE);
        
        /* CLAWS: set compose button type: news folder items 
@@ -2449,8 +2452,6 @@ static void folderview_create_folder_node(FolderView *folderview, FolderItem *it
                                     FALSE, FALSE);
        gtk_cmctree_expand(ctree, parent_node);
        gtk_cmctree_node_set_row_data(ctree, node, item);
-       if (normal_style)
-               gtk_cmctree_node_set_row_style(ctree, node, normal_style);
        folderview_sort_folders(folderview, parent_node, item->folder);
 
        hookdata.item = item;
@@ -2484,7 +2485,8 @@ static void folderview_empty_trash_cb(GtkAction *action, gpointer data)
        if (prefs_common.ask_on_clean) {
                if (alertpanel(_("Empty trash"),
                               _("Delete all messages in trash?"),
-                              GTK_STOCK_CANCEL, g_strconcat("+", _("_Empty trash"), NULL), NULL) != G_ALERTALTERNATE)
+                              GTK_STOCK_CANCEL, _("_Empty trash"), NULL,
+                                                ALERTFOCUS_SECOND) != G_ALERTALTERNATE)
                        return;
        }
        
@@ -2530,7 +2532,7 @@ static void folderview_send_queue_cb(GtkAction *action, gpointer data)
                if (alertpanel(_("Offline warning"), 
                               _("You're working offline. Override?"),
                               GTK_STOCK_NO, GTK_STOCK_YES,
-                              NULL) != G_ALERTALTERNATE)
+                              NULL, ALERTFOCUS_FIRST) != G_ALERTALTERNATE)
                return;
 
        /* ask for confirmation before sending queued messages only
@@ -2542,7 +2544,7 @@ static void folderview_send_queue_cb(GtkAction *action, gpointer data)
                        if (alertpanel(_("Send queued messages"), 
                                   _("Send all queued messages?"),
                                   GTK_STOCK_CANCEL, _("_Send"),
-                                  NULL) != G_ALERTALTERNATE)
+                                  NULL, ALERTFOCUS_FIRST) != G_ALERTALTERNATE)
                                return;
                }
        }
@@ -2631,8 +2633,8 @@ void folderview_move_folder(FolderView *folderview, FolderItem *from_folder,
                                             _("Do you really want to make folder '%s' a subfolder of '%s'?"), 
                                        from_folder->name, to_folder->name);
                status = alertpanel_full(copy ? _("Copy folder"):_("Move folder"), buf,
-                                        GTK_STOCK_NO, GTK_STOCK_YES, NULL, TRUE,
-                                        NULL, ALERT_QUESTION, G_ALERTDEFAULT);
+                                        GTK_STOCK_NO, GTK_STOCK_YES, NULL, ALERTFOCUS_FIRST,
+                                                                TRUE, NULL, ALERT_QUESTION);
                g_free(buf);
 
                if ((status & ~G_ALERTDISABLE) != G_ALERTALTERNATE)
@@ -2745,18 +2747,12 @@ static void folderview_processing_cb(GtkAction *action, gpointer data)
 
 void folderview_set_target_folder_color(gint color_op) 
 {
-       gint firstone = 1;
        GList *list;
        FolderView *folderview;
 
        for (list = folderview_list; list != NULL; list = list->next) {
                folderview = (FolderView *)list->data;
                gtkut_convert_int_to_gdk_color(color_op, &folderview->color_op);
-               if (firstone) {
-                       bold_tgtfold_style->fg[GTK_STATE_NORMAL] =
-                               folderview->color_op;
-                       firstone = 0;
-               }
        }
 }
 
@@ -2785,6 +2781,11 @@ void folderview_reflect_prefs(void)
                                GTK_SCROLLED_WINDOW(folderview->scrolledwin));
        gint height = gtk_adjustment_get_value(pos);
 
+       gtkut_convert_int_to_gdk_color(prefs_common.color[COL_NEW],
+                       &folderview->color_new);
+       gtkut_convert_int_to_gdk_color(prefs_common.color[COL_TGT_FOLDER],
+                       &folderview->color_op);
+
        if (!last_smallfont || strcmp(last_smallfont, SMALL_FONT) ||
                        !last_normalfont || strcmp(last_normalfont, NORMAL_FONT) ||
                        !last_boldfont || strcmp(last_boldfont, BOLD_FONT) ||
@@ -2808,15 +2809,12 @@ void folderview_reflect_prefs(void)
                s = NULL;               \
        }
 
-       STYLE_FREE(normal_style);
-       STYLE_FREE(normal_color_style);
        STYLE_FREE(bold_style);
-       STYLE_FREE(bold_color_style);
-       STYLE_FREE(bold_tgtfold_style);
 
 #undef STYLE_FREE
 
-       folderview_init(folderview);
+       folderview_set_fonts(folderview);
+
        gtk_cmclist_freeze(GTK_CMCLIST(folderview->ctree));
        folderview_column_set_titles(folderview);
        folderview_set_all();
@@ -3139,10 +3137,9 @@ void folderview_finish_dnd(const gchar *data, GdkDragContext *drag_context,
                g_slist_free(msglist);
                gtk_drag_finish(drag_context, TRUE, FALSE, time);
        } else {
-               gtk_drag_finish(drag_context, FALSE, FALSE, time);                      
+               gtk_drag_finish(drag_context, FALSE, FALSE, time);
        }
-       list_free_strings(list);
-       g_list_free(list);
+       list_free_strings_full(list);
 }
 
 static void folderview_drag_received_cb(GtkWidget        *widget,
@@ -3184,23 +3181,21 @@ static void folderview_drag_received_cb(GtkWidget        *widget,
                              src_item && src_item != item && FOLDER_CLASS(item->folder)->copy_msg != NULL)) {
                                return;
                        }
-                       if (item && src_item) {
-                               switch (gdk_drag_context_get_selected_action(drag_context)) {
-                               case GDK_ACTION_COPY:
+
+                       switch (gdk_drag_context_get_selected_action(drag_context)) {
+                       case GDK_ACTION_COPY:
+                               summary_copy_selected_to(folderview->summaryview, item);
+                               gtk_drag_finish(drag_context, TRUE, FALSE, time);
+                               break;
+                       case GDK_ACTION_MOVE:
+                       case GDK_ACTION_DEFAULT:
+                       default:
+                               if (FOLDER_CLASS(src_item->folder)->remove_msg == NULL)
                                        summary_copy_selected_to(folderview->summaryview, item);
-                                       gtk_drag_finish(drag_context, TRUE, FALSE, time);
-                                       break;
-                               case GDK_ACTION_MOVE:
-                               case GDK_ACTION_DEFAULT:
-                               default:
-                                       if (FOLDER_CLASS(src_item->folder)->remove_msg == NULL)
-                                               summary_copy_selected_to(folderview->summaryview, item);
-                                       else
-                                               summary_move_selected_to(folderview->summaryview, item);
-                                       gtk_drag_finish(drag_context, TRUE, TRUE, time);
-                               }
-                       } else
-                               gtk_drag_finish(drag_context, FALSE, FALSE, time);
+                               else
+                                       summary_move_selected_to(folderview->summaryview, item);
+                               gtk_drag_finish(drag_context, TRUE, TRUE, time);
+                       }
                } else {
                        /* comes from folderview */
                        char *source;
@@ -3326,3 +3321,33 @@ void folderview_grab_focus(FolderView *folderview)
         if (folderview)
                 gtk_widget_grab_focus(folderview->ctree);
 }
+
+static void folderview_header_set_displayed_columns_cb(GtkAction *gaction,
+               gpointer data)
+{
+       prefs_folder_column_open();
+}
+
+static gboolean folderview_header_button_pressed(GtkWidget *widget,
+               GdkEvent *_event,
+               gpointer user_data)
+{
+       GdkEventButton *event = (GdkEventButton *)_event;
+       FolderView *folderview = (FolderView *)user_data;
+
+       cm_return_val_if_fail(folderview != NULL, FALSE);
+
+       /* Only handle single button presses. */
+       if (event->type == GDK_2BUTTON_PRESS ||
+                       event->type == GDK_3BUTTON_PRESS)
+               return FALSE;
+
+       /* Handle right-click for context menu */
+       if (event->button == 3) {
+               gtk_menu_popup(GTK_MENU(folderview->headerpopupmenu),
+                               NULL, NULL, NULL, NULL, 3, event->time);
+               return TRUE;
+       }
+
+       return FALSE;
+}