Added header popup menu to summaryview, with two menuitems.
authorAndrej Kacian <ticho@claws-mail.org>
Sun, 25 Nov 2018 14:20:58 +0000 (15:20 +0100)
committerAndrej Kacian <ticho@claws-mail.org>
Thu, 29 Nov 2018 17:09:19 +0000 (18:09 +0100)
Also added "Lock column headers" to prefs dialog.

Sorting lock pref implementation by Paul.

src/prefs_common.c
src/prefs_common.h
src/prefs_summaries.c
src/summaryview.c
src/summaryview.h

index a305c72..aacb721 100644 (file)
@@ -507,7 +507,10 @@ static PrefParam param[] = {
        {"summary_col_show_tags", "FALSE",
         &prefs_common.summary_col_visible[S_COL_TAGS], P_BOOL, NULL, NULL, NULL},
 
-       {"summary_col_pos_mark", "0",
+       {"summary_col_lock", "FALSE", &prefs_common.summary_col_lock, P_BOOL,
+        NULL, NULL, NULL},
+
+        {"summary_col_pos_mark", "0",
          &prefs_common.summary_col_pos[S_COL_MARK], P_INT, NULL, NULL, NULL},
        {"summary_col_pos_unread", "1",
          &prefs_common.summary_col_pos[S_COL_STATUS], P_INT, NULL, NULL, NULL},
index f2ad141..edc55f2 100644 (file)
@@ -293,6 +293,9 @@ struct _PrefsCommon
        /* Actions */
        GSList *actions_list;
 
+       /* Summary lock column headers */
+       gboolean summary_col_lock;
+
        /* Summary columns visibility, position and size */
        gboolean summary_col_visible[N_SUMMARY_COLS];
        gint summary_col_pos[N_SUMMARY_COLS];
index 68225e1..2b94105 100644 (file)
@@ -82,6 +82,7 @@ typedef struct _SummariesPage
        GtkWidget *checkbtn_folder_default_hide_read_threads;
        GtkWidget *checkbtn_folder_default_hide_read_msgs;
        GtkWidget *checkbtn_folder_default_hide_del_msgs;
+       GtkWidget *checkbtn_summary_col_lock;
 
 } SummariesPage;
 
@@ -337,7 +338,6 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
        GtkWidget *label_datefmt;
        GtkWidget *button_datefmt;
        GtkWidget *entry_datefmt;
-       GtkWidget *hbox_dispitem;
        GtkWidget *button_dispitem;
        GtkWidget *checkbtn_reopen_last_folder;
        GtkWidget *checkbtn_always_show_msg;
@@ -365,6 +365,7 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
        GtkWidget *checkbtn_folder_default_hide_read_threads;
        GtkWidget *checkbtn_folder_default_hide_read_msgs;
        GtkWidget *checkbtn_folder_default_hide_del_msgs;
+       GtkWidget *checkbtn_summary_col_lock;
 
        notebook = gtk_notebook_new();
        gtk_widget_show(notebook);
@@ -375,16 +376,16 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox1,
                                 gtk_label_new(_("Folder list")));
        
-       hbox_dispitem = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox_dispitem);
-       gtk_box_pack_start(GTK_BOX(vbox1), hbox_dispitem, FALSE, TRUE, 0);
+       hbox0 = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (hbox0);
+       gtk_box_pack_start(GTK_BOX(vbox1), hbox0, FALSE, TRUE, 0);
 
        label = gtk_label_new(_("Displayed columns"));
        gtk_widget_show(label);
-       gtk_box_pack_start(GTK_BOX(hbox_dispitem), label, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(hbox0), label, FALSE, FALSE, 0);
        button_dispitem = gtk_button_new_from_stock(GTK_STOCK_EDIT);
        gtk_widget_show (button_dispitem);
-       gtk_box_pack_start (GTK_BOX (hbox_dispitem), button_dispitem, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox0), button_dispitem, FALSE, FALSE, 0);
        g_signal_connect (G_OBJECT (button_dispitem), "clicked",
                          G_CALLBACK (prefs_folder_column_open),
                          NULL);
@@ -440,20 +441,23 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
        gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox1,
                                 gtk_label_new(_("Message list")));
 
