German translation update by Axel Köllhofer
[clawsker.git] / clawsker
index b36f796d34ef8f672c8d1807e8545553490df546..ea085802c87a82f7460588bd73c949c1fffd1189 100755 (executable)
--- a/clawsker
+++ b/clawsker
@@ -70,6 +70,8 @@ sub _ {
     tab_other => _('Other'),
     tab_winpos => _('Windows'),
     tab_accounts => _('Accounts'),
+    tab_plugins => _('Plugins'),
+    tab_info => _('Info'),
 
     ab_frame => _('Addressbook'),
     mem_frame => _('Memory'),
@@ -163,15 +165,17 @@ sub _ {
     l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
     h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
     l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
-    h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
+    h_beh_out_ascii => _('If allowed by content, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is always enforced.'),
     l_beh_pp_unsel => _('Primary paste unselects selection'),
     h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
     l_beh_inline_at => _('Show inline attachments'),
-    h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view.'),
+    h_beh_inline_at => _('Allows to hide inline attachments already shown in mail structure view.'),
     l_beh_addr_swc => _('Address search in compose window matches any'),
     h_beh_addr_swc => _('On Tab-key completion, address text will match any part of the string or only from the start.'),
     l_beh_fold_swc => _('Folder search in folder selector matches any'),
     h_beh_fold_swc => _('On folder name completion text will match any part of the string or only from the start.'),
+    l_beh_rewrite_ff => _('Rewrite first \'From\' using QP encoding'),
+    h_beh_rewrite_ff => _('Workaround some servers which convert first \'From\' to \'>From\' by using Quoted-Printable transfer encoding instead of 7bit/8bit encoding.'),
 
     l_col_emphasis => _('X-Mailer header'),
     h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
@@ -212,22 +216,41 @@ sub _ {
     l_acc_gtls_pri => _('GnuTLS priority'),
     h_acc_gtls_pri => _('Value to use as GnuTLS priority string if custom priority check is enabled. Otherwise this value is ignored.'),
 
-    e_error => _('Error: '),
-    e_noclawsrc => _('resource file for Claws Mail was not found.'),
-    e_running => _('seems Claws Mail is currently running, close it first.'),
+    l_plu_gpg_alimit => _('Autocompletion limit'),
+    h_plu_gpg_alimit => _('Limits the number of addresses obtained from keyring through autocompletion. Use 0 to get all matches.'),
+    l_plu_lav_burl => _('Base URL'),
+    h_plu_lav_burl => _('This is the URL where avatar requests are sent. You can use the one of your own libravatar server, if available.'),
+    l_plu_prl_flvb => _('Log level'),
+    h_plu_prl_flvb => _('Verbosity level of log, accumulative.'),
+    l_plu_prl_none => _('None'),
+    l_plu_prl_manual => _('Manual'),
+    l_plu_prl_action => _('Actions'),
+    l_plu_prl_match => _('Matches'),
 );
 
+# data and metadata of resource files
+my $CONFIGDATA;
+my $CONFIGMETA;
+my $ACCOUNTDATA;
+my $ACCOUNTMETA;
 # all preferences read by load_preferences
 my %PREFS = ();
 my %ACPREFS = ();
+my %PLPREFS = ();
 # values of all preferences handled by clawsker
 my %HPVALUE = ();
 my %ACHPVALUE = ();
+my %PLHPVALUE = ();
 # default config dir and file name
 my $ALTCONFIGDIR = FALSE;
 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
 my $CONFIGRC = 'clawsrc';
 my $ACCOUNTRC = 'accountrc';
+# supported and available plugins lists
+my @PLUGINS = qw(AttRemover GPG ManageSieve Libravatar PerlPlugin);
+my @AVPLUGINS = ();
+# loaded icons
+my @APPICONS = ();
 
 # index constants for preference arrays
 use constant NAME  => 0; # the name on the rc file
@@ -236,10 +259,10 @@ use constant DESC  => 2; # the description for the hint/help
 use constant TYPE  => 3; # data type: bool, int, float, string, color
 use constant CMVER => 4; # lowest[,highest] Claws Mail version(s) the feature exists
 use constant CMDEF => 5; # default value for the preference in Claws Mail
-use constant GUI   => 6; # GUI element
+use constant PLUGIN => 6; # plugin section (only in plugin preferences)
 
 # constants for GUI spacing
-use constant HBOX_SPC => 5;
+use constant HBOX_PAD => 5;
 use constant FRAME_SPC => 2;
 use constant PAGE_SPC => 5;
 
@@ -385,7 +408,7 @@ sub error_dialog {
 }
 
 sub claws_is_running {
-    my $emsg = "$xl::s{e_error}$xl::s{e_running}";
+    my $emsg = _('Error: seems Claws Mail is currently running, close it first.');
     log_message ($emsg);
     error_dialog ($emsg);
     return FALSE;
@@ -408,7 +431,7 @@ sub check_claws_not_running {
 sub check_rc_file {
     my ($rcfile) = @_;
     (defined($rcfile) && -f $rcfile) or do {
-        my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
+        my $emsg = _('Error: resource file for Claws Mail was not found.');
         log_message ($emsg);
         error_dialog ($emsg);
         return FALSE;
@@ -439,12 +462,19 @@ sub set_widget_sens {
 
 # graphic element creation
 
+sub new_hbox_spaced_pack {
+    my $hbox = Gtk2::HBox->new (FALSE);
+    foreach (@_) {
+        $hbox->pack_start ($_, FALSE, FALSE, HBOX_PAD);
+    }
+    return $hbox;
+}
+
 sub new_check_button_for($$$) {
     my ($hash, $key, $vhash) = @_;
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
     #
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
     my $cb = Gtk2::CheckButton->new ($label);
     my $value = $$vhash{$name};
     $value //= $$hash{$key}[CMDEF];
@@ -455,9 +485,8 @@ sub new_check_button_for($$$) {
         });
     set_widget_hint ($cb, $$hash{$key}[DESC]);
     set_widget_sens ($cb, $$hash{$key}[CMVER]);
-    $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($cb);
 }
 
 sub new_text_box_for_int($$$) {
@@ -467,7 +496,6 @@ sub new_text_box_for_int($$$) {
     my @type = split (/,/, $$hash{$key}[TYPE]);
     push (@type, 0), push (@type, 10000) unless ($#type > 0);
     #
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
     my $glabel = Gtk2::Label->new ($label);
     my $pagei = int (($type[2] - $type[1]) / 10);
     my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
@@ -482,10 +510,8 @@ sub new_text_box_for_int($$$) {
     set_widget_hint ($gentry, $$hash{$key}[DESC]);
     set_widget_sens ($gentry, $$hash{$key}[CMVER]);
     $glabel->set_sensitive ($gentry->sensitive);
-    $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
-    $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($glabel, $gentry);
 }
 
 sub new_text_box_for_nchar($$$) {
@@ -493,7 +519,6 @@ sub new_text_box_for_nchar($$$) {
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
     my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen,width
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
     my $glabel = Gtk2::Label->new ($label);
     my $gentry = Gtk2::Entry->new ();
     $gentry->set_max_length($type[2]) if defined ($type[2]);
@@ -510,10 +535,8 @@ sub new_text_box_for_nchar($$$) {
     set_widget_hint ($gentry, $$hash{$key}[DESC]);
     set_widget_sens ($gentry, $$hash{$key}[CMVER]);
     $glabel->set_sensitive ($gentry->sensitive);
-    $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
-    $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($glabel, $gentry);
 }
 
 sub new_color_button_for($$$) {
@@ -524,7 +547,6 @@ sub new_color_button_for($$$) {
     my $value = $$vhash{$name};
     $value //= $$hash{$key}[CMDEF];
     my $col = gdk_color_from_str ($value);
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
     my $glabel = Gtk2::Label->new ($label);
     my $button = Gtk2::ColorButton->new_with_color ($col);
     $button->set_title ($label);
@@ -536,10 +558,8 @@ sub new_color_button_for($$$) {
     set_widget_hint ($button, $$hash{$key}[DESC]);
     set_widget_sens ($button, $$hash{$key}[CMVER]);
     $glabel->set_sensitive ($button->sensitive);
-    $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
-    $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($button, $glabel);
 }
 
 sub new_selection_box_for($$$) {
@@ -547,7 +567,6 @@ sub new_selection_box_for($$$) {
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
     #
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
     my $glabel = Gtk2::Label->new ($label);
     my $combo = Gtk2::ComboBox->new_text;
     my @options = split (';', $$hash{$key}[TYPE]);
@@ -565,19 +584,17 @@ sub new_selection_box_for($$$) {
     set_widget_hint ($combo, $$hash{$key}[DESC]);
     set_widget_sens ($combo, $$hash{$key}[CMVER]);
     $glabel->set_sensitive ($combo->sensitive);
-    $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
-    $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($glabel, $combo);
 }
 
 # more graphic helpers
 
 sub new_hbox_pack {
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
+    my $hbox = Gtk2::HBox->new (FALSE);
     $hbox->set_border_width (PAGE_SPC);
-    foreach my $item (@_) {
-        $hbox->pack_start ($item, FALSE, FALSE, 0);
+    foreach (@_) {
+        $hbox->pack_start ($_, FALSE, FALSE, 0);
     }
     return $hbox;
 }
@@ -585,8 +602,8 @@ sub new_hbox_pack {
 sub new_vbox_pack {
     my $vbox = Gtk2::VBox->new (FALSE, 5);
     $vbox->set_border_width (PAGE_SPC);
-    foreach my $item (@_) {
-        $vbox->pack_start ($item, FALSE, FALSE, 0);
+    foreach (@_) {
+        $vbox->pack_start ($_, FALSE, FALSE, 0);
     }
     return $vbox;
 }
@@ -594,8 +611,8 @@ sub new_vbox_pack {
 sub new_vbox_pack_compact {
     my $vbox = Gtk2::VBox->new (FALSE, 0);
     $vbox->set_border_width (0);
-    foreach my $item (@_) {
-        $vbox->pack_start ($item, FALSE, FALSE, 0);
+    foreach (@_) {
+        $vbox->pack_start ($_, FALSE, FALSE, 0);
     }
     return $vbox;
 }
@@ -618,25 +635,22 @@ sub new_subpage_frame {
         'bool',
         '2.7.0',
         '0',
-        undef,
     ],
     max_use => [
         'cache_max_mem_usage',
         $xl::s{l_oth_max_use},
         $xl::s{h_oth_max_use},
         'int,0,262144', # 0 Kb - 256 Mb
-        '0.0.0',
+        '0.7.8.36',
         '4096',
-        undef,
     ],
     min_time => [
         'cache_min_keep_time',
         $xl::s{l_oth_min_time},
         $xl::s{h_oth_min_time},
         'int,0,120', # 0 minutes - 2 hours
-        '0.0.0',
+        '0.7.8.36',
         '15',
-        undef,
     ],
     use_netm => [
         'use_networkmanager',
@@ -645,7 +659,6 @@ sub new_subpage_frame {
         'bool',
         '3.3.1',
         '1',
-        undef,
     ],
     mp_rounds => [
         'master_passphrase_pbkdf2_rounds',
@@ -654,7 +667,6 @@ sub new_subpage_frame {
         'int,50000,1000000',
         '3.13.2.110',
         '50000',
-        undef,
     ],
 );
 
@@ -686,54 +698,48 @@ sub new_other_page() {
         $xl::s{l_gui_b_unread},
         $xl::s{h_gui_b_unread},
         'bool',
-        '0.0.0',
+        '0.5.3',
         '1',
-        undef,
     ],
     no_markup => [
         'compose_no_markup',
         $xl::s{l_gui_no_markup},
         $xl::s{h_gui_no_markup},
         'bool',
-        '0.0.0',
+        '2.1.0.16',
         '0',
-        undef,
     ],
     dot_lines => [
         'enable_dotted_lines',
         $xl::s{l_gui_dot_lines},
         $xl::s{h_gui_dot_lines},
         'bool',
-        '0.0.0,3.7.10.44',
+        '2.4.0.115,3.7.10.44',
         '0',
-        undef,
     ],
     h_scroll => [
         'enable_hscrollbar',
         $xl::s{l_gui_h_scroll},
         $xl::s{h_gui_h_scroll},
         'bool',
-        '0.0.0',
+        '0.8.6.18',
         '1',
-        undef,
     ],
     swp_from => [
         'enable_swap_from',
         $xl::s{l_gui_swp_from},
         $xl::s{h_gui_swp_from},
         'bool',
-        '0.0.0',
+        '1.9.13.40',
         '0',
-        undef,
     ],
     v_scroll => [
         'folderview_vscrollbar_policy',
         $xl::s{l_gui_v_scroll},
         $xl::s{h_gui_v_scroll},
         '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
-        '0.0.0',
+        '0.7.8.14',
         '0',
-        undef,
     ],
     from_show => [
         'summary_from_show',
@@ -742,16 +748,14 @@ sub new_other_page() {
         '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
         '3.7.10',
         '0',
-        undef,
     ],
     strip_off => [
         'stripes_color_offset',
         $xl::s{l_gui_strip_off},
         $xl::s{h_gui_strip_off},
         'int,0,40000', # no idea what this number means
-        '0.0.0',
+        '2.4.0.186',
         '4000',
-        undef,
     ],
     cursor_v => [
         'textview_cursor_visible',
@@ -760,7 +764,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     toolbar_d => [
         'toolbar_detachable',
@@ -769,7 +772,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     strip_all => [
         'use_stripes_everywhere',
@@ -778,7 +780,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     strip_sum => [
         'use_stripes_in_summaries',
@@ -787,7 +788,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     two_linev => [
         'two_line_vertical',
@@ -796,7 +796,6 @@ sub new_other_page() {
         'bool',
         '3.4.0.7',
         '0',
-        undef,
     ],
     margin_co => [
         'show_compose_margin',
@@ -805,7 +804,6 @@ sub new_other_page() {
         'bool',
         '3.7.6.7',
         '0',
-        undef,
     ],
     mview_date => [
         'msgview_date_format',
@@ -814,7 +812,6 @@ sub new_other_page() {
         'bool',
         '3.7.8.42',
         '0',
-        undef,
     ],
     zero_char => [
         'zero_replacement_char',
@@ -823,7 +820,6 @@ sub new_other_page() {
         'char,1,1',
         '2.8.1.77',
         '0',
-        undef,
     ],
     type_any => [
         'type_any_header',
@@ -832,7 +828,6 @@ sub new_other_page() {
         'bool',
         '3.12.0.44',
         '0',
-        undef,
     ],
     next_del => [
         'next_on_delete',
@@ -841,7 +836,6 @@ sub new_other_page() {
         'bool',
         '3.13.0.5',
         '0',
-        undef,
     ],
 );
 
@@ -903,7 +897,6 @@ sub new_gui_page() {
         'int,100,3000', # 0.1 seconds - 3 seconds
         '0.0.0',
         '500',
-        undef,
     ],
     dangerous => [
         'live_dangerously',
@@ -912,7 +905,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     flowed => [
         'respect_flowed_format',
@@ -921,7 +913,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     parts_rw => [
         'save_parts_readwrite',
@@ -930,7 +921,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     skip_ssl => [
         'skip_ssl_cert_check',
@@ -939,7 +929,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     up_step => [
         'statusbar_update_step',
@@ -948,7 +937,6 @@ sub new_gui_page() {
         'int,1,200', # 1 item - 200 items
         '0.0.0',
         '10',
-        undef,
     ],
     thread_a => [
         'thread_by_subject_max_age',
@@ -957,7 +945,6 @@ sub new_gui_page() {
         'int,1,30', # 1 day - 30 days
         '0.0.0',
         '10',
-        undef,
     ],
     unsafe_ssl => [
         'unsafe_ssl_certs',
@@ -966,16 +953,14 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     use_utf8 => [
         'utf8_instead_of_locale_for_broken_mail',
         $xl::s{l_beh_use_utf8},
         $xl::s{h_beh_use_utf8},
         'bool',
-        '0.0.0',
+        '1.9.14.49',
         '0',
-        undef,
     ],
     warn_dnd => [
         'warn_dnd',
@@ -984,7 +969,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     out_ascii => [
         'outgoing_fallback_to_ascii',
@@ -993,7 +977,6 @@ sub new_gui_page() {
         'bool',
         '3.4.0.37',
         '1',
-        undef,
     ],
     pp_unsel => [
         'primary_paste_unselects',
@@ -1002,7 +985,6 @@ sub new_gui_page() {
         'bool',
         '3.6.1.35',
         '0',
-        undef,
     ],
     inline_at => [
         'show_inline_attachments',
@@ -1011,7 +993,6 @@ sub new_gui_page() {
         'bool',
         '3.7.8.48',
         '1',
-        undef,
     ],
     addr_swc => [
         'address_search_wildcard',
@@ -1020,7 +1001,6 @@ sub new_gui_page() {
         'bool',
         '3.9.3.18',
         '0',
-        undef,
     ],
     fold_swc => [
         'folder_search_wildcard',
@@ -1029,7 +1009,14 @@ sub new_gui_page() {
         'bool',
         '3.9.3.18',
         '0',
-        undef,
+    ],
+    rewrite_ff => [
+        'rewrite_first_from',
+        $xl::s{l_beh_rewrite_ff},
+        $xl::s{h_beh_rewrite_ff},
+        'bool',
+        '3.14.0.94',
+        '0',
     ],
 );
 
@@ -1062,7 +1049,8 @@ sub new_behaviour_page() {
                              new_check_button_for (\%pr::beh, 'dangerous', \%HPVALUE),
                              new_check_button_for (\%pr::beh, 'out_ascii', \%HPVALUE),
                              new_check_button_for (\%pr::beh, 'pp_unsel', \%HPVALUE),
-                             new_check_button_for (\%pr::beh, 'inline_at', \%HPVALUE)),
+                             new_check_button_for (\%pr::beh, 'inline_at', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'rewrite_ff', \%HPVALUE)),
                          $xl::s{msgs_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
     $bf->pack_start (new_subpage_frame (
@@ -1082,7 +1070,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#0000cf',
-        undef,
     ],
     log_err => [
         'log_error_color',
@@ -1091,7 +1078,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#af0000',
-        undef,
     ],
     log_in => [
         'log_in_color',
@@ -1100,7 +1086,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#000000',
-        undef,
     ],
     log_msg => [
         'log_msg_color',
@@ -1109,7 +1094,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#00af00',
-        undef,
     ],
     log_out => [
         'log_out_color',
@@ -1118,7 +1102,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#0000ef',
-        undef,
     ],
     log_warn => [
         'log_warn_color',
@@ -1127,7 +1110,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#af0000',
-        undef,
     ],
     diff_add => [
         'diff_added_color',
@@ -1136,7 +1118,6 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#008b8b',
-        undef,
     ],
     diff_del => [
         'diff_deleted_color',
@@ -1145,7 +1126,6 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#6a5acd',
-        undef,
     ],
     diff_hunk => [
         'diff_hunk_color',
@@ -1154,7 +1134,6 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#a52a2a',
-        undef,
     ],
 );
 
@@ -1189,7 +1168,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     main_y => [
         'mainwin_y',
@@ -1198,7 +1176,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     main_w => [
         'mainwin_width',
@@ -1207,7 +1184,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '779',
-        undef,
     ],
     main_h => [
         'mainwin_height',
@@ -1216,7 +1192,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '568',
-        undef,
     ],
     main_mx => [
         'mainwin_maximised',
@@ -1225,7 +1200,6 @@ sub new_colours_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     main_fs => [
         'mainwin_fullscreen',
@@ -1234,7 +1208,6 @@ sub new_colours_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     msgs_x => [
         'main_messagewin_x',
@@ -1243,7 +1216,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '256',
-        undef,
     ],
     msgs_y => [
         'main_messagewin_y',
@@ -1252,7 +1224,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '210',
-        undef,
     ],
     msgs_w => [
         'messagewin_width',
@@ -1261,7 +1232,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     msgs_h => [
         'messagewin_height',
@@ -1270,7 +1240,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '540',
-        undef,
     ],
     send_w => [
         'sendwin_width',
@@ -1279,7 +1248,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '460',
-        undef,
     ],
     send_h => [
         'sendwin_height',
@@ -1288,7 +1256,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     recv_w => [
         'receivewin_width',
@@ -1297,7 +1264,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '460',
-        undef,
     ],
     recv_h => [
         'receivewin_height',
@@ -1306,7 +1272,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fold_x => [
         'folderwin_x',
@@ -1315,7 +1280,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     fold_y => [
         'folderwin_y',
@@ -1324,7 +1288,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     fold_w => [
         'folderitemwin_width',
@@ -1333,7 +1296,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     fold_h => [
         'folderitemwin_height',
@@ -1342,7 +1304,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fsel_w => [
         'folderselwin_width',
@@ -1351,7 +1312,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     fsel_h => [
         'folderselwin_height',
@@ -1360,7 +1320,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     sour_w => [
         'sourcewin_width',
@@ -1369,7 +1328,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     sour_h => [
         'sourcewin_height',
@@ -1378,7 +1336,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     addr_w => [
         'addressbookwin_width',
@@ -1387,7 +1344,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     addr_h => [
         'addressbookwin_height',
@@ -1396,7 +1352,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     adep_w => [
         'addressbookeditpersonwin_width',
@@ -1405,7 +1360,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '640',
-        undef,
     ],
     adep_h => [
         'addressbookeditpersonwin_height',
@@ -1414,7 +1368,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '320',
-        undef,
     ],
     adeg_w => [
         'addressbookeditgroupwin_width',
@@ -1423,7 +1376,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '580',
-        undef,
     ],
     adeg_h => [
         'addressbookeditgroupwin_height',
@@ -1432,7 +1384,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '340',
-        undef,
     ],
     adda_w => [
         'addressaddwin_width',
@@ -1441,7 +1392,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     adda_h => [
         'addressaddwin_height',
@@ -1450,7 +1400,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     addf_w => [
         'addressbook_folderselwin_width',
@@ -1459,7 +1408,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     addf_h => [
         'addressbook_folderselwin_height',
@@ -1468,7 +1416,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acce_w => [
         'editaccountwin_width',
@@ -1477,7 +1424,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     acce_h => [
         'editaccountwin_height',
@@ -1486,7 +1432,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acco_w => [
         'accountswin_width',
@@ -1495,7 +1440,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     acco_h => [
         'accountswin_height',
@@ -1504,7 +1448,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     filt_w => [
         'filteringwin_width',
@@ -1513,7 +1456,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     filt_h => [
         'filteringwin_height',
@@ -1522,7 +1464,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fila_w => [
         'filteringactionwin_width',
@@ -1531,7 +1472,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '490',
-        undef,
     ],
     fila_h => [
         'filteringactionwin_height',
@@ -1540,7 +1480,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fild_w => [
         'filtering_debugwin_width',
@@ -1549,7 +1488,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     fild_h => [
         'filtering_debugwin_height',
@@ -1558,7 +1496,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     matc_w => [
         'matcherwin_width',
@@ -1567,7 +1504,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     matc_h => [
         'matcherwin_height',
@@ -1576,7 +1512,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     pref_w => [
         'prefswin_width',
@@ -1585,7 +1520,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     pref_h => [
         'prefswin_height',
@@ -1594,7 +1528,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     temp_w => [
         'templateswin_width',
@@ -1603,7 +1536,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '480',
-        undef,
     ],
     temp_h => [
         'templateswin_height',
@@ -1612,7 +1544,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acti_w => [
         'actionswin_width',
@@ -1621,7 +1552,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '486',
-        undef,
     ],
     acti_h => [
         'actionswin_height',
@@ -1630,7 +1560,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     tags_w => [
         'tagswin_width',
@@ -1639,7 +1568,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '486',
-        undef,
     ],
     tags_h => [
         'tagswin_height',
@@ -1648,7 +1576,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     plug_w => [
         'pluginswin_width',
@@ -1657,7 +1584,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     plug_h => [
         'pluginswin_height',
@@ -1666,7 +1592,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     logw_w => [
         'logwin_width',
@@ -1675,7 +1600,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     logw_h => [
         'logwin_height',
@@ -1684,7 +1608,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     prin_w => [
         'print_previewwin_width',
@@ -1693,7 +1616,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     prin_h => [
         'print_previewwin_height',
@@ -1702,7 +1624,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
 );
 
@@ -1912,7 +1833,6 @@ sub new_winpos_page() {
         'bool',
         '3.9.0.181',
         '0',
-        undef,
     ],
     tls_pri => [
         'gnutls_priority',
@@ -1921,7 +1841,6 @@ sub new_winpos_page() {
         'char,0,256,32',
         '3.9.0.181',
         '0',
-        undef,
     ],
 );
 
@@ -1939,52 +1858,242 @@ sub new_account_subpage($) {
 sub new_accounts_page() {
     my $accbook = Gtk2::Notebook->new;
     $accbook->set_tab_pos ('right');
-    foreach (keys %ACPREFS) {
+    my @akeys = sort {
+        $ACPREFS{$a}{'account_name'} cmp $ACPREFS{$b}{'account_name'}
+    } keys %ACPREFS;
+    foreach (@akeys) {
         my $name = $ACPREFS{$_}{'account_name'};
-        $accbook->append_page (new_account_subpage ($_), $name);
+        my $isdef = ($ACPREFS{$_}{'is_default'} eq '1');
+        my $page = new_account_subpage ($_);
+        $accbook->append_page ($page, $isdef? '<b>' . $name . '</b>': $name);
+        if ($isdef) {
+            my $label = $accbook->get_tab_label ($page);
+            $label->set_use_markup (TRUE);
+        }
     }
     return $accbook;
 }
 
+%pr::plu = ( # plugins hidden preferences
+    # att_remover
+    arm_winw => [
+        'win_width',
+        $xl::s{l_win_w},
+        $xl::s{h_win_w},
+        'int,0,3000', # 0 pixels - 3000 pixels
+        '3.9.0.74',
+        '-1',
+        'AttRemover',
+    ],
+    arm_winh => [
+        'win_height',
+        $xl::s{l_win_h},
+        $xl::s{h_win_h},
+        'int,0,3000', # 0 pixels - 3000 pixels
+        '3.9.0.74',
+        '-1',
+        'AttRemover',
+    ],
+    # GPG
+    gpg_alimit => [
+        'autocompletion_limit',
+        $xl::s{l_plu_gpg_alimit},
+        $xl::s{h_plu_gpg_alimit},
+        'int,0,100',
+        '3.12.0.75',
+        '0',
+        'GPG',
+    ],
+    # managesieve
+    msv_winw => [
+        'manager_win_width',
+        $xl::s{l_win_w},
+        $xl::s{h_win_w},
+        'int,0,3000', # 0 pixels - 3000 pixels
+        '3.11.1.210',
+        '-1',
+        'ManageSieve',
+    ],
+    msv_winh => [
+        'manager_win_height',
+        $xl::s{l_win_h},
+        $xl::s{h_win_h},
+        'int,0,3000', # 0 pixels - 3000 pixels
+        '3.11.1.210',
+        '-1',
+        'ManageSieve',
+    ],
+    # libravatar
+    lav_burl => [
+        'base_url',
+        $xl::s{l_plu_lav_burl},
+        $xl::s{h_plu_lav_burl},
+        'char,0,1024,32',
+        '3.9.3.32',
+        'http://cdn.libravatar.org/avatar',
+        'Libravatar',
+    ],
+    # perl
+    prl_flvb => [
+        'filter_log_verbosity',
+        $xl::s{l_plu_prl_flvb},
+        $xl::s{h_plu_prl_flvb},
+        '0=l_plu_prl_none;1=l_plu_prl_manual;2=l_plu_prl_action;3=l_plu_prl_match',
+        '3.9.0.75',
+        '2',
+        'PerlPlugin',
+    ],
+);
+
+sub new_plugins_page() {
+    my %frame = ();
+    $frame{'AttRemover'} =
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::plu, 'arm_winw', $PLHPVALUE{'AttRemover'}),
+                          new_text_box_for_int (\%pr::plu, 'arm_winh', $PLHPVALUE{'AttRemover'})),
+                     _('Attachment remover'), 'not-packed');
+    $frame{'GPG'} =
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::plu, 'gpg_alimit', $PLHPVALUE{'GPG'})),
+                     _('GPG'), 'not-packed');
+    $frame{'ManageSieve'} =
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::plu, 'msv_winw', $PLHPVALUE{'ManageSieve'}),
+                          new_text_box_for_int (\%pr::plu, 'msv_winh', $PLHPVALUE{'ManageSieve'})),
+                     _('Sieve manager'), 'not-packed');
+    $frame{'Libravatar'} =
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_nchar (\%pr::plu, 'lav_burl', $PLHPVALUE{'Libravatar'})),
+                     _('Libravatar'), 'not-packed');
+    $frame{'PerlPlugin'} =
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_selection_box_for (\%pr::plu, 'prl_flvb', $PLHPVALUE{'PerlPlugin'})),
+                     _('Perl'), 'not-packed');
+    foreach (@PLUGINS) {
+        $frame{$_}->set_sensitive (defined $PLHPVALUE{$_});
+    }
+    return new_vbox_pack (
+                $frame{'AttRemover'},
+                $frame{'GPG'},
+                $frame{'ManageSieve'},
+                $frame{'Libravatar'},
+                $frame{'PerlPlugin'});
+}
+
+sub new_info_page() {
+    my $t0 = Gtk2::Table->new (7, 2, FALSE);
+    my $v = get_toolkit_versions ();
+    my %labels = (
+        'glib' => 'Perl-GLib',
+        'glib-r' => _('GLib runtime'),
+        'glib-b' => _('GLib built'),
+        'gtk2' => 'Perl-GTK2',
+        'gtk2-r' => _('GTK2 runtime'),
+        'gtk2-b' => _('GTK2 built'),
+    );
+    my $row = 0;
+    foreach (sort keys %$v) {
+        if (defined $v->{$_}) {
+            my $label = Gtk2::Label->new ($labels{$_});
+            my $value = Gtk2::Label->new ('<b>' . $v->{$_} . '</b>');
+            $label->set_alignment (0, 0.5);
+            $value->set_alignment (0, 0.5);
+            $value->set_use_markup (TRUE);
+            $t0->attach ($label, 0, 1, $row, $row + 1, 'fill', 'shrink', 8, 6);
+            $t0->attach ($value, 1, 2, $row, $row + 1, 'fill', 'shrink', 8, 6);
+            ++$row;
+        }
+    }
+    my $t1 = Gtk2::Table->new (2, 2, FALSE);
+    my @lbl = map { $_->set_alignment (0, 0.5); $_ } (
+        Gtk2::Label->new (_('Binary')),
+        Gtk2::Label->new (_('Configuration'))
+    );
+    my $cfgv = $CONFIGDATA->{'Common'}{'config_version'};
+    $cfgv //= '';
+    my @val = map { $_->set_alignment (0, 0.5); $_->set_use_markup (TRUE); $_ } (
+        Gtk2::Label->new ('<b>' . $CLAWSV . '</b>'),
+        Gtk2::Label->new ('<b>' . $cfgv . '</b>')
+    );
+    for (my $i = 0; $i <= $#lbl; ++$i) {
+        $t1->attach ($lbl[$i], 0, 1, $i, $i + 1, 'fill', 'shrink', 8, 6);
+        $t1->attach ($val[$i], 1, 2, $i, $i + 1, 'fill', 'shrink', 8, 6);
+    }
+    return new_vbox_pack (
+                new_subpage_frame ($t0, _('Library versions'), 'not-packed'),
+                new_subpage_frame ($t1, _('Claws Mail versions'), 'not-packed'));
+}
+
 # version info
+sub get_toolkit_versions {
+    my %versions = ();
+    $versions{'glib'} = $Glib::VERSION;
+    # version info stuff appeared in 1.040
+    if ($Glib::VERSION >= 1.040) {
+        $versions{'glib-b'} = join('.', Glib->GET_VERSION_INFO);
+        $versions{'glib-r'} = join('.',
+            &Glib::major_version, &Glib::minor_version, &Glib::micro_version);
+    }
+    $versions{'gtk2'} = $Gtk2::VERSION;
+    if ($Gtk2::VERSION >= 1.040) {
+        $versions{'gtk2-b'} = join('.', Gtk2->GET_VERSION_INFO);
+        $versions{'gtk2-r'} = join('.',
+            &Gtk2::major_version, &Gtk2::minor_version, &Gtk2::micro_version);
+    }
+    return \%versions;
+}
+
 sub print_version() {
     print $xl::s{about_title} . "\n";
     print $xl::s{about_version} . " $VERSION\n";
-    print "Perl-GLib " . $Glib::VERSION;
-    # version info stuff appeared in 1.040
-    if ($Glib::VERSION >= 1.040) {
-        print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
-              . _(", running with ") . join(".", &Glib::major_version,
-              &Glib::minor_version, &Glib::micro_version);
+    my $v = get_toolkit_versions ();
+    if ($v->{'glib-b'}) {
+        print _("Perl-GLib version {glibv}, built for {glibb}, running with {glibr}.",
+                glibv => $v->{'glib'},
+                glibb => $v->{'glib-b'},
+                glibr => $v->{'glib-r'});
+    } else {
+        print _("Perl-GLib version {glibv}.", glibv => $v->{'glib'});
     }
     print "\n";
-    print "Perl-GTK2 " . $Gtk2::VERSION;
-    if ($Gtk2::VERSION >= 1.040) {
-        print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
-              . _(", running with ") . join(".", &Gtk2::major_version,
-              &Gtk2::minor_version, &Gtk2::micro_version);
+    if ($v->{'gtk2-b'}) {
+        print _("Perl-GTK2 version {gtkv}, built for {gtkb}, running with {gtkr}.",
+                gtkv => $v->{'gtk2'},
+                gtkb => $v->{'gtk2-b'},
+                gtkr => $v->{'gtk2-r'});
+    } else {
+        print _("Perl-GTK2 version {gtkv}.", gtkv => $v->{'gtk2'});
     }
     print "\n";
     my $clawsver = ($CLAWSV eq "") ?
-                _("was not found!") :
-                (_("returned version ") . $CLAWSV);
-    print "Claws Mail " . $clawsver . "\n";
+                _("Claws Mail was not found!") :
+                _("Claws Mail returned version {cmv}.", cmv => $CLAWSV);
+    print $clawsver . "\n";
 }
 
 # the command line help
 sub print_help() {
-    my $line = '-' x length ($xl::s{about_title}) . "\n";
-    print $line;
-    print $xl::s{about_title} . "\n";
-    print $line;
-    print _("Syntax:\n");
-    print _("  clawsker [options]\n");
-    print _("Options:\n");
-    print _("  -h|--help                        Prints this help screen.\n");
-    print _("  -v|--version                     Prints version infos.\n");
-    print _("  -b|--verbose                     More messages on standard output.\n");
-    print _("  -a|--alternate-config-dir <dir>  Uses <dir> as Claws Mail config dir.\n");
-    print _("  -c|--clawsrc <file>              Uses <file> as full resource name.\n");
+    my $line = '-' x length ($xl::s{about_title});
+    say $line;
+    say $xl::s{about_title};
+    say $line;
+    my @help = (
+        _("Syntax:"),
+        _("  clawsker [options]"),
+        _("Options:"),
+        _("  -a|--alternate-config-dir <dir>  Uses <dir> as Claws Mail configuration."),
+        _("  -b|--verbose                     More messages on standard output."),
+        _("  -c|--clawsrc <file>              Uses <file> as full resource name."),
+        _("  -h|--help                        Prints this help screen and exits."),
+        _("  -r|--read-only                   Disables writing changes to disk."),
+        _("  -v|--version                     Prints version information and exits.")
+    );
+    foreach (@help) { say $_ }
 }
 
 sub parse_command_line {
@@ -2041,33 +2150,104 @@ sub init_hidden_preferences {
             $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
         }
     }
-    return TRUE;
-}
-
-sub init_ac_hidden_preferences {
     foreach my $akey (keys %ACPREFS) {
         foreach my $key (keys %pr::acc) {
             my $pname = $pr::acc{$key}[NAME];
             $ACHPVALUE{$akey}{$pname} = $ACPREFS{$akey}{$pname};
         }
     }
+    foreach my $key (keys %pr::plu) {
+        my $plugin = $pr::plu{$key}[PLUGIN];
+        my $pname = $pr::plu{$key}[NAME];
+        if (defined $PLPREFS{$plugin}) {
+            $PLHPVALUE{$plugin}{$pname} = $PLPREFS{$plugin}{$pname};
+        }
+    }
     return TRUE;
 }
 
+# generic load/save resource files
+sub load_resource {
+    my $rc = shift;
+    my %data = ();
+    my %meta = ();
+    my $line = 0;
+    open (RCF, '<:encoding(utf8)', $rc)
+        or die _("Error: opening '{file}' for reading", file => $rc) . ": $!\n";
+    my $section = '_'; # default unnamed section
+    while (<RCF>) {
+        chomp;
+        ++$line;
+        next if (/^\s*$/);
+        if (/^\[([^\]]+)\]$/) { # new section
+            $section = $1;
+            die _("Error: duplicate section '{sect}' in resource file '{file}'\n",
+                sect => $section, file => $rc) if ($data{$section});
+            $data{$section} = {};
+            $meta{$section}{'#'} = $line;
+        }
+        elsif (/^([0-9a-z_]+)=(.*)$/) { # key=value
+            $data{$section}{$1} = $2;
+            $meta{$section}{$1} = $line;
+        }
+        elsif (/^(.*)$/) { # lone value
+            push (@{$data{$section}{'_'}}, $1);
+        }
+    }
+    close (RCF);
+    return (\%data, \%meta);
+}
+
+sub save_resource {
+    my ($rc, $data, $meta) = @_;
+    open (RCF, '>:utf8', $rc)
+        or die _("Error: opening '{file}' for writing", file => $rc) . ": $!\n";
+    my @sections = keys %$data;
+    if (defined $meta) {
+        @sections = sort {
+            $meta->{$a}{'#'} <=> $meta->{$b}{'#'}
+        } @sections
+    }
+    foreach my $section (@sections) {
+        say RCF "[$section]";
+        if (ref ($data->{$section}{'_'}) eq 'ARRAY') {
+            foreach my $val (@{$data->{$section}{'_'}}) {
+                say RCF $val;
+            }
+        } else {
+            my @keys = keys %{$data->{$section}};
+            if (defined $meta) {
+                @keys = sort {
+                    $meta->{$section}{$a} <=> $meta->{$section}{$b}
+                } @keys
+            }
+            foreach my $key (@keys) {
+                my $val = $data->{$section}{$key};
+                say RCF "$key=$val";
+            }
+        }
+        say RCF "";
+    }
+    close (RCF);
+}
+
 # load current status from disc
-sub load_preferences {
+sub load_rc_preferences {
     my $rc = get_rc_filename ();
     log_message ("Loading preferences from $rc\n");
     return FALSE unless check_rc_file ($rc);
-    return FALSE unless check_claws_not_running ();
-    open (RCF, "<$rc");
-    while (<RCF>) {
-        chomp;
-        if (/^([8a-z_]+)=(.*)$/) {
-            $PREFS{$1} = decode('UTF-8', $2);
+    ($CONFIGDATA, $CONFIGMETA) = load_resource ($rc);
+    foreach (keys %{$CONFIGDATA->{'Common'}}) {
+        $PREFS{$_} = $CONFIGDATA->{'Common'}{$_};
+    }
+    foreach my $plugin (@PLUGINS) {
+        if (defined $CONFIGDATA->{$plugin}) {
+            push (@AVPLUGINS, $plugin);
+            foreach (keys %{$CONFIGDATA->{$plugin}}) {
+                $PLPREFS{$plugin}{$_} = $CONFIGDATA->{$plugin}{$_};
+            }
         }
     }
-    close (RCF);
     return TRUE;
 }
 
@@ -2075,23 +2255,22 @@ sub load_ac_preferences {
     my $rc = get_ac_rc_filename ();
     log_message ("Loading account preferences from $rc\n");
     return FALSE unless check_rc_file ($rc);
-    return FALSE unless check_claws_not_running ();
-    open (RCF, "<$rc");
-    my $akey;
-    while (<RCF>) {
-        chomp;
-        if (/^\[Account: (\d+)\]$/) {
-          $akey = $1;
-          next;
-        }
-        if (/^([8a-z_]+)=(.*)$/) {
-            $ACPREFS{$akey}{$1} = decode('UTF-8', $2);
+    ($ACCOUNTDATA, $ACCOUNTMETA) = load_resource ($rc);
+    foreach my $asect (keys %$ACCOUNTDATA) {
+        if ($asect =~ /^Account: (\d+)$/) {
+            foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+                $ACPREFS{$1}{$_} = $ACCOUNTDATA->{$asect}{$_};
+            }
         }
     }
-    close (RCF);
     return TRUE;
 }
 
+sub load_preferences {
+    return FALSE unless check_claws_not_running ();
+    return (load_rc_preferences () and load_ac_preferences ());
+}
+
 # save current preferences to disc
 sub save_preferences {
     my $rc = get_rc_filename ();
@@ -2100,24 +2279,19 @@ sub save_preferences {
     return FALSE unless check_claws_not_running ();
     my $rcbak = "$rc.backup";
     rename ($rc, $rcbak);
-    open (RCF, ">$rc");
-    open (RCB, "<$rcbak");
-    while (<RCB>) {
-        chomp;
-        if (/^([8a-z_]+)=(.*)$/) {
-            if (defined($HPVALUE{$1})) {
-                print RCF $1 . "=" . $HPVALUE{$1} . "\n";
-            }
-            else {
-                print RCF $_ . "\n";
-            }
+    foreach (keys %PREFS) {
+        if (defined $HPVALUE{$_}) {
+            $CONFIGDATA->{'Common'}{$_} = $HPVALUE{$_};
         }
-        else {
-            print RCF $_ . "\n";
+    }
+    foreach my $plugin (@AVPLUGINS) {
+        foreach (keys %{$CONFIGDATA->{$plugin}}) {
+            if (defined $PLHPVALUE{$plugin}{$_}) {
+                $CONFIGDATA->{$plugin}{$_} = $PLHPVALUE{$plugin}{$_};
+            }
         }
     }
-    close (RCB);
-    close (RCF);
+    save_resource ($rc, $CONFIGDATA, $CONFIGMETA);
     return TRUE;
 }
 
@@ -2128,30 +2302,16 @@ sub save_ac_preferences {
     return FALSE unless check_claws_not_running ();
     my $rcbak = "$rc.backup";
     rename ($rc, $rcbak);
-    open (RCF, ">$rc");
-    open (RCB, "<$rcbak");
-    my $akey;
-    while (<RCB>) {
-        chomp;
-        if (/^\[Account: (\d+)\]$/) {
-          $akey = $1;
-          print RCF $_ . "\n";
-          next;
-        }
-        if (/^([8a-z_]+)=(.*)$/) {
-            if (defined($ACHPVALUE{$akey}{$1})) {
-                print RCF $1 . "=" . $ACHPVALUE{$akey}{$1} . "\n";
-            }
-            else {
-                print RCF $_ . "\n";
+    foreach my $asect (keys %$ACCOUNTDATA) {
+        if ($asect =~ /^Account: (\d+)$/) {
+            foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+                if (defined $ACHPVALUE{$1}{$_}) {
+                    $ACCOUNTDATA->{$asect}{$_} = $ACHPVALUE{$1}{$_};
+                }
             }
         }
-        else {
-            print RCF $_ . "\n";
-        }
     }
-    close (RCB);
-    close (RCF);
+    save_resource ($rc, $ACCOUNTDATA, $ACCOUNTMETA);
     return TRUE;
 }
 
@@ -2165,6 +2325,8 @@ sub new_notebook {
     $nb->append_page (new_other_page (), $xl::s{tab_other});
     $nb->append_page (new_winpos_page (), $xl::s{tab_winpos});
     $nb->append_page (new_accounts_page (), $xl::s{tab_accounts});
+    $nb->append_page (new_plugins_page (), $xl::s{tab_plugins});
+    $nb->append_page (new_info_page (), $xl::s{tab_info});
 
     return $nb;
 }
@@ -2202,6 +2364,13 @@ along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.";
                     . "<span size=\"large\">$lic</span>\n\n"
                     . "<span size=\"small\">$license</span>");
     $dialog->set_title ($xl::s{about});
+    if (Gtk2->CHECK_VERSION (2, 10, 0)) {
+        my @icons = get_app_icons ();
+        my $image = Gtk2::Image->new_from_pixbuf ($icons[-1]);
+        $image->show ();
+        $image->set_alignment (0, 0);
+        $dialog->set_image ($image);
+    }
     #
     return $dialog;
 }
@@ -2234,17 +2403,24 @@ sub new_button_box {
 }
 
 sub get_app_icons {
-    my $dir = $DATADIR . '/icons/hicolor';
-    my @names = map {
-      join ('/', ($dir, , $_ . 'x' . $_, 'apps', $NAME . '.png'))
-    } (64, 128);
-    my @icons = ();
+    return @APPICONS if (@APPICONS);
+    my @names;
+    if (-d $DATADIR) { # installed
+        my $dir = $DATADIR . '/icons/hicolor';
+        @names = map {
+            join ('/', ($dir, $_ . 'x' . $_, 'apps', $NAME . '.png'))
+        } (48, 64, 128);
+    } else { # unpacked tarball or git clone
+        @names = map {
+            join ('/', ('./icons', $NAME . '-' . $_ . '.png'));
+        } (48, 64, 128);
+    }
     foreach (@names) {
         my $icon = undef;
         $icon = Gtk2::Gdk::Pixbuf->new_from_file($_) if (-f $_);
-        push @icons, $icon if ($icon);
+        push @APPICONS, $icon if ($icon);
     }
-    return @icons;
+    return @APPICONS;
 }
 
 # initialise
@@ -2252,9 +2428,7 @@ exit unless parse_command_line ();
 Gtk2->init;
 $main_window = Gtk2::Window->new ('toplevel');
 exit unless load_preferences ();
-exit unless load_ac_preferences ();
 exit unless init_hidden_preferences ();
-exit unless init_ac_hidden_preferences ();
 # create main GUI
 my $box = Gtk2::VBox->new (FALSE, 5);
 $box->set_border_width(3);