From: Andrej Kacian Date: Sun, 25 Nov 2018 14:20:58 +0000 (+0100) Subject: Added header popup menu to summaryview, with two menuitems. X-Git-Tag: 3.17.2~22 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=1e39691952b7907d1fe0bb91861ceb5fce539b71 Added header popup menu to summaryview, with two menuitems. Also added "Lock column headers" to prefs dialog. Sorting lock pref implementation by Paul. --- diff --git a/src/prefs_common.c b/src/prefs_common.c index a305c7294..aacb72143 100644 --- a/src/prefs_common.c +++ b/src/prefs_common.c @@ -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}, diff --git a/src/prefs_common.h b/src/prefs_common.h index f2ad14162..edc55f2df 100644 --- a/src/prefs_common.h +++ b/src/prefs_common.h @@ -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]; diff --git a/src/prefs_summaries.c b/src/prefs_summaries.c index 68225e138..2b9410559 100644 --- a/src/prefs_summaries.c +++ b/src/prefs_summaries.c @@ -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(); } diff --git a/src/summaryview.c b/src/summaryview.c index c10842462..38c1c1ef4 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -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(); +} diff --git a/src/summaryview.h b/src/summaryview.h index 582476106..c90a48b2b 100644 --- a/src/summaryview.h +++ b/src/summaryview.h @@ -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; };