-       hbox_dispitem = gtk_hbox_new (FALSE, 8);
-       gtk_widget_show (hbox_dispitem);
-       gtk_box_pack_start(GTK_BOX(vbox1), hbox_dispitem, FALSE, TRUE, 0);
+       hbox0 = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (hbox0);
+       gtk_box_pack_start(GTK_BOX(vbox1), hbox0, FALSE, TRUE, 0);
        
        label = gtk_label_new(_("Displayed columns"));
        gtk_widget_show(label);
-       gtk_box_pack_start(GTK_BOX(hbox_dispitem), label, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(hbox0), label, FALSE, FALSE, 0);
        button_dispitem = gtk_button_new_from_stock(GTK_STOCK_EDIT);
        gtk_widget_show (button_dispitem);
-       gtk_box_pack_start (GTK_BOX (hbox_dispitem), button_dispitem, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox0), button_dispitem, FALSE, FALSE, 0);
        g_signal_connect (G_OBJECT (button_dispitem), "clicked",
                          G_CALLBACK (prefs_summary_column_open),
                          NULL);
 
+       PACK_SPACER(hbox0, hbox1, 4);
+       PACK_CHECK_BUTTON(hbox0, checkbtn_summary_col_lock, _("Lock column headers"));
+
        hbox2 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox2);
        gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, TRUE, 0);
@@ -676,6 +680,7 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
        prefs_summaries->checkbtn_folder_default_hide_read_threads = checkbtn_folder_default_hide_read_threads;
        prefs_summaries->checkbtn_folder_default_hide_read_msgs = checkbtn_folder_default_hide_read_msgs;
        prefs_summaries->checkbtn_folder_default_hide_del_msgs = checkbtn_folder_default_hide_del_msgs;
+       prefs_summaries->checkbtn_summary_col_lock = checkbtn_summary_col_lock;
 
        prefs_summaries->page.widget = vbox1;
        g_signal_connect(G_OBJECT(checkbtn_always_show_msg), "toggled",
@@ -744,6 +749,8 @@ static void prefs_summaries_create_widget(PrefsPage *_page, GtkWindow *window,
                        prefs_common.folder_default_hide_read_msgs);
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_folder_default_hide_del_msgs),
                        prefs_common.folder_default_hide_del_msgs);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_summary_col_lock),
+                       prefs_common.summary_col_lock);
 
        gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
                
@@ -796,6 +803,8 @@ static void prefs_summaries_save(PrefsPage *_page)
                GTK_TOGGLE_BUTTON(page->checkbtn_ask_override_colorlabel));
        prefs_common.mark_as_read_delay = gtk_spin_button_get_value_as_int(
                        GTK_SPIN_BUTTON(page->spinbtn_mark_as_read_delay));
+       prefs_common.summary_col_lock = gtk_toggle_button_get_active(
+               GTK_TOGGLE_BUTTON(page->checkbtn_summary_col_lock));
 
        prefs_common.default_sort_key = combobox_get_active_data(
                        GTK_COMBO_BOX(page->optmenu_sort_key));
@@ -803,6 +812,7 @@ static void prefs_summaries_save(PrefsPage *_page)
                        GTK_COMBO_BOX(page->optmenu_sort_type));
        prefs_common.next_unread_msg_dialog = combobox_get_active_data(
                        GTK_COMBO_BOX(page->optmenu_nextunreadmsgdialog));
+
        main_window_reflect_prefs_all();
 }
 
index c108424..38c1c1e 100644 (file)
@@ -444,6 +444,20 @@ static GtkActionEntry summary_popup_entries[] =
        {"SummaryViewPopup/View",                 NULL, N_("_View"), NULL, NULL, NULL },
 };
 
