"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "pan-0.133/pan/gui/actions.cc" of archive pan-0.133.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
    2 /*
    3  * Pan - A Newsreader for Gtk+
    4  * Copyright (C) 2002-2006  Charles Kerr <charles@rebelbase.com>
    5  *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; version 2 of the License.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software
   17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18  */
   19 
   20 #include <config.h>
   21 extern "C" {
   22   #include <glib/gi18n.h>
   23   #include <gtk/gtk.h>
   24 }
   25 #include <pan/general/debug.h>
   26 #include <pan/tasks/task-xover.h>
   27 #include <pan/icons/pan-pixbufs.h>
   28 #include "actions.h"
   29 #include "pad.h"
   30 #include "gui.h"
   31 
   32 #if !GTK_CHECK_VERSION(2,6,0)
   33 #define GTK_STOCK_EDIT GTK_STOCK_OPEN
   34 #endif
   35 
   36 using pan::PanUI;
   37 
   38 namespace
   39 {
   40   PanUI * pan_ui (0);
   41   Prefs * prefs (0);
   42 
   43   struct BuiltinIconInfo
   44   {
   45     const guint8* raw;
   46     const char * name;
   47   };
   48 
   49   const BuiltinIconInfo my_builtin_icons [] =
   50   {
   51     { icon_article_read, "ICON_ARTICLE_READ" },
   52     { icon_article_unread, "ICON_ARTICLE_UNREAD" },
   53     { icon_compose_followup, "ICON_COMPOSE_FOLLOWUP" },
   54     { icon_compose_post, "ICON_COMPOSE_POST" },
   55     { icon_disk, "ICON_DISK" },
   56     { icon_filter_only_attachments, "ICON_ONLY_ATTACHMENTS" },
   57     { icon_filter_only_cached, "ICON_ONLY_CACHED" },
   58     { icon_filter_only_me, "ICON_ONLY_ME" },
   59     { icon_filter_only_unread, "ICON_ONLY_UNREAD" },
   60     { icon_filter_only_watched, "ICON_ONLY_WATCHED" },
   61     { icon_get_dialog, "ICON_GET_DIALOG" },
   62     { icon_get_selected, "ICON_GET_SELECTED" },
   63     { icon_get_subscribed, "ICON_GET_SUBSCRIBED" },
   64     { icon_read_group, "ICON_READ_GROUP" },
   65     { icon_read_more, "ICON_READ_MORE" },
   66     { icon_read_less, "ICON_READ_LESS" },
   67     { icon_read_unread_article, "ICON_READ_UNREAD_ARTICLE" },
   68     { icon_read_unread_thread, "ICON_READ_UNREAD_THREAD" },
   69     { icon_score, "ICON_SCORE" },
   70     { icon_search_pulldown, "ICON_SEARCH_PULLDOWN" }
   71   };
   72 
   73   void
   74   register_my_builtin_icons ()
   75   {
   76     GtkIconFactory * factory = gtk_icon_factory_new ();
   77     gtk_icon_factory_add_default (factory);
   78 
   79     for (int i(0), qty(G_N_ELEMENTS(my_builtin_icons)); i<qty; ++i)
   80     {
   81       GdkPixbuf * pixbuf = gdk_pixbuf_new_from_inline (-1, my_builtin_icons[i].raw, false, 0);
   82 
   83       const int width (gdk_pixbuf_get_width (pixbuf));
   84       gtk_icon_theme_add_builtin_icon (my_builtin_icons[i].name, width, pixbuf);
   85 
   86       GtkIconSet * icon_set = gtk_icon_set_new_from_pixbuf (pixbuf);
   87       gtk_icon_factory_add (factory, my_builtin_icons[i].name, icon_set);
   88       g_object_unref (pixbuf);
   89 
   90       //std::cerr << "registered icon " << my_builtin_icons[i].name << std::endl;
   91 
   92       gdk_pixbuf_unref (pixbuf);
   93       gtk_icon_set_unref (icon_set);
   94     }
   95 
   96     g_object_unref (G_OBJECT (factory));
   97   }
   98 
   99   GtkActionGroup * _group (0);
  100 
  101   void do_prompt_for_charset           (GtkAction*) { pan_ui->do_prompt_for_charset(); }
  102   void do_read_selected_group          (GtkAction*) { pan_ui->do_read_selected_group(); }
  103   void do_mark_selected_groups_read    (GtkAction*) { pan_ui->do_mark_selected_groups_read(); }
  104   void do_clear_selected_groups        (GtkAction*) { pan_ui->do_clear_selected_groups(); }
  105   void do_xover_selected_groups        (GtkAction*) { pan_ui->do_xover_selected_groups(); }
  106   void do_xover_subscribed_groups      (GtkAction*) { pan_ui->do_xover_subscribed_groups(); }
  107   void do_download_headers             (GtkAction*) { pan_ui->do_download_headers(); }
  108   void do_refresh_groups               (GtkAction*) { pan_ui->do_refresh_groups(); }
  109   void do_subscribe_selected_groups    (GtkAction*) { pan_ui->do_subscribe_selected_groups(); }
  110   void do_unsubscribe_selected_groups  (GtkAction*) { pan_ui->do_unsubscribe_selected_groups(); }
  111   void do_save_articles                (GtkAction*) { pan_ui->do_save_articles(); }
  112   void do_save_articles_from_nzb       (GtkAction*) { pan_ui->do_save_articles_from_nzb(); }
  113   void do_print                        (GtkAction*) { pan_ui->do_print(); }
  114   void do_import_tasks                 (GtkAction*) { pan_ui->do_import_tasks(); }
  115   void do_cancel_latest_task           (GtkAction*) { pan_ui->do_cancel_latest_task(); }
  116   void do_show_task_window             (GtkAction*) { pan_ui->do_show_task_window(); }
  117   void do_show_log_window              (GtkAction*) { pan_ui->do_show_log_window(); }
  118   void do_quit                         (GtkAction*) { pan_ui->do_quit(); }
  119   void do_clear_header_pane            (GtkAction*) { pan_ui->do_clear_header_pane(); }
  120   void do_clear_body_pane              (GtkAction*) { pan_ui->do_clear_body_pane(); }
  121   void do_select_all_articles          (GtkAction*) { pan_ui->do_select_all_articles(); }
  122   void do_unselect_all_articles        (GtkAction*) { pan_ui->do_unselect_all_articles(); }
  123   void do_add_subthreads_to_selection  (GtkAction*) { pan_ui->do_add_subthreads_to_selection(); }
  124   void do_add_threads_to_selection     (GtkAction*) { pan_ui->do_add_threads_to_selection(); }
  125   void do_add_similar_to_selection     (GtkAction*) { pan_ui->do_add_similar_to_selection(); }
  126   void do_select_article_body          (GtkAction*) { pan_ui->do_select_article_body(); }
  127   void do_show_preferences_dialog      (GtkAction*) { pan_ui->do_show_preferences_dialog(); }
  128   void do_show_group_preferences_dialog(GtkAction*) { pan_ui->do_show_group_preferences_dialog(); }
  129   void do_show_profiles_dialog         (GtkAction*) { pan_ui->do_show_profiles_dialog(); }
  130   void do_jump_to_group_tab            (GtkAction*) { pan_ui->do_jump_to_group_tab(); }
  131   void do_jump_to_header_tab           (GtkAction*) { pan_ui->do_jump_to_header_tab(); }
  132   void do_jump_to_body_tab             (GtkAction*) { pan_ui->do_jump_to_body_tab(); }
  133   void do_rot13_selected_text          (GtkAction*) { pan_ui->do_rot13_selected_text(); }
  134   void do_download_selected_article    (GtkAction*) { pan_ui->do_download_selected_article(); }
  135   void do_read_selected_article        (GtkAction*) { pan_ui->do_read_selected_article(); }
  136   void do_show_selected_article_info   (GtkAction*) { pan_ui->do_show_selected_article_info(); }
  137   void do_read_more                    (GtkAction*) { pan_ui->do_read_more(); }
  138   void do_read_less                    (GtkAction*) { pan_ui->do_read_less(); }
  139   void do_read_next_unread_group       (GtkAction*) { pan_ui->do_read_next_unread_group(); }
  140   void do_read_next_group              (GtkAction*) { pan_ui->do_read_next_group(); }
  141   void do_read_next_unread_article     (GtkAction*) { pan_ui->do_read_next_unread_article(); }
  142   void do_read_next_article            (GtkAction*) { pan_ui->do_read_next_article(); }
  143   void do_read_next_watched_article    (GtkAction*) { pan_ui->do_read_next_watched_article(); }
  144   void do_read_next_unread_thread      (GtkAction*) { pan_ui->do_read_next_unread_thread(); }
  145   void do_read_next_thread             (GtkAction*) { pan_ui->do_read_next_thread(); }
  146   void do_read_previous_article        (GtkAction*) { pan_ui->do_read_previous_article(); }
  147   void do_read_previous_thread         (GtkAction*) { pan_ui->do_read_previous_thread(); }
  148   void do_read_parent_article          (GtkAction*) { pan_ui->do_read_parent_article(); }
  149   void do_show_servers_dialog          (GtkAction*) { pan_ui->do_show_servers_dialog(); }
  150   void do_plonk                        (GtkAction*) { pan_ui->do_plonk(); }
  151   void do_ignore                       (GtkAction*) { pan_ui->do_ignore(); }
  152   void do_watch                        (GtkAction*) { pan_ui->do_watch(); }
  153   void do_show_score_dialog            (GtkAction*) { pan_ui->do_show_score_dialog(); }
  154   void do_show_new_score_dialog        (GtkAction*) { pan_ui->do_show_new_score_dialog(); }
  155   void do_cancel_article               (GtkAction*) { pan_ui->do_cancel_article(); }
  156   void do_supersede_article            (GtkAction*) { pan_ui->do_supersede_article(); }
  157   void do_delete_article               (GtkAction*) { pan_ui->do_delete_article(); }
  158   void do_clear_article_cache          (GtkAction*) { pan_ui->do_clear_article_cache(); }
  159   void do_mark_article_read            (GtkAction*) { pan_ui->do_mark_article_read(); }
  160   void do_mark_article_unread          (GtkAction*) { pan_ui->do_mark_article_unread(); }
  161   void do_post                         (GtkAction*) { pan_ui->do_post(); }
  162   void do_followup_to                  (GtkAction*) { pan_ui->do_followup_to(); }
  163   void do_reply_to                     (GtkAction*) { pan_ui->do_reply_to(); }
  164   void do_pan_web                      (GtkAction*) { pan_ui->do_pan_web(); }
  165   void do_bug_report                   (GtkAction*) { pan_ui->do_bug_report(); }
  166   void do_tip_jar                      (GtkAction*) { pan_ui->do_tip_jar(); }
  167   void do_about_pan                    (GtkAction*) { pan_ui->do_about_pan(); }
  168 
  169   void do_work_online         (GtkToggleAction * a) { pan_ui->do_work_online         (gtk_toggle_action_get_active(a)); }
  170   void do_tabbed_layout       (GtkToggleAction * a) { pan_ui->do_tabbed_layout       (gtk_toggle_action_get_active(a)); }
  171   void do_show_group_pane     (GtkToggleAction * a) { pan_ui->do_show_group_pane     (gtk_toggle_action_get_active(a)); }
  172   void do_show_header_pane    (GtkToggleAction * a) { pan_ui->do_show_header_pane    (gtk_toggle_action_get_active(a)); }
  173   void do_show_body_pane      (GtkToggleAction * a) { pan_ui->do_show_body_pane      (gtk_toggle_action_get_active(a)); }
  174   void do_show_toolbar        (GtkToggleAction * a) { pan_ui->do_show_toolbar        (gtk_toggle_action_get_active(a)); }
  175   void do_shorten_group_names (GtkToggleAction * a) { pan_ui->do_shorten_group_names (gtk_toggle_action_get_active(a)); }
  176 
  177   guint get_action_activate_signal_id ()
  178   {
  179     static guint sig_id = 0;
  180     if (!sig_id)
  181       sig_id = g_signal_lookup ("activate", GTK_TYPE_ACTION);
  182     return sig_id;
  183   }
  184 
  185   void
  186   toggle_action_set_active (const char * action_name, bool is_active)
  187   {
  188     GtkAction * a = gtk_action_group_get_action (_group, action_name);
  189     const guint sig_id (get_action_activate_signal_id ());
  190     const gulong tag (g_signal_handler_find (a, G_SIGNAL_MATCH_ID, sig_id, 0, NULL, NULL, NULL));
  191     g_signal_handler_block (a, tag);
  192     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(a), is_active);
  193     g_signal_handler_unblock (a, tag);
  194   };
  195 
  196 
  197   /**
  198   ***  Boy these `match only' buttons are more trouble to sync than they're worth. :)
  199   **/
  200 
  201   const int SCORE_STATE_MASK (MATCH_IGNORED | MATCH_LOW_SCORING | MATCH_NORMAL_SCORING | MATCH_MEDIUM_SCORING | MATCH_HIGH_SCORING | MATCH_WATCHED);
  202   int prev_score_state;
  203   int match_on_score_state (MATCH_LOW_SCORING | MATCH_NORMAL_SCORING | MATCH_MEDIUM_SCORING | MATCH_HIGH_SCORING | MATCH_WATCHED);
  204 
  205   void sync_score_state_actions ()
  206   {
  207     toggle_action_set_active ("match-only-watched-articles",    match_on_score_state == MATCH_WATCHED);
  208     toggle_action_set_active ("match-watched-articles",         match_on_score_state & MATCH_WATCHED);
  209     toggle_action_set_active ("match-high-scoring-articles",    match_on_score_state & MATCH_HIGH_SCORING);
  210     toggle_action_set_active ("match-medium-scoring-articles",  match_on_score_state & MATCH_MEDIUM_SCORING);
  211     toggle_action_set_active ("match-normal-scoring-articles",  match_on_score_state & MATCH_NORMAL_SCORING);
  212     toggle_action_set_active ("match-low-scoring-articles",     match_on_score_state & MATCH_LOW_SCORING);
  213     toggle_action_set_active ("match-ignored-articles",         match_on_score_state & MATCH_IGNORED);
  214   }
  215 
  216   void set_new_match_on_score_state (int new_state)
  217   {
  218     prev_score_state = match_on_score_state;
  219     match_on_score_state = new_state;
  220     sync_score_state_actions ();
  221     pan_ui->do_match_on_score_state (new_state);
  222   }
  223 
  224   void set_score_state_bit_from_toggle (GtkToggleAction * a, int bit)
  225   {
  226     int new_state (match_on_score_state);
  227     if (gtk_toggle_action_get_active (a))
  228       new_state |= bit;
  229     else
  230       new_state &= (SCORE_STATE_MASK & ~bit);
  231     if (!new_state)
  232       new_state = SCORE_STATE_MASK;
  233     set_new_match_on_score_state (new_state);
  234   }
  235 
  236   void do_match_only_watched_articles (GtkToggleAction * a)   { set_new_match_on_score_state (gtk_toggle_action_get_active(a) ? MATCH_WATCHED : prev_score_state); }
  237   void do_match_watched_articles (GtkToggleAction * a)        { set_score_state_bit_from_toggle (a, MATCH_WATCHED); }
  238   void do_match_high_scoring_articles (GtkToggleAction * a)   { set_score_state_bit_from_toggle (a, MATCH_HIGH_SCORING); }
  239   void do_match_medium_scoring_articles (GtkToggleAction * a) { set_score_state_bit_from_toggle (a, MATCH_MEDIUM_SCORING); }
  240   void do_match_normal_scoring_articles (GtkToggleAction * a) { set_score_state_bit_from_toggle (a, MATCH_NORMAL_SCORING); }
  241   void do_match_low_scoring_articles (GtkToggleAction * a)    { set_score_state_bit_from_toggle (a, MATCH_LOW_SCORING); }
  242   void do_match_ignored_articles (GtkToggleAction * a)        { set_score_state_bit_from_toggle (a, MATCH_IGNORED); }
  243 
  244   /**
  245   ***
  246   **/
  247 
  248   void do_match_only_cached_articles (GtkToggleAction * a) { pan_ui->do_match_only_cached_articles (gtk_toggle_action_get_active(a)); }
  249   void do_match_only_binary_articles (GtkToggleAction * a) { pan_ui->do_match_only_binary_articles (gtk_toggle_action_get_active(a)); }
  250   void do_match_only_my_articles (GtkToggleAction * a) { pan_ui->do_match_only_my_articles (gtk_toggle_action_get_active(a)); }
  251   void do_match_only_unread_articles (GtkToggleAction * a) { pan_ui->do_match_only_unread_articles (gtk_toggle_action_get_active(a)); }
  252 
  253   GtkActionEntry entries[] =
  254   {
  255     { "file-menu", NULL, N_("_File"), NULL, NULL, NULL },
  256     { "edit-menu", NULL, N_("_Edit"), NULL, NULL, NULL },
  257     { "view-layout-menu", NULL, N_("_Layout"), NULL, NULL, NULL },
  258     { "view-group-pane-menu", NULL, N_("_Group Pane"), NULL, NULL, NULL },
  259     { "view-header-pane-menu", NULL, N_("_Header Pane"), NULL, NULL, NULL },
  260     { "view-body-pane-menu", NULL, N_("_Body Pane"), NULL, NULL, NULL },
  261     { "view-menu", NULL, N_("_View"), NULL, NULL, NULL },
  262     { "filter-menu", NULL, N_("Filte_r"), NULL, NULL, NULL },
  263     { "go-menu", NULL, N_("_Go"), NULL, NULL, NULL },
  264     { "actions-menu", NULL, N_("_Actions"), NULL, NULL, NULL },
  265     { "article-actions-menu", NULL, N_("_Articles"), NULL, NULL, NULL },
  266     { "group-actions-menu", NULL, N_("G_roups"), NULL, NULL, NULL },
  267     { "posting-actions-menu", NULL, N_("_Post"), NULL, NULL, NULL },
  268     { "post-menu", NULL, N_("_Post"), NULL, NULL, NULL },
  269     { "help-menu", NULL, N_("_Help"), NULL, NULL, NULL },
  270 
  271     { "set-charset", NULL,
  272       N_("Set Character _Encoding..."), NULL,
  273       N_("Set Character Encoding..."),
  274       G_CALLBACK(do_prompt_for_charset) },
  275 
  276     { "read-selected-group", "ICON_READ_MORE",
  277       N_("_Read Group"), NULL,
  278       N_("Read Group"),
  279       G_CALLBACK(do_read_selected_group) },
  280 
  281     { "mark-groups-read", GTK_STOCK_CLEAR,
  282       N_("_Mark Selected Groups Read"), "<control><shift>M",
  283       N_("Mark Selected Groups Read"),
  284       G_CALLBACK(do_mark_selected_groups_read) },
  285 
  286     { "delete-groups-articles", GTK_STOCK_DELETE,
  287       N_("_Delete Selected Groups' Articles"), "<control><shift>Delete",
  288       N_("Delete Selected Groups' Articles"),
  289       G_CALLBACK(do_clear_selected_groups) },
  290 
  291     { "get-new-headers-in-selected-groups", "ICON_GET_SELECTED",
  292       N_("Get New _Headers in Selected Groups"), "A",
  293       N_("Get New Headers in Selected Groups"),
  294       G_CALLBACK(do_xover_selected_groups) },
  295 
  296     { "get-new-headers-in-subscribed-groups", "ICON_GET_SUBSCRIBED",
  297       N_("Get New _Headers in Subscribed Groups"), "<shift>A",
  298       N_("Get New Headers in Subscribed Groups"),
  299       G_CALLBACK(do_xover_subscribed_groups) },
  300 
  301     { "download-headers", "ICON_GET_DIALOG",
  302       N_("Get _Headers..."), "",
  303       N_("Get Headers..."),
  304       G_CALLBACK(do_download_headers) },
  305 
  306     { "refresh-group-list", NULL,
  307       N_("Refresh Group List"), "",
  308       N_("Refresh Group List"),
  309       G_CALLBACK(do_refresh_groups) },
  310 
  311     { "subscribe", NULL,
  312       N_("_Subscribe"), NULL,
  313       N_("Subscribe"),
  314       G_CALLBACK(do_subscribe_selected_groups) },
  315 
  316     { "unsubscribe", NULL,
  317       N_("_Unsubscribe"), NULL,
  318       N_("Unsubscribe"),
  319       G_CALLBACK(do_unsubscribe_selected_groups) },
  320 
  321     { "save-articles", GTK_STOCK_SAVE,
  322       N_("_Save Articles..."), "<shift>S",
  323       N_("Save Articles..."),
  324       G_CALLBACK(do_save_articles) },
  325 
  326     { "save-articles-from-nzb", GTK_STOCK_SAVE,
  327       N_("_Save Articles from this NZB..."), NULL,
  328       N_("Save Articles from this NZB"),
  329       G_CALLBACK(do_save_articles_from_nzb) },
  330 
  331     { "print", GTK_STOCK_PRINT,
  332       NULL, "<control>P",
  333       NULL,
  334       G_CALLBACK(do_print) },
  335 
  336     { "import-tasks", GTK_STOCK_OPEN,
  337       N_("_Import NZB Files..."), NULL,
  338       NULL,
  339       G_CALLBACK(do_import_tasks) },
  340 
  341     { "cancel-last-task", GTK_STOCK_CANCEL,
  342       N_("_Cancel Last Task"), "<control>Delete",
  343       NULL,
  344       G_CALLBACK(do_cancel_latest_task) },
  345 
  346     { "show-task-window", NULL,
  347       N_("_Task Manager"), NULL,
  348       NULL,
  349       G_CALLBACK(do_show_task_window) },
  350 
  351     { "show-log-dialog", GTK_STOCK_DIALOG_INFO,
  352       N_("_Event Log"), NULL,
  353       NULL,
  354       G_CALLBACK(do_show_log_window) },
  355 
  356     { "quit", NULL,
  357       N_("_Quit"), "<control>Q",
  358       NULL,
  359       G_CALLBACK(do_quit) },
  360 
  361     { "select-all-articles", NULL,
  362       N_("Select _All Articles"), "<control>D",
  363       NULL,
  364       G_CALLBACK(do_select_all_articles) },
  365 
  366     { "unselect-all-articles", NULL,
  367       N_("_Deselect All Articles"), "<shift><control>D",
  368       NULL,
  369       G_CALLBACK(do_unselect_all_articles) },
  370 
  371     { "add-subthreads-to-selection", NULL,
  372       N_("Add Su_bthreads to Selection"), "D",
  373       NULL,
  374       G_CALLBACK(do_add_subthreads_to_selection) },
  375 
  376     { "add-threads-to-selection", NULL,
  377       N_("Add _Threads to Selection"), "<shift>D",
  378       NULL,
  379       G_CALLBACK(do_add_threads_to_selection) },
  380 
  381     { "add-similar-articles-to-selection", NULL,
  382       N_("Add _Similar Articles to Selection"), "<control>S",
  383       NULL,
  384       G_CALLBACK(do_add_similar_to_selection) },
  385 
  386     { "select-article-body", NULL,
  387       N_("Select Article _Body"), NULL,
  388       NULL,
  389       G_CALLBACK(do_select_article_body) },
  390 
  391     { "show-preferences-dialog", GTK_STOCK_PREFERENCES,
  392       N_("Edit _Preferences"), NULL,
  393       NULL,
  394       G_CALLBACK(do_show_preferences_dialog) },
  395 
  396     { "show-group-preferences-dialog", GTK_STOCK_PREFERENCES,
  397       N_("Edit Selected _Group's Preferences"), NULL,
  398       NULL,
  399       G_CALLBACK(do_show_group_preferences_dialog) },
  400 
  401     { "show-profiles-dialog", GTK_STOCK_EDIT,
  402       N_("Edit P_osting Profiles"), NULL,
  403       NULL,
  404       G_CALLBACK(do_show_profiles_dialog) },
  405 
  406     { "show-servers-dialog", GTK_STOCK_NETWORK,
  407       N_("Edit _News Servers"), NULL,
  408       NULL,
  409       G_CALLBACK(do_show_servers_dialog) },
  410 
  411     { "jump-to-group-tab", GTK_STOCK_JUMP_TO,
  412       N_("Jump to _Group Tab"), "1",
  413       NULL,
  414       G_CALLBACK(do_jump_to_group_tab) },
  415 
  416     { "jump-to-header-tab", GTK_STOCK_JUMP_TO,
  417       N_("Jump to _Header Tab"), "2",
  418       NULL,
  419       G_CALLBACK(do_jump_to_header_tab) },
  420 
  421     { "jump-to-body-tab", GTK_STOCK_JUMP_TO,
  422       N_("Jump to _Body Tab"), "3",
  423       NULL,
  424       G_CALLBACK(do_jump_to_body_tab) },
  425 
  426     { "rot13-selected-text", NULL,
  427       N_("_Rot13 Selected Text"), "<control><shift>R",
  428       NULL,
  429       G_CALLBACK(do_rot13_selected_text) },
  430 
  431     { "clear-header-pane", NULL,
  432       N_("Clear _Header Pane"), NULL,
  433       NULL,
  434       G_CALLBACK(do_clear_header_pane) },
  435     { "clear-body-pane", NULL,
  436       N_("Clear _Body Pane"), NULL,
  437       NULL,
  438       G_CALLBACK(do_clear_body_pane) },
  439 
  440     { "download-selected-article", "ICON_DISK",
  441       N_("Cache Article"), NULL,
  442       NULL,
  443       G_CALLBACK(do_download_selected_article) },
  444 
  445     { "read-selected-article", "ICON_READ_MORE",
  446       N_("Read Article"), NULL,
  447       NULL,
  448       G_CALLBACK(do_read_selected_article) },
  449 
  450     { "show-selected-article-info", NULL,
  451       N_("Show Article Information"), NULL,
  452       NULL,
  453       G_CALLBACK(do_show_selected_article_info) },
  454 
  455     { "read-more", "ICON_READ_MORE",
  456       N_("Read _More"), "space",
  457       N_("Read More"),
  458       G_CALLBACK(do_read_more) },
  459 
  460     { "read-less", "ICON_READ_LESS",
  461       N_("Read _Back"), "BackSpace",
  462       N_("Read Back"),
  463       G_CALLBACK(do_read_less) },
  464 
  465     { "read-next-unread-group", "ICON_READ_UNREAD_GROUP",
  466       N_("Next _Unread Group"), "G",
  467       NULL,
  468       G_CALLBACK(do_read_next_unread_group) },
  469 
  470     { "read-next-group", "ICON_READ_GROUP",
  471       N_("Next _Group"), "<shift>G",
  472       NULL,
  473       G_CALLBACK(do_read_next_group) },
  474 
  475     { "read-next-unread-article", "ICON_READ_UNREAD_ARTICLE",
  476       N_("Next _Unread Article"), "N",
  477       N_("Next Unread Article"),
  478       G_CALLBACK(do_read_next_unread_article) },
  479 
  480     { "read-next-article", NULL,
  481       N_("Next _Article"), "<control>N",
  482       N_("Next Article"),
  483       G_CALLBACK(do_read_next_article) },
  484 
  485     { "read-next-watched-article", NULL,
  486       N_("Next _Watched Article"), "<control><shift>N",
  487       NULL,
  488       G_CALLBACK(do_read_next_watched_article) },
  489 
  490     { "read-next-unread-thread", "ICON_READ_UNREAD_THREAD",
  491       N_("Next Unread _Thread"), "T",
  492       N_("Next Unread Thread"),
  493       G_CALLBACK(do_read_next_unread_thread) },
  494 
  495     { "read-next-thread", NULL,
  496       N_("Next Threa_d"), "<control>T",
  497       NULL,
  498       G_CALLBACK(do_read_next_thread) },
  499 
  500     { "read-previous-article", NULL,
  501       N_("Pre_vious Article"), "V",
  502       NULL,
  503       G_CALLBACK(do_read_previous_article) },
  504 
  505     { "read-previous-thread", NULL,
  506       N_("Previous _Thread"), "<control>V",
  507       NULL,
  508 
  509       G_CALLBACK(do_read_previous_thread) },
  510     { "read-parent-article", NULL,
  511       N_("_Parent Article"), "U",
  512       NULL,
  513       G_CALLBACK(do_read_parent_article) },
  514 
  515     { "plonk", NULL,
  516       N_("Ignore _Author"), NULL,
  517       NULL,
  518       G_CALLBACK(do_plonk) },
  519     { "watch-thread", NULL,
  520       N_("_Watch Thread"), NULL,
  521       NULL,
  522       G_CALLBACK(do_watch) },
  523 
  524     { "ignore-thread", NULL,
  525       N_("_Ignore Thread"), NULL,
  526       NULL,
  527       G_CALLBACK(do_ignore) },
  528 
  529     { "view-article-score", "ICON_SCORE",
  530       N_("Edit Article's Watch/Ignore/Score..."), "<control><shift>C",
  531       NULL,
  532       G_CALLBACK(do_show_score_dialog) },
  533 
  534     { "add-article-score", "ICON_SCORE",
  535       N_("Add a _Scoring Rule..."), "S",
  536       NULL,
  537       G_CALLBACK(do_show_new_score_dialog) },
  538 
  539     { "cancel-article", NULL,
  540       N_("Cance_l Article..."), NULL,
  541       NULL,
  542       G_CALLBACK(do_cancel_article) },
  543 
  544     { "supersede-article", NULL,
  545       N_("_Supersede Article..."), NULL,
  546       NULL,
  547       G_CALLBACK(do_supersede_article) },
  548 
  549     { "delete-article", GTK_STOCK_DELETE,
  550       N_("_Delete Article"), "Delete",
  551       NULL,
  552       G_CALLBACK(do_delete_article) },
  553 
  554     { "clear-article-cache", NULL,
  555       N_("Clear Article Cache"), NULL,
  556       NULL,
  557       G_CALLBACK(do_clear_article_cache) },
  558 
  559     { "mark-article-read", "ICON_ARTICLE_READ",
  560       N_("_Mark Article as Read"), "M",
  561       NULL,
  562       G_CALLBACK(do_mark_article_read) },
  563 
  564     { "mark-article-unread", "ICON_ARTICLE_UNREAD",
  565       N_("Mark Article as _Unread"), "<control>M",
  566       NULL,
  567       G_CALLBACK(do_mark_article_unread) },
  568 
  569     { "post", "ICON_COMPOSE_POST",
  570       N_("_Post to Newsgroup"), "P",
  571       N_("Post to Newsgroup"),
  572       G_CALLBACK(do_post) },
  573 
  574     { "followup-to", "ICON_COMPOSE_FOLLOWUP",
  575       N_("_Followup to Newsgroup"), "F",
  576       N_("Followup to Newsgroup"),
  577       G_CALLBACK(do_followup_to) },
  578 
  579     { "reply-to", NULL,
  580       N_("_Reply to Author in Mail"), "R",
  581       NULL,
  582       G_CALLBACK(do_reply_to) },
  583 
  584     { "pan-web-page", NULL,
  585       N_("_Pan Home Page"), NULL,
  586       NULL,
  587       G_CALLBACK(do_pan_web) },
  588 
  589     { "bug-report", NULL,
  590       N_("Give _Feedback or Report a Bug..."), NULL,
  591       NULL,
  592       G_CALLBACK(do_bug_report) },
  593 
  594     { "tip-jar", NULL,
  595       N_("_Tip Jar..."), NULL,
  596       NULL,
  597       G_CALLBACK(do_tip_jar) },
  598 
  599 #if GTK_CHECK_VERSION(2,6,0)
  600     { "about-pan", GTK_STOCK_ABOUT,
  601       N_("_About"), NULL,
  602       NULL,
  603       G_CALLBACK(do_about_pan) }
  604 #else
  605     { "about-pan", NULL,
  606       N_("_About"), NULL,
  607       NULL,
  608       G_CALLBACK(do_about_pan) }
  609 #endif
  610   };
  611 
  612   void prefs_toggle_callback_impl (GtkToggleAction * action)
  613   {
  614     const char * name (gtk_action_get_name (GTK_ACTION(action)));
  615     prefs->set_flag (name, gtk_toggle_action_get_active (action));
  616   }
  617 
  618   const guint n_entries (G_N_ELEMENTS (entries));
  619 
  620   GtkToggleActionEntry toggle_entries[] =
  621   {
  622     { "thread-headers",           NULL, N_("_Thread Headers"),                NULL, NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  623     { "wrap-article-body",        NULL, N_("_Wrap Article Body"),              "W", NULL, G_CALLBACK(prefs_toggle_callback_impl), false },
  624     { "mute-quoted-text",         NULL, N_("Mute _Quoted Text"),               "Q", NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  625     { "show-all-headers",         NULL, N_("Show All _Headers in Body Pane"),  "H", NULL, G_CALLBACK(prefs_toggle_callback_impl), false },
  626     { "show-smilies-as-graphics", NULL, N_("Show _Smilies as Graphics"),      NULL, NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  627     { "show-text-markup",         NULL, N_("Show *Bold*, __Underlined__, and /Italic/"), NULL, NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  628     { "size-pictures-to-fit",     NULL, N_("Size Pictures to _Fit"),          NULL, NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  629     { "monospace-font-enabled",   NULL, N_("Use _Monospace Font"),             "C", NULL, G_CALLBACK(prefs_toggle_callback_impl), false },
  630     { "focus-on-image",           NULL, N_("Set Focus to Images"),            NULL, NULL, G_CALLBACK(prefs_toggle_callback_impl), true },
  631 
  632 
  633     { "work-online", "ICON_ONLINE", N_("_Work Online"), "L", NULL, G_CALLBACK(do_work_online), true },
  634     { "tabbed-layout", GTK_STOCK_JUMP_TO, N_("_Tabbed Layout"), "Z", NULL, G_CALLBACK(do_tabbed_layout), false },
  635     { "show-group-pane", NULL, N_("Show Group _Pane"), "<control>1", NULL, G_CALLBACK(do_show_group_pane), true },
  636     { "show-header-pane", NULL, N_("Show Hea_der Pane"), "<control>2", NULL, G_CALLBACK(do_show_header_pane), true },
  637     { "show-body-pane", NULL, N_("Show Bod_y Pane"), "<control>3", NULL, G_CALLBACK(do_show_body_pane), true },
  638     { "show-toolbar", NULL, N_("Show _Toolbar"), NULL, NULL, G_CALLBACK(do_show_toolbar), true },
  639     { "shorten-group-names", GTK_STOCK_ZOOM_OUT, N_("Abbreviate Group Names"), "B", NULL, G_CALLBACK(do_shorten_group_names), false },
  640 
  641     { "match-only-unread-articles", "ICON_ONLY_UNREAD", N_("Match Only _Unread Articles"), NULL, N_("Match Only Unread Articles"), G_CALLBACK(do_match_only_unread_articles), false },
  642     { "match-only-cached-articles", "ICON_ONLY_CACHED", N_("Match Only _Cached Articles"), NULL, N_("Match Only Cached Articles"), G_CALLBACK(do_match_only_cached_articles), false },
  643     { "match-only-binary-articles", "ICON_ONLY_ATTACHMENTS", N_("Match Only _Complete Articles"), NULL, N_("Match Only Complete Articles"), G_CALLBACK(do_match_only_binary_articles), false },
  644     { "match-only-my-articles", "ICON_ONLY_ME", N_("Match Only _My Articles"), NULL, N_("Match Only My Articles"), G_CALLBACK(do_match_only_my_articles), false },
  645     { "match-only-watched-articles", "ICON_ONLY_WATCHED", N_("Match Only _Watched Articles"), NULL, N_("Match Only Watched Articles"), G_CALLBACK(do_match_only_watched_articles), false },
  646 
  647     { "match-watched-articles", NULL, N_("Match Scores of 9999 (_Watched)"), NULL, NULL, G_CALLBACK(do_match_watched_articles), true },
  648     { "match-high-scoring-articles", NULL, N_("Match Scores of 5000...9998 (_High)"), NULL, NULL, G_CALLBACK(do_match_high_scoring_articles), true },
  649     { "match-medium-scoring-articles", NULL, N_("Match Scores of 1...4999 (Me_dium)"), NULL, NULL, G_CALLBACK(do_match_medium_scoring_articles), true },
  650