+static void summary_header_lock_sorting_cb(GtkAction *gaction, gpointer data);
+static void summary_header_set_displayed_columns_cb(GtkAction *gaction, gpointer data);
+
+static GtkActionEntry summary_header_popup_entries[] =
+{
+       {"SummaryViewHeaderPopup",                     NULL, "SummaryViewHeaderPopup", NULL, NULL, NULL },
+       {"SummaryViewHeaderPopup/SetDisplayedColumns", NULL, N_("_Set displayed columns"), NULL, NULL, G_CALLBACK(summary_header_set_displayed_columns_cb) }
+};
+
+static GtkToggleActionEntry summary_header_popup_toggle_entries[] =
+{
+       {"SummaryViewHeaderPopup/LockColumnHeaders",     NULL, N_("_Lock column headers"), NULL, NULL, G_CALLBACK(summary_header_lock_sorting_cb), FALSE }
+};
+
 static const gchar *const col_label[N_SUMMARY_COLS] = {
        "",            /* S_COL_MARK    */
        N_("S"),       /* S_COL_STATUS  */
@@ -662,8 +676,20 @@ SummaryView *summary_create(MainWindow *mainwin)
 
        /* create popup menu */
        
-       gtk_action_group_add_actions(mainwin->action_group, summary_popup_entries,
-                       G_N_ELEMENTS(summary_popup_entries), (gpointer)summaryview);
+       gtk_action_group_add_actions(mainwin->action_group,
+                       summary_popup_entries,
+                       G_N_ELEMENTS(summary_popup_entries),
+                       (gpointer)summaryview);
+
+       gtk_action_group_add_actions(mainwin->action_group,
+                       summary_header_popup_entries,
+                       G_N_ELEMENTS(summary_header_popup_entries),
+                       (gpointer)summaryview);
+
+       gtk_action_group_add_toggle_actions(mainwin->action_group,
+                       summary_header_popup_toggle_entries,
+                       G_N_ELEMENTS(summary_header_popup_toggle_entries),
+                       (gpointer)summaryview);
 
        summaryview->ui_manager = gtk_ui_manager_new();
        summaryview->action_group = cm_menu_create_action_group_full(summaryview->ui_manager,"Menu", summary_popup_entries,
@@ -757,9 +783,15 @@ SummaryView *summary_create(MainWindow *mainwin)
 #ifndef GENERIC_UMPC
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewPopup/View", "AllHeaders", "View/AllHeaders", GTK_UI_MANAGER_MENUITEM)
 #endif         
+
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus", "SummaryViewHeaderPopup", "SummaryViewHeaderPopup", GTK_UI_MANAGER_MENU)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup", "LockColumnHeaders", "SummaryViewHeaderPopup/LockColumnHeaders", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup", "SetDisplayedColumns", "SummaryViewHeaderPopup/SetDisplayedColumns", GTK_UI_MANAGER_MENUITEM)
+
        summaryview->popupmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
                                gtk_ui_manager_get_widget(mainwin->ui_manager, "/Menus/SummaryViewPopup")) );
-
+       summaryview->headerpopupmenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
+                               gtk_ui_manager_get_widget(mainwin->ui_manager, "/Menus/SummaryViewHeaderPopup")) );
 
        summaryview->vbox = vbox;
        summaryview->scrolledwin = scrolledwin;
@@ -997,6 +1029,7 @@ void summary_init(SummaryView *summaryview)
        main_create_mailing_list_menu (summaryview->mainwin, NULL);     
        summary_set_menu_sensitive(summaryview);
 
+       summaryview->header_menu_lock = FALSE;
 }
 
 #define CURRENTLY_DISPLAYED(m) \
@@ -6599,6 +6632,38 @@ static gboolean tooltip_cb (GtkWidget  *widget,
        return TRUE;
 }
 #endif
+
+static gboolean summary_header_button_pressed(GtkWidget *widget,
+               GdkEvent *_event,
+               gpointer user_data)
+{
+       GdkEventButton *event = (GdkEventButton *)_event;
+       SummaryView *summaryview = (SummaryView *)user_data;
+
+       cm_return_val_if_fail(summaryview != 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) {
+               /* Set up any menu items that need setting up. */
+               summaryview->header_menu_lock = TRUE;
+               cm_toggle_menu_set_active_full(summaryview->mainwin->ui_manager,
+                               "Menus/SummaryViewHeaderPopup/LockColumnHeaders",
+                               prefs_common_get_prefs()->summary_col_lock);
+               summaryview->header_menu_lock = FALSE;
+
+               gtk_menu_popup(GTK_MENU(summaryview->headerpopupmenu),
+                               NULL, NULL, NULL, NULL, 3, event->time);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 static GtkWidget *summary_ctree_create(SummaryView *summaryview)
 {
        GtkWidget *ctree;
@@ -6692,24 +6757,29 @@ static GtkWidget *summary_ctree_create(SummaryView *summaryview)
 
        /* connect signal to the buttons for sorting */
 #define CLIST_BUTTON_SIGNAL_CONNECT(col, func) \
+       g_signal_connect \
+               (G_OBJECT(GTK_CMCLIST(ctree)->column[col_pos[col]].button), \
+                "button-press-event", \
+                G_CALLBACK(summary_header_button_pressed), \
+                summaryview); \
        g_signal_connect \
                (G_OBJECT(GTK_CMCLIST(ctree)->column[col_pos[col]].button), \
                 "clicked", \
                 G_CALLBACK(func), \
-                summaryview)
-
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MARK   , summary_mark_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_STATUS , summary_status_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MIME   , summary_mime_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_NUMBER , summary_num_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SIZE   , summary_size_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_DATE   , summary_date_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_FROM   , summary_from_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TO     , summary_to_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SUBJECT, summary_subject_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE,   summary_score_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED,  summary_locked_clicked);
-       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS,    summary_tags_clicked);
+                summaryview);
+
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MARK   , summary_mark_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_STATUS , summary_status_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_MIME   , summary_mime_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_NUMBER , summary_num_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SIZE   , summary_size_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_DATE   , summary_date_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_FROM   , summary_from_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TO     , summary_to_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SUBJECT, summary_subject_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_SCORE  , summary_score_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_LOCKED , summary_locked_clicked)
+       CLIST_BUTTON_SIGNAL_CONNECT(S_COL_TAGS   , summary_tags_clicked)
        
 #undef CLIST_BUTTON_SIGNAL_CONNECT
 
@@ -7307,6 +7377,11 @@ guint summary_get_selection_count(SummaryView *summaryview)
 static void summary_sort_by_column_click(SummaryView *summaryview,
                                         FolderSortKey sort_key)
 {
+       if (prefs_common.summary_col_lock) {
+               debug_print("summaryview columns locked, ignoring\n");
+               return;
+       }
+
        GtkCMCTreeNode *node = NULL;
        START_TIMING("");
        if (summaryview->sort_key == sort_key)
@@ -8460,3 +8535,26 @@ gboolean summary_has_opened_message(SummaryView *summaryview)
        return (summaryview->displayed != NULL);
 }
 
+static void summary_header_lock_sorting_cb(GtkAction *gaction, gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *)data;
+       gboolean sorting_lock = prefs_common_get_prefs()->summary_col_lock;
+
+       if (summaryview->header_menu_lock)
+               return;
+
+       debug_print("%slocking summaryview columns\n",
+                       sorting_lock ? "un" : "");
+       prefs_common_get_prefs()->summary_col_lock = !sorting_lock;
+}
+
+static void summary_header_set_displayed_columns_cb(GtkAction *gaction,
+               gpointer data)
+{
+       SummaryView *summaryview = (SummaryView *)data;
+
+       if (summaryview->header_menu_lock)
+               return;
+
+       prefs_summary_column_open();
+}
index 5824761..c90a48b 100644 (file)
@@ -108,6 +108,7 @@ struct _SummaryView
        GtkWidget *toggle_search;
        GtkWidget *quick_search_pixmap;
        GtkWidget *popupmenu;
+       GtkWidget *headerpopupmenu;
        GtkWidget *colorlabel_menu;
        GtkWidget *tags_menu;
        GtkWidget *window;
@@ -168,12 +169,17 @@ private:
 
        GtkTargetList *target_list; /* DnD */
 
-       // folders with matches for recursive quicksearch queries
+       /* folders with matches for recursive quicksearch queries */
        GSList *recursive_matched_folders;
        FolderItem *search_root_folder;
 
        guint mark_as_read_timeout_tag;
 
+       /* A flag to indicate to header popup menuitem handlers that
+        * they should not do anything, because the menu items are
+        * being set up prior to the popup menu being displayed. */
+       gboolean header_menu_lock;
+
        GtkActionGroup *action_group;
        GtkUIManager *ui_manager;
 };