Do not fail comparing with empty versions
[clawsker.git] / clawsker
index 649bcf13d5aa667f6825a219a5053a91028ee50e..6594bd73cb16469132eddc7563b8dd4d281aed4c 100755 (executable)
--- a/clawsker
+++ b/clawsker
@@ -1,20 +1,38 @@
 #!/usr/bin/perl -w
 #
 # Clawsker :: A Claws Mail Tweaker
+# Copyright 2007-2016 Ricardo Mones <ricardo@mones.org>
 #
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# See COPYING file for license details.
+# See AUTHORS file for a complete list of contributors.
+#
+
+binmode STDOUT, ":encoding(utf8)";
+
+use 5.010_000;
 use strict;
-use encoding 'utf8';
+use utf8;
+use version 0.77;
 use Glib qw(TRUE FALSE);
-use Gtk2 -init;
+use Gtk2;
 use POSIX qw(setlocale);
 use Locale::gettext;
 use Encode;
+use Digest::MD5 qw(md5_hex);
+use Getopt::Long;
 
 my $NAME = 'clawsker';
 my $PREFIX = '@PREFIX@';
 my $LIBDIR = '@LIBDIR@';
+my $DATADIR = '@DATADIR@';
 my $VERSION = '@VERSION@';
 my $VERBOSE = FALSE;
+my $READONLY = FALSE;
 my $CLAWSV = undef;
 my $main_window = undef;
 
@@ -52,6 +70,9 @@ sub _ {
     tab_gui => _('GUI'),
     tab_other => _('Other'),
     tab_winpos => _('Windows'),
+    tab_accounts => _('Accounts'),
+    tab_plugins => _('Plugins'),
+    tab_info => _('Info'),
 
     ab_frame => _('Addressbook'),
     mem_frame => _('Memory'),
@@ -60,6 +81,7 @@ sub _ {
     dnd_frame => _('Drag \'n\' drop'),
     ssl_frame => _('Secure Sockets Layer'),
     msgs_frame => _('Messages'),
+    swc_frame => _('Completion'),
     stripes_frame => _('Coloured stripes'),
     sbar_frame => _('Scroll bars'),
     mlist_frame => _('Message List'),
@@ -67,6 +89,9 @@ sub _ {
     compo_frame => _('Compose window'),
     netm_frame => _('NetworkManager'),
     diff_frame => _('Viewing patches'),
+    mpass_frame => _('Master passphrase'),
+    compose_frame => _('Compose window'),
+    qs_frame => _('Quick search'),
 
     l_oth_use_dlg => _('Use detached address book edit dialogue'),
     h_oth_use_dlg => _('If true use a separate dialogue to edit a person\'s details. Otherwise will use a form embedded in the address book\'s main window.'),
@@ -76,10 +101,12 @@ sub _ {
     h_oth_min_time => _('The minimum time in minutes to keep a cache in memory. Caches more recent than this time will not be freed, even if the memory usage is too high.'),
     l_oth_use_netm => _('Use NetworkManager'),
     h_oth_use_netm => _('Use NetworkManager to switch offline automatically.'),
-    
+    l_oth_mp_rounds => _('Rounds for PBKDF2 function'),
+    h_oth_mp_rounds => _('Specify the number of iterations the key derivation function will be applied on master passphrase computation. Does not modify currently stored passphrase, only master passphrases computed after changing this value are affected.'),
+
     l_gui_b_unread => _('Show unread messages with bold font'),
     h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
-    l_gui_no_markup => _('Don\'t use markup in compose window'),
+    l_gui_no_markup => _('Don\'t use markup'),
     h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
     l_gui_dot_lines => _('Use dotted lines in tree view components'),
     h_gui_dot_lines => _('Use the old dotted line look in the main window tree views (Folder, Message and other lists) instead of the modern lineless look.'),
@@ -93,7 +120,7 @@ sub _ {
     l_gui_v_scroll_auto => _('Automatic'),
     l_gui_v_scroll_hide => _('Hide always'),
     l_gui_from_show => _('From column displays'),
-    h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both'),
+    h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both.'),
     l_gui_from_show_name => _('Name only'),
     l_gui_from_show_addr => _('Address only'),
     l_gui_from_show_both => _('Both name and address'),
@@ -109,12 +136,20 @@ sub _ {
     h_gui_strip_sum => _('Enable alternately coloured lines in Message List and Folder List.'),
     l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
     h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
-    l_gui_margin_co => _('Show compose margin'),
+    l_gui_margin_co => _('Show margin'),
     h_gui_margin_co => _('Shows a small margin in the Compose View.'),
     l_gui_mview_date => _('Don\'t display localized date'),
-    h_gui_mview_date => _('Toggles localization of date format in Message View'),
+    h_gui_mview_date => _('Toggles localization of date format in Message View.'),
     l_gui_zero_char => _('Zero replacement character'),
-    h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List'),
+    h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List.'),
+    l_gui_type_any => _('Editable headers'),
+    h_gui_type_any => _('Allows to manually type any value in Compose Window header entries or just select from the available choices in the associated dropdown list.'),
+    l_gui_warn_send_multi => _('Warn when sending to more than'),
+    h_gui_warn_send_multi => _('Warn when sending to multiple recipients.'),
+    l_gui_warn_send_multi_threshold => _('recipients'),
+    h_gui_warn_send_multi_threshold => _('Warn when sending to multiple recipients.'),
+    l_gui_next_del => _('Select next message on delete'),
+    h_gui_next_del => _('When deleting a message, toggles between selecting the next one (newer message) or the previous one (older message).'),
 
     l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
     h_beh_hover_t => _('Time in milliseconds that will cause a folder tree to expand when the mouse cursor is held over it during drag and drop.'),
@@ -137,11 +172,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.'),
@@ -153,15 +194,34 @@ sub _ {
     h_col_log_msg => _('Colour for messages in log window.'),
     l_col_log_out => _('Client messages'),
     h_col_log_out => _('Colour for messages sent to servers in log window.'),
-    l_col_log_warn => _('Warnings'),
+    l_col_log_warn => _('Warning messages'),
     h_col_log_warn => _('Colour for warning messages in log window.'),
 
+    l_col_tags_bg => _('Tags background'),
+    h_col_tags_bg => _('Background colour for tags in message view.'),
+    l_col_tags_text => _('Tags text'),
+    h_col_tags_text => _('Text colour for tags in message view.'),
+
+    l_col_default_header_bg => _('Default headers background'),
+    h_col_default_header_bg => _('Background colour for default headers in compose window.'),
+    l_col_default_header_text => _('Default headers text'),
+    h_col_default_header_text => _('Text colour for default headers in compose window.'),
+
+    l_col_qs_active_bg => _('Active quick search background'),
+    h_col_qs_active_bg => _('Background colour for active quick search.'),
+    l_col_qs_active_text => _('Active quick search text'),
+    h_col_qs_active_text => _('Text colour for active quick search.'),
+    l_col_qs_error_bg => _('Quick search error background'),
+    h_col_qs_error_bg => _('Background colour for quick search error.'),
+    l_col_qs_error_text => _('Quick search error text'),
+    h_col_qs_error_text => _('Text colour for quick search error.'),
+
     l_col_diff_add => _('Added lines'),
     h_col_diff_add => _('Colour for added lines in patches.'),
     l_col_diff_del => _('Deleted lines'),
     h_col_diff_del => _('Colour for deleted lines in patches.'),
     l_col_diff_hunk => _('Hunk lines'),
-    h_col_diff_hunk => _('Color for hunk headers in patches.'),
+    h_col_diff_hunk => _('Colour for hunk headers in patches.'),
 
     l_win_x => _('X position'),
     h_win_x => _('X coordinate for window\'s top-left corner.'),
@@ -177,68 +237,76 @@ sub _ {
     l_win_main_fs => _('Full-screen'),
     h_win_main_fs => _('Changes full screen status.'),
 
-    e_error => _('Error: '),
-    e_noclawsrc => _('resource file for Claws Mail was not found.'),
-    e_running => _('seems Claws Mail is currently running, close it first.'),
-    e_requireddir => _('option requires a directory name.'),
-    e_requiredfile => _('option requires a file name.'),
-    e_notadir => _('specified name is not a directory or does not exist.'),
-    e_notafile => _('specified name is not a file or does not exist.'),
+    l_acc_gtls_set => _('Use custom GnuTLS priority'),
+    h_acc_gtls_set => _('Enables using user provided GnuTLS priority string.'),
+    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.'),
+
+    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
 use constant LABEL => 1; # the label on the GUI
 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 Claws Mail version the feature exists
+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;
 
 # version functions
 
-sub version_greater_or_equal() {
+sub version_greater_or_equal {
     my ($version, $refvers) = @_;
-    my @version = split (/\./, $version);
-    my @refvers = split (/\./, $refvers);
-    while ($#version < $#refvers) {
-        push (@version, '0');
-    }
-    my $idx = 0;
-    while (($idx <= $#refvers) 
-            and (int ($version[$idx]) == int ($refvers[$idx]))) {
-        ++$idx;
-    }
-    return TRUE if (($idx > $#refvers)
-        or (int ($version[$idx]) >= int ($refvers[$idx])));
+    return TRUE if (length($version) == 0 and length($refvers) >= 0);
+    return FALSE if (length($version) >= 0 and length($refvers) == 0);
+    return TRUE if (version->parse($version) >= version->parse($refvers));
     return FALSE;
 }
 
-sub get_claws_version() {
-    my @cmbin = (
-        'claws-mail',
-    );
-    my $res = "";
-    foreach my $bin (@cmbin) {
-        $_ = qx/which $bin/;
-        chomp;
-        last if ($_ ne "");
-    }
+sub get_claws_version {
+    $_ = qx/which claws-mail/;
+    chomp;
     return "" unless ($_); # not installed
+    my $res = "";
     $_ = qx/$_ -v/;
     chomp;
     my @fver = split (/ /);
@@ -246,7 +314,7 @@ sub get_claws_version() {
     my @ver = split (/\./, $fver[3]);
     $res .= "$ver[0].";
     $res .= "$ver[1].";
-    if ($ver[2] =~ /(\d+)cvs(\d+)/) {
+    if ($ver[2] =~ /(\d+)git(\d+)/) {
         $res .= "$1.$2";
     }
     else {
@@ -282,8 +350,8 @@ sub handle_string_value {
 }
 
 sub handle_nchar_value {
-    my ($widget, $event, $dataref, $minlen) = @_;
-    $_ = substr ($widget->get_text (), 0, $minlen);
+    my ($widget, $event, $dataref, $minlen, $maxlen) = @_;
+    $_ = substr ($widget->get_text (), 0, $maxlen);
     $widget->set_text ($_);
     $$dataref = $_;
 }
@@ -294,7 +362,7 @@ sub gdk_color_from_str {
     $_ = uc ($str);
     if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
         $rr = hex($1) * 256;
-        $gg = hex($2) * 256; 
+        $gg = hex($2) * 256;
         $bb = hex($3) * 256;
     }
     my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
@@ -313,7 +381,7 @@ sub str_from_gdk_color {
 sub handle_color_value {
     my ($widget, $event, $dataref) = @_;
     my $newcol = $widget->get_color;
-    $$dataref = &str_from_gdk_color ($newcol);
+    $$dataref = str_from_gdk_color ($newcol);
 }
 
 sub handle_selection_value {
@@ -325,6 +393,10 @@ sub get_rc_filename {
     return $CONFIGDIR . $CONFIGRC;
 }
 
+sub get_ac_rc_filename {
+    return $CONFIGDIR . $ACCOUNTRC;
+}
+
 sub set_rc_filename {
     my ($fullname) = @_;
     my @parts = split ('/', $fullname);
@@ -347,27 +419,36 @@ sub error_dialog {
     my ($emsg) = @_;
     my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
     my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
-    $errordlg->set_title (_('Error message'));
+    $errordlg->set_title (_('Clawsker error'));
     $errordlg->run;
     $errordlg->destroy;
 }
 
-sub check_claws_not_running() {
-    my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
-    $socket .= "claws-mail-$<";
-    -S $socket and do {
-        my $emsg = "$xl::s{e_error}$xl::s{e_running}";
-        log_message ($emsg);
-        error_dialog ($emsg);
-        return FALSE;
-     };
-     return TRUE;
+sub claws_is_running {
+    my $emsg = _('Error: seems Claws Mail is currently running, close it first.');
+    log_message ($emsg);
+    error_dialog ($emsg);
+    return FALSE;
 }
 
-sub check_rc_file() {
+sub check_claws_not_running {
+    return TRUE if $READONLY;
+    my $tmpdir = (defined $ENV{TMPDIR})? $ENV{TMPDIR}: '/tmp';
+    $tmpdir = '/tmp' if ($tmpdir eq '');
+    my $lockdir = "$tmpdir/claws-mail-$<";
+    -d $lockdir and do {
+        $_ = $CONFIGDIR;
+        s/\/$//;
+        my $socket = "$lockdir/" . md5_hex ($_);
+        -S $socket and return claws_is_running ();
+    };
+    return TRUE;
+}
+
+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;
@@ -375,129 +456,183 @@ sub check_rc_file() {
     return TRUE;
 }
 
-sub set_widget_hint() {
+sub set_widget_hint {
     if ($SHOWHINTS) {
-        my ($wdgt, $hint) = @_;    
+        my ($wdgt, $hint) = @_;
         $wdgt->set_tooltip_text ($hint);
         $wdgt->set_has_tooltip (TRUE);
     }
 }
 
-sub set_widget_sens() {
-    my ($wdgt, $minver) = @_;
-    $wdgt->set_sensitive (&version_greater_or_equal ($CLAWSV, $minver));
+sub set_widget_sens {
+    my ($wdgt, $versions) = @_;
+    my @ver = split(/,/, $versions);
+    if ($#ver == 1) {
+      $wdgt->set_sensitive (
+        version_greater_or_equal ($CLAWSV, $ver[0])
+        and version_greater_or_equal ($ver[1], $CLAWSV)
+      );
+    } else {
+        $wdgt->set_sensitive (version_greater_or_equal ($CLAWSV, $ver[0]));
+    }
 }
 
-# graphic element creation 
+# 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) = @_;
+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);
-    $$hash{$key}[GUI] = $cb;
-    if (defined ($HPVALUE{$name})) {
-        $cb->set_active ($HPVALUE{$name} eq '1');
-    }
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
+    $cb->set_active ($value eq '1');
     $cb->signal_connect (clicked => sub {
             my ($w, $e) = @_;
-            &handle_bool_value($w, $e, \$HPVALUE{$name});
+            handle_bool_value ($w, $e, \$$vhash{$name});
         });
-    &set_widget_hint ($cb, $$hash{$key}[DESC]);
-    &set_widget_sens ($cb, $$hash{$key}[CMVER]);
-    $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
+    set_widget_hint ($cb, $$hash{$key}[DESC]);
+    set_widget_sens ($cb, $$hash{$key}[CMVER]);
     #
-    return $hbox;
+    return new_hbox_spaced_pack ($cb);
 }
 
-sub new_text_box_for_int {
-    my ($hash, $key) = @_;
+sub new_text_box_for_int($$$) {
+    my ($hash, $key, $vhash) = @_;
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
     my @type = split (/,/, $$hash{$key}[TYPE]);
-    push (@type, 0), push (@type, 10000) unless ($#type > 0); 
+    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);
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
     $gentry->set_numeric (TRUE);
-    $gentry->set_value ($HPVALUE{$name});
-    $$hash{$key}[GUI] = $gentry;
+    $gentry->set_value ($value);
     $gentry->signal_connect('value-changed' => sub {
             my ($w, $e) = @_;
-            &handle_int_value($w, $e, \$HPVALUE{$name});
+            handle_int_value ($w, $e, \$$vhash{$name});
         });
-    &set_widget_hint ($gentry, $$hash{$key}[DESC]);
-    &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
+    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 check_button_and_text_box_update_sens($$$) {
+    my ($cb, $gentry, $glabel) = @_;
+    $gentry->set_sensitive ($cb->get_active);
+    $glabel->set_sensitive ($cb->get_active);
 }
 
-sub new_text_box_for_nchar {
-    my ($hash, $key) = @_;
+sub new_check_button_and_text_box_for_int($$$$) {
+    my ($hash, $key, $key2, $vhash) = @_;
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
-    my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
+    #
+    my $cb = Gtk2::CheckButton->new ($label);
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
+    $cb->set_active ($value eq '1');
+    set_widget_hint ($cb, $$hash{$key}[DESC]);
+    set_widget_sens ($cb, $$hash{$key}[CMVER]);
+       #
+    my $name2 = $$hash{$key2}[NAME];
+    my $label2 = $$hash{$key2}[LABEL];
+    my @type = split (/,/, $$hash{$key2}[TYPE]);
+    push (@type, 0), push (@type, 10000) unless ($#type > 0);
+    #
+    my $pagei = int (($type[2] - $type[1]) / 10);
+    my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
+    my $value2 = $$vhash{$name2};
+    my $glabel = Gtk2::Label->new ($label2);
+    $value2 //= $$hash{$key2}[CMDEF];
+    $gentry->set_numeric (TRUE);
+    $gentry->set_value ($value2);
+    $gentry->signal_connect('value-changed' => sub {
+            my ($w, $e) = @_;
+            handle_int_value ($w, $e, \$$vhash{$name});
+        });
+    set_widget_hint ($gentry, $$hash{$key2}[DESC]);
+    set_widget_sens ($gentry, $$hash{$key2}[CMVER]);
+       check_button_and_text_box_update_sens($cb, $gentry, $glabel);
+    #
+    $cb->signal_connect ('clicked' => sub {
+                   my ($w, $e) = @_;
+            handle_bool_value ($w, $e, \$$vhash{$name});
+                       check_button_and_text_box_update_sens($w, $gentry, $glabel);
+       });
+       #
+    return new_hbox_spaced_pack ($cb, $gentry, $glabel);
+}
+
+sub new_text_box_for_nchar($$$) {
+    my ($hash, $key, $vhash) = @_;
+    my $name = $$hash{$key}[NAME];
+    my $label = $$hash{$key}[LABEL];
+    my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen,width
     my $glabel = Gtk2::Label->new ($label);
     my $gentry = Gtk2::Entry->new ();
     $gentry->set_max_length($type[2]) if defined ($type[2]);
-    $gentry->set_width_chars(int ($type[2]) + 2) if defined ($type[2]);
-    $gentry->set_text ($HPVALUE{$name});
-    $$hash{$key}[GUI] = $gentry;
+    my $width = $type[3];
+    $width //= $type[2];
+    $gentry->set_width_chars(int ($width) + 2) if defined ($width);
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
+    $gentry->set_text ($value);
     $gentry->signal_connect('key-release-event' => sub {
             my ($w, $e) = @_;
-            &handle_nchar_value($w, $e, \$HPVALUE{$name}, $type[1]);
+            handle_nchar_value ($w, $e, \$$vhash{$name}, $type[1], $type[2]);
         });
-    &set_widget_hint ($gentry, $$hash{$key}[DESC]);
-    &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
+    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 {
-    my ($hash, $key) = @_;
+sub new_color_button_for($$$) {
+    my ($hash, $key, $vhash) = @_;
     my $name = $$hash{$key}[NAME];
     my $label = $$hash{$key}[LABEL];
     #
-    my $col = &gdk_color_from_str ($HPVALUE{$name});
-    my $hbox = Gtk2::HBox->new (FALSE, 5);
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
+    my $col = gdk_color_from_str ($value);
     my $glabel = Gtk2::Label->new ($label);
     my $button = Gtk2::ColorButton->new_with_color ($col);
-    $$hash{$key}[GUI] = $button;
     $button->set_title ($label);
     $button->set_relief ('none');
     $button->signal_connect ('color-set' => sub {
             my ($w, $e) = @_;
-            &handle_color_value($w, $e, \$HPVALUE{$name}); 
+            handle_color_value ($w, $e, \$$vhash{$name});
         });
-    &set_widget_hint ($button, $$hash{$key}[DESC]);
-    &set_widget_sens ($button, $$hash{$key}[CMVER]);
+    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 {
-    my ($hash, $key) = @_;
+sub new_selection_box_for($$$) {
+    my ($hash, $key, $vhash) = @_;
     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;
-    $$hash{$key}[GUI] = $combo;
     my @options = split (';', $$hash{$key}[TYPE]);
     foreach my $opt (@options) {
         my ($index, $textkey) = split ('=', $opt);
@@ -505,84 +640,90 @@ sub new_selection_box_for {
     }
     $combo->signal_connect ('changed' => sub {
             my ($w, $e) = @_;
-            &handle_selection_value($w, $e, \$HPVALUE{$name});
+            handle_selection_value ($w, $e, \$$vhash{$name});
         });
-    $combo->set_active ($HPVALUE{$name});
-    &set_widget_hint ($combo, $$hash{$key}[DESC]);
-    &set_widget_sens ($combo, $$hash{$key}[CMVER]);
+    my $value = $$vhash{$name};
+    $value //= $$hash{$key}[CMDEF];
+    $combo->set_active ($value);
+    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);
+sub new_hbox_pack {
+    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;
-}    
+}
 
-sub new_vbox_pack() {
+sub new_hbox_pack_compact {
+    my $hbox = Gtk2::HBox->new (FALSE);
+    $hbox->set_border_width (0);
+    foreach (@_) {
+        $hbox->pack_start ($_, FALSE, FALSE, 0);
+    }
+    return $hbox;
+}
+
+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;
-}    
+}
 
-sub new_vbox_pack_compact() {
+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;
-}    
+}
 
-sub new_subpage_frame () {
+sub new_subpage_frame {
     my ($box, $title, $notpacked) = @_;
     my $frame = Gtk2::Frame->new ($title);
-    $frame->add ($box);    
-    return &new_vbox_pack ($frame) unless defined ($notpacked);
+    $frame->add ($box);
+    return new_vbox_pack ($frame) unless defined ($notpacked);
     return $frame;
 }
 
 # preference maps and corresponding page creation subs
 
 %pr::oth = ( # other preferences
-    use_dlg => [ 
+    use_dlg => [
         'addressbook_use_editaddress_dialog',
         $xl::s{l_oth_use_dlg},
         $xl::s{h_oth_use_dlg},
         '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',
@@ -591,82 +732,87 @@ sub new_subpage_frame () {
         'bool',
         '3.3.1',
         '1',
-        undef,
+    ],
+    mp_rounds => [
+        'master_passphrase_pbkdf2_rounds',
+        $xl::s{l_oth_mp_rounds},
+        $xl::s{h_oth_mp_rounds},
+        'int,50000,1000000',
+        '3.13.2.110',
+        '50000',
     ],
 );
 
 sub new_other_page() {
-    return &new_vbox_pack (
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_check_button_for(\%pr::oth, 'use_dlg')),
+    return new_vbox_pack (
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_check_button_for(\%pr::oth, 'use_dlg', \%HPVALUE)),
                    $xl::s{ab_frame}, 'not-packed'),
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_text_box_for_int(\%pr::oth, 'max_use'),
-                       &new_text_box_for_int(\%pr::oth, 'min_time')),
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_text_box_for_int(\%pr::oth, 'max_use', \%HPVALUE),
+                       new_text_box_for_int(\%pr::oth, 'min_time', \%HPVALUE)),
                    $xl::s{mem_frame}, 'not-packed'),
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_check_button_for(\%pr::oth, 'use_netm')),
-                   $xl::s{netm_frame}, 'not-packed')
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_check_button_for(\%pr::oth, 'use_netm', \%HPVALUE)),
+                   $xl::s{netm_frame}, 'not-packed'),
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_text_box_for_int(\%pr::oth, 'mp_rounds', \%HPVALUE)),
+                   $xl::s{mpass_frame}, 'not-packed')
            );
 }
 
 %pr::gui = ( # gui bells and whistles
-    b_unread => [ 
+    b_unread => [
         'bold_unread',
         $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',
+        '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',
@@ -675,16 +821,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',
@@ -693,7 +837,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     toolbar_d => [
         'toolbar_detachable',
@@ -702,7 +845,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     strip_all => [
         'use_stripes_everywhere',
@@ -711,7 +853,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     strip_sum => [
         'use_stripes_in_summaries',
@@ -720,7 +861,6 @@ sub new_other_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     two_linev => [
         'two_line_vertical',
@@ -729,7 +869,6 @@ sub new_other_page() {
         'bool',
         '3.4.0.7',
         '0',
-        undef,
     ],
     margin_co => [
         'show_compose_margin',
@@ -738,7 +877,6 @@ sub new_other_page() {
         'bool',
         '3.7.6.7',
         '0',
-        undef,
     ],
     mview_date => [
         'msgview_date_format',
@@ -747,7 +885,6 @@ sub new_other_page() {
         'bool',
         '3.7.8.42',
         '0',
-        undef,
     ],
     zero_char => [
         'zero_replacement_char',
@@ -756,7 +893,38 @@ sub new_other_page() {
         'char,1,1',
         '2.8.1.77',
         '0',
-        undef,
+    ],
+    type_any => [
+        'type_any_header',
+        $xl::s{l_gui_type_any},
+        $xl::s{h_gui_type_any},
+        'bool',
+        '3.12.0.44',
+        '0',
+    ],
+    warn_send_multi => [
+        'warn_sending_many_recipients',
+        $xl::s{l_gui_warn_send_multi},
+        $xl::s{l_gui_warn_send_multi},
+        'bool',
+        '3.14.1.125',
+        '0',
+    ],
+    warn_send_multi_threshold => [
+        'warn_sending_many_recipients_num',
+        $xl::s{l_gui_warn_send_multi_threshold},
+        $xl::s{l_gui_warn_send_multi_threshold},
+        'int,1,1000',
+        '3.14.1.125',
+        '2',
+    ],
+    next_del => [
+        'next_on_delete',
+        $xl::s{l_gui_next_del},
+        $xl::s{h_gui_next_del},
+        'bool',
+        '3.13.0.5',
+        '0',
     ],
 );
 
@@ -764,43 +932,46 @@ sub new_gui_page() {
     my $gf = Gtk2::VBox->new (FALSE, 5);
     $gf->set_border_width (PAGE_SPC);
 
-    my $cb_dot_lines = &new_check_button_for (\%pr::gui, 'dot_lines'); 
-    my $cb_toolbar_d = &new_check_button_for (\%pr::gui, 'toolbar_d');
-    my $tb_zero_char = &new_text_box_for_nchar (\%pr::gui, 'zero_char');
+    my $cb_dot_lines = new_check_button_for (\%pr::gui, 'dot_lines', \%HPVALUE);
+    my $cb_toolbar_d = new_check_button_for (\%pr::gui, 'toolbar_d', \%HPVALUE);
+    my $tb_zero_char = new_text_box_for_nchar (\%pr::gui, 'zero_char', \%HPVALUE);
 
-    $gf->pack_start (&new_subpage_frame (
-                         &new_vbox_pack (
-                             &new_check_button_for (\%pr::gui, 'strip_all'),
-                             &new_check_button_for (\%pr::gui, 'strip_sum'),
-                             &new_text_box_for_int (\%pr::gui, 'strip_off')),
+    $gf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_check_button_for (\%pr::gui, 'strip_all', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'strip_sum', \%HPVALUE),
+                             new_text_box_for_int (\%pr::gui, 'strip_off', \%HPVALUE)),
                          $xl::s{stripes_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
-    $gf->pack_start (&new_subpage_frame (
-                         &new_vbox_pack (
-                             &new_check_button_for (\%pr::gui, 'b_unread'),
-                             &new_check_button_for (\%pr::gui, 'swp_from'),
-                             &new_check_button_for (\%pr::gui, 'two_linev'),
-                             &new_selection_box_for (\%pr::gui, 'from_show')),
-                         $xl::s{mlist_frame}, 'not-packed'), 
+    $gf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_check_button_for (\%pr::gui, 'b_unread', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'swp_from', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'two_linev', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'next_del', \%HPVALUE),
+                             new_selection_box_for (\%pr::gui, 'from_show', \%HPVALUE)),
+                         $xl::s{mlist_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
-    $gf->pack_start (&new_subpage_frame (
-                         &new_hbox_pack (
-                             &new_check_button_for (\%pr::gui, 'cursor_v'),
-                             &new_check_button_for (\%pr::gui, 'mview_date')),
-                         $xl::s{mview_frame}, 'not-packed'), 
+    $gf->pack_start (new_subpage_frame (
+                         new_hbox_pack (
+                             new_check_button_for (\%pr::gui, 'cursor_v', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'mview_date', \%HPVALUE)),
+                         $xl::s{mview_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
-    $gf->pack_start (&new_subpage_frame (
-                         &new_hbox_pack (
-                             &new_check_button_for (\%pr::gui, 'no_markup'),
-                             &new_check_button_for (\%pr::gui, 'margin_co')),
-                         $xl::s{compo_frame}, 'not-packed'), 
+    $gf->pack_start (new_subpage_frame (
+                         new_hbox_pack (
+                             new_check_button_for (\%pr::gui, 'no_markup', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'margin_co', \%HPVALUE),
+                             new_check_button_for (\%pr::gui, 'type_any', \%HPVALUE),
+                             new_check_button_and_text_box_for_int (\%pr::gui, 'warn_send_multi', 'warn_send_multi_threshold', \%HPVALUE)),
+                         $xl::s{compo_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
     $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
     $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
-    $gf->pack_start (&new_subpage_frame (
-                         &new_vbox_pack (
-                             &new_check_button_for (\%pr::gui, 'h_scroll'),
-                             &new_selection_box_for (\%pr::gui, 'v_scroll')),
+    $gf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_check_button_for (\%pr::gui, 'h_scroll', \%HPVALUE),
+                             new_selection_box_for (\%pr::gui, 'v_scroll', \%HPVALUE)),
                          $xl::s{sbar_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
     $gf->pack_start ($tb_zero_char, FALSE, FALSE, 0);
@@ -816,7 +987,6 @@ sub new_gui_page() {
         'int,100,3000', # 0.1 seconds - 3 seconds
         '0.0.0',
         '500',
-        undef,
     ],
     dangerous => [
         'live_dangerously',
@@ -825,7 +995,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     flowed => [
         'respect_flowed_format',
@@ -834,7 +1003,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     parts_rw => [
         'save_parts_readwrite',
@@ -843,7 +1011,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     skip_ssl => [
         'skip_ssl_cert_check',
@@ -852,7 +1019,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     up_step => [
         'statusbar_update_step',
@@ -861,7 +1027,6 @@ sub new_gui_page() {
         'int,1,200', # 1 item - 200 items
         '0.0.0',
         '10',
-        undef,
     ],
     thread_a => [
         'thread_by_subject_max_age',
@@ -870,7 +1035,6 @@ sub new_gui_page() {
         'int,1,30', # 1 day - 30 days
         '0.0.0',
         '10',
-        undef,
     ],
     unsafe_ssl => [
         'unsafe_ssl_certs',
@@ -879,16 +1043,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',
@@ -897,7 +1059,6 @@ sub new_gui_page() {
         'bool',
         '0.0.0',
         '1',
-        undef,
     ],
     out_ascii => [
         'outgoing_fallback_to_ascii',
@@ -906,7 +1067,6 @@ sub new_gui_page() {
         'bool',
         '3.4.0.37',
         '1',
-        undef,
     ],
     pp_unsel => [
         'primary_paste_unselects',
@@ -915,7 +1075,6 @@ sub new_gui_page() {
         'bool',
         '3.6.1.35',
         '0',
-        undef,
     ],
     inline_at => [
         'show_inline_attachments',
@@ -924,7 +1083,30 @@ sub new_gui_page() {
         'bool',
         '3.7.8.48',
         '1',
-        undef,
+    ],
+    addr_swc => [
+        'address_search_wildcard',
+        $xl::s{l_beh_addr_swc},
+        $xl::s{h_beh_addr_swc},
+        'bool',
+        '3.9.3.18',
+        '0',
+    ],
+    fold_swc => [
+        'folder_search_wildcard',
+        $xl::s{l_beh_fold_swc},
+        $xl::s{h_beh_fold_swc},
+        'bool',
+        '3.9.3.18',
+        '0',
+    ],
+    rewrite_ff => [
+        'rewrite_first_from',
+        $xl::s{l_beh_rewrite_ff},
+        $xl::s{h_beh_rewrite_ff},
+        'bool',
+        '3.14.0.94',
+        '0',
     ],
 );
 
@@ -932,35 +1114,41 @@ sub new_behaviour_page() {
     my $bf = Gtk2::VBox->new (FALSE, 5);
     $bf->set_border_width (PAGE_SPC);
 
-    my $tb_up_step = &new_text_box_for_int (\%pr::beh, 'up_step');
-    my $tb_thread_a = &new_text_box_for_int (\%pr::beh, 'thread_a');
+    my $tb_up_step = new_text_box_for_int (\%pr::beh, 'up_step', \%HPVALUE);
+    my $tb_thread_a = new_text_box_for_int (\%pr::beh, 'thread_a', \%HPVALUE);
 
-    $bf->pack_start (&new_subpage_frame (
-                         &new_vbox_pack (
-                             &new_text_box_for_int (\%pr::beh, 'hover_t'),
-                             &new_check_button_for (\%pr::beh, 'warn_dnd')),
-                         $xl::s{dnd_frame}, 'not-packed'), 
+    $bf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_text_box_for_int (\%pr::beh, 'hover_t', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'warn_dnd', \%HPVALUE)),
+                         $xl::s{dnd_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
-    $bf->pack_start (&new_subpage_frame (
-                         &new_hbox_pack (
-                             &new_check_button_for (\%pr::beh, 'skip_ssl'),
-                             &new_check_button_for (\%pr::beh, 'unsafe_ssl')),
+    $bf->pack_start (new_subpage_frame (
+                         new_hbox_pack (
+                             new_check_button_for (\%pr::beh, 'skip_ssl', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'unsafe_ssl', \%HPVALUE)),
                          $xl::s{ssl_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
     $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
     $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
-    $bf->pack_start (&new_subpage_frame (
-                         &new_vbox_pack (
-                             &new_check_button_for (\%pr::beh, 'flowed'),
-                             &new_check_button_for (\%pr::beh, 'parts_rw'),
-                             &new_check_button_for (\%pr::beh, 'use_utf8'),
-                             &new_check_button_for (\%pr::beh, 'dangerous'),
-                             &new_check_button_for (\%pr::beh, 'out_ascii'),
-                             &new_check_button_for (\%pr::beh, 'pp_unsel'),
-                             &new_check_button_for (\%pr::beh, 'inline_at')),
+    $bf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_check_button_for (\%pr::beh, 'flowed', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'parts_rw', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'use_utf8', \%HPVALUE),
+                             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, 'rewrite_ff', \%HPVALUE)),
                          $xl::s{msgs_frame}, 'not-packed'),
                      FALSE, FALSE, FRAME_SPC);
-
+    $bf->pack_start (new_subpage_frame (
+                         new_vbox_pack (
+                             new_check_button_for (\%pr::beh, 'addr_swc', \%HPVALUE),
+                             new_check_button_for (\%pr::beh, 'fold_swc', \%HPVALUE)),
+                         $xl::s{swc_frame}, 'not-packed'),
+                     FALSE, FALSE, FRAME_SPC);
     return $bf;
 }
 
@@ -972,7 +1160,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#0000cf',
-        undef,
     ],
     log_err => [
         'log_error_color',
@@ -981,7 +1168,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#af0000',
-        undef,
     ],
     log_in => [
         'log_in_color',
@@ -990,7 +1176,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#000000',
-        undef,
     ],
     log_msg => [
         'log_msg_color',
@@ -999,7 +1184,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#00af00',
-        undef,
     ],
     log_out => [
         'log_out_color',
@@ -1008,7 +1192,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#0000ef',
-        undef,
     ],
     log_warn => [
         'log_warn_color',
@@ -1017,7 +1200,6 @@ sub new_behaviour_page() {
         'color',
         '0.0.0',
         '#af0000',
-        undef,
     ],
     diff_add => [
         'diff_added_color',
@@ -1026,7 +1208,6 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#008b8b',
-        undef,
     ],
     diff_del => [
         'diff_deleted_color',
@@ -1035,7 +1216,6 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#6a5acd',
-        undef,
     ],
     diff_hunk => [
         'diff_hunk_color',
@@ -1044,30 +1224,112 @@ sub new_behaviour_page() {
         'color',
         '3.8.0.54',
         '#a52a2a',
-        undef,
+    ],
+    tags_bg => [
+        'tags_bgcolor',
+        $xl::s{l_col_tags_bg},
+        $xl::s{h_col_tags_bg},
+        'color',
+        '3.14.1.31',
+        '#f5f6be',
+    ],
+    tags_text => [
+        'tags_color',
+        $xl::s{l_col_tags_text},
+        $xl::s{h_col_tags_text},
+        'color',
+        '3.14.1.31',
+        '#000000',
+    ],
+    default_header_bg => [
+        'default_header_bgcolor',
+        $xl::s{l_col_default_header_bg},
+        $xl::s{h_col_default_header_bg},
+        'color',
+        '3.14.1.31',
+        '#f5f6be',
+    ],
+    default_header_text => [
+        'default_header_color',
+        $xl::s{l_col_default_header_text},
+        $xl::s{h_col_default_header_text},
+        'color',
+        '3.14.1.31',
+        '#000000',
+    ],
+    qs_active_bg => [
+        'qs_active_bgcolor',
+        $xl::s{l_col_qs_active_bg},
+        $xl::s{h_col_qs_active_bg},
+        'color',
+        '3.14.1.31',
+        '#f5f6be',
+    ],
+    qs_active_text => [
+        'qs_active_color',
+        $xl::s{l_col_qs_active_text},
+        $xl::s{h_col_qs_active_text},
+        'color',
+        '3.14.1.31',
+        '#000000',
+    ],
+    qs_error_bg => [
+        '',
+        $xl::s{l_col_qs_error_bg},
+        $xl::s{h_col_qs_error_bg},
+        'qs_error_bgcolor',
+        '3.14.1.31',
+        '#ff7070',
+    ],
+    qs_error_text => [
+        '',
+        $xl::s{l_col_qs_error_text},
+        $xl::s{h_col_qs_error_text},
+        'qs_error_color',
+        '3.14.1.31',
+        '#000000',
     ],
 );
 
 sub new_colours_page() {
-    return &new_vbox_pack (
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_color_button_for (\%pr::col, 'emphasis')),
+    return new_vbox_pack (
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_color_button_for (\%pr::col, 'emphasis', \%HPVALUE),
+                       new_hbox_pack_compact (
+                           new_color_button_for (\%pr::col, 'tags_text', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'tags_bg', \%HPVALUE))),
                    $xl::s{msgview_frame}, 'not-packed'),
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_color_button_for (\%pr::col, 'log_err'),
-                       &new_color_button_for (\%pr::col, 'log_in'),
-                       &new_color_button_for (\%pr::col, 'log_msg'),
-                       &new_color_button_for (\%pr::col, 'log_out'),
-                       &new_color_button_for (\%pr::col, 'log_warn')),
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_vbox_pack_compact (
+                           new_color_button_for (\%pr::col, 'log_err', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'log_warn', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'log_msg', \%HPVALUE)),
+                       new_vbox_pack_compact (
+                           new_color_button_for (\%pr::col, 'log_in', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'log_out', \%HPVALUE))),
                    $xl::s{log_frame}, 'not-packed'),
-               &new_subpage_frame (
-                   &new_vbox_pack (
-                       &new_color_button_for (\%pr::col, 'diff_add'),
-                       &new_color_button_for (\%pr::col, 'diff_del'),
-                       &new_color_button_for (\%pr::col, 'diff_hunk')),
-                   $xl::s{diff_frame}, 'not-packed')
+               new_subpage_frame (
+                   new_vbox_pack (
+                       new_color_button_for (\%pr::col, 'diff_add', \%HPVALUE),
+                       new_color_button_for (\%pr::col, 'diff_del', \%HPVALUE),
+                       new_color_button_for (\%pr::col, 'diff_hunk', \%HPVALUE)),
+                   $xl::s{diff_frame}, 'not-packed'),
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_color_button_for (\%pr::col, 'default_header_text', \%HPVALUE),
+                       new_color_button_for (\%pr::col, 'default_header_bg', \%HPVALUE)),
+                   $xl::s{compose_frame}, 'not-packed'),
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_vbox_pack_compact (
+                           new_color_button_for (\%pr::col, 'qs_active_text', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'qs_error_text', \%HPVALUE)),
+                       new_vbox_pack_compact (
+                           new_color_button_for (\%pr::col, 'qs_active_bg', \%HPVALUE),
+                           new_color_button_for (\%pr::col, 'qs_error_bg', \%HPVALUE))),
+                   $xl::s{qs_frame}, 'not-packed')
            );
 }
 
@@ -1079,7 +1341,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     main_y => [
         'mainwin_y',
@@ -1088,7 +1349,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     main_w => [
         'mainwin_width',
@@ -1097,7 +1357,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '779',
-        undef,
     ],
     main_h => [
         'mainwin_height',
@@ -1106,7 +1365,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '568',
-        undef,
     ],
     main_mx => [
         'mainwin_maximised',
@@ -1115,7 +1373,6 @@ sub new_colours_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     main_fs => [
         'mainwin_fullscreen',
@@ -1124,7 +1381,6 @@ sub new_colours_page() {
         'bool',
         '0.0.0',
         '0',
-        undef,
     ],
     msgs_x => [
         'main_messagewin_x',
@@ -1133,7 +1389,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '256',
-        undef,
     ],
     msgs_y => [
         'main_messagewin_y',
@@ -1142,7 +1397,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '210',
-        undef,
     ],
     msgs_w => [
         'messagewin_width',
@@ -1151,7 +1405,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     msgs_h => [
         'messagewin_height',
@@ -1160,7 +1413,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '540',
-        undef,
     ],
     send_w => [
         'sendwin_width',
@@ -1169,7 +1421,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '460',
-        undef,
     ],
     send_h => [
         'sendwin_height',
@@ -1178,7 +1429,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     recv_w => [
         'receivewin_width',
@@ -1187,7 +1437,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '460',
-        undef,
     ],
     recv_h => [
         'receivewin_height',
@@ -1196,7 +1445,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fold_x => [
         'folderwin_x',
@@ -1205,7 +1453,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     fold_y => [
         'folderwin_y',
@@ -1214,7 +1461,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '16',
-        undef,
     ],
     fold_w => [
         'folderitemwin_width',
@@ -1223,7 +1469,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     fold_h => [
         'folderitemwin_height',
@@ -1232,7 +1477,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fsel_w => [
         'folderselwin_width',
@@ -1241,7 +1485,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     fsel_h => [
         'folderselwin_height',
@@ -1250,7 +1493,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     sour_w => [
         'sourcewin_width',
@@ -1259,7 +1501,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     sour_h => [
         'sourcewin_height',
@@ -1268,7 +1509,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     addr_w => [
         'addressbookwin_width',
@@ -1277,7 +1517,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     addr_h => [
         'addressbookwin_height',
@@ -1286,7 +1525,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     adep_w => [
         'addressbookeditpersonwin_width',
@@ -1295,7 +1533,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '640',
-        undef,
     ],
     adep_h => [
         'addressbookeditpersonwin_height',
@@ -1304,7 +1541,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '320',
-        undef,
     ],
     adeg_w => [
         'addressbookeditgroupwin_width',
@@ -1313,7 +1549,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '580',
-        undef,
     ],
     adeg_h => [
         'addressbookeditgroupwin_height',
@@ -1322,7 +1557,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '340',
-        undef,
     ],
     adda_w => [
         'addressaddwin_width',
@@ -1331,7 +1565,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     adda_h => [
         'addressaddwin_height',
@@ -1340,7 +1573,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     addf_w => [
         'addressbook_folderselwin_width',
@@ -1349,7 +1581,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '300',
-        undef,
     ],
     addf_h => [
         'addressbook_folderselwin_height',
@@ -1358,7 +1589,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acce_w => [
         'editaccountwin_width',
@@ -1367,7 +1597,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     acce_h => [
         'editaccountwin_height',
@@ -1376,7 +1605,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acco_w => [
         'accountswin_width',
@@ -1385,7 +1613,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     acco_h => [
         'accountswin_height',
@@ -1394,7 +1621,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     filt_w => [
         'filteringwin_width',
@@ -1403,7 +1629,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '500',
-        undef,
     ],
     filt_h => [
         'filteringwin_height',
@@ -1412,7 +1637,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fila_w => [
         'filteringactionwin_width',
@@ -1421,7 +1645,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '490',
-        undef,
     ],
     fila_h => [
         'filteringactionwin_height',
@@ -1430,7 +1653,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     fild_w => [
         'filtering_debugwin_width',
@@ -1439,7 +1661,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     fild_h => [
         'filtering_debugwin_height',
@@ -1448,7 +1669,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     matc_w => [
         'matcherwin_width',
@@ -1457,7 +1677,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     matc_h => [
         'matcherwin_height',
@@ -1466,7 +1685,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     pref_w => [
         'prefswin_width',
@@ -1475,7 +1693,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     pref_h => [
         'prefswin_height',
@@ -1484,7 +1701,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     temp_w => [
         'templateswin_width',
@@ -1493,7 +1709,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '480',
-        undef,
     ],
     temp_h => [
         'templateswin_height',
@@ -1502,7 +1717,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     acti_w => [
         'actionswin_width',
@@ -1511,7 +1725,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '486',
-        undef,
     ],
     acti_h => [
         'actionswin_height',
@@ -1520,7 +1733,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     tags_w => [
         'tagswin_width',
@@ -1529,7 +1741,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '486',
-        undef,
     ],
     tags_h => [
         'tagswin_height',
@@ -1538,7 +1749,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     plug_w => [
         'pluginswin_width',
@@ -1547,7 +1757,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     plug_h => [
         'pluginswin_height',
@@ -1556,7 +1765,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     logw_w => [
         'logwin_width',
@@ -1565,7 +1773,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '520',
-        undef,
     ],
     logw_h => [
         'logwin_height',
@@ -1574,7 +1781,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
     prin_w => [
         'print_previewwin_width',
@@ -1583,7 +1789,6 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '600',
-        undef,
     ],
     prin_h => [
         'print_previewwin_height',
@@ -1592,189 +1797,188 @@ sub new_colours_page() {
         'int,0,3000', # 0 pixels - 3000 pixels
         '0.0.0',
         '-1',
-        undef,
     ],
 );
 
 sub new_winpos_subpage_main() {
-    return &new_subpage_frame (
-               &new_vbox_pack_compact (
-                   &new_vbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'main_x'), 
-                       &new_text_box_for_int (\%pr::win, 'main_y')), 
-                   &new_hbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'main_w'), 
-                       &new_text_box_for_int (\%pr::win, 'main_h')), 
-                   &new_vbox_pack (
-                       &new_check_button_for (\%pr::win, 'main_fs'), 
-                       &new_check_button_for (\%pr::win, 'main_mx'))),
+    return new_subpage_frame (
+               new_vbox_pack_compact (
+                   new_vbox_pack (
+                       new_text_box_for_int (\%pr::win, 'main_x', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'main_y', \%HPVALUE)),
+                   new_hbox_pack (
+                       new_text_box_for_int (\%pr::win, 'main_w', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'main_h', \%HPVALUE)),
+                   new_vbox_pack (
+                       new_check_button_for (\%pr::win, 'main_fs', \%HPVALUE),
+                       new_check_button_for (\%pr::win, 'main_mx', \%HPVALUE))),
                _('Main window')
            );
 }
 
 sub new_winpos_subpage_msgs() {
-    return &new_subpage_frame (
-               &new_vbox_pack_compact (
-                   &new_vbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'msgs_x'),
-                       &new_text_box_for_int (\%pr::win, 'msgs_y')),
-                   &new_hbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'msgs_w'),
-                       &new_text_box_for_int (\%pr::win, 'msgs_h'))),
+    return new_subpage_frame (
+               new_vbox_pack_compact (
+                   new_vbox_pack (
+                       new_text_box_for_int (\%pr::win, 'msgs_x', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'msgs_y', \%HPVALUE)),
+                   new_hbox_pack (
+                       new_text_box_for_int (\%pr::win, 'msgs_w', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'msgs_h', \%HPVALUE))),
                _('Message window')
            );
 }
 
 sub new_winpos_subpage_sendrecv() {
-    return &new_vbox_pack (
-               &new_subpage_frame (
-                   &new_hbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'send_w'),
-                       &new_text_box_for_int (\%pr::win, 'send_h')),
+    return new_vbox_pack (
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_text_box_for_int (\%pr::win, 'send_w', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'send_h', \%HPVALUE)),
                    _('Send window'), 'not-packed'),
-               &new_subpage_frame (
-                   &new_hbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'recv_w'),
-                       &new_text_box_for_int (\%pr::win, 'recv_h')),
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_text_box_for_int (\%pr::win, 'recv_w', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'recv_h', \%HPVALUE)),
                    _('Receive window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_fold() {
-    return &new_vbox_pack (
-               &new_subpage_frame (
-                   &new_vbox_pack_compact (
-                       &new_vbox_pack (
-                            &new_text_box_for_int (\%pr::win, 'fold_x'), 
-                            &new_text_box_for_int (\%pr::win, 'fold_y')), 
-                       &new_hbox_pack (
-                           &new_text_box_for_int (\%pr::win, 'fold_w'), 
-                           &new_text_box_for_int (\%pr::win, 'fold_h'))),
+    return new_vbox_pack (
+               new_subpage_frame (
+                   new_vbox_pack_compact (
+                       new_vbox_pack (
+                            new_text_box_for_int (\%pr::win, 'fold_x', \%HPVALUE),
+                            new_text_box_for_int (\%pr::win, 'fold_y', \%HPVALUE)),
+                       new_hbox_pack (
+                           new_text_box_for_int (\%pr::win, 'fold_w', \%HPVALUE),
+                           new_text_box_for_int (\%pr::win, 'fold_h', \%HPVALUE))),
                    _('Folder window'), 'not-packed'),
-               &new_subpage_frame (
-                   &new_hbox_pack (
-                       &new_text_box_for_int (\%pr::win, 'fsel_w'),
-                       &new_text_box_for_int (\%pr::win, 'fsel_h')),
+               new_subpage_frame (
+                   new_hbox_pack (
+                       new_text_box_for_int (\%pr::win, 'fsel_w', \%HPVALUE),
+                       new_text_box_for_int (\%pr::win, 'fsel_h', \%HPVALUE)),
                    _('Folder selection window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_addrbook() {
-    return &new_vbox_pack (
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'addr_w'),
-                          &new_text_box_for_int (\%pr::win, 'addr_h')),
+    return new_vbox_pack (
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'addr_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'addr_h', \%HPVALUE)),
                      _('Addressbook main window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'adep_w'),
-                          &new_text_box_for_int (\%pr::win, 'adep_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'adep_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'adep_h', \%HPVALUE)),
                      _('Edit person window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'adeg_w'),
-                          &new_text_box_for_int (\%pr::win, 'adeg_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'adeg_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'adeg_h', \%HPVALUE)),
                      _('Edit group window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'adda_w'),
-                          &new_text_box_for_int (\%pr::win, 'adda_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'adda_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'adda_h', \%HPVALUE)),
                      _('Add address window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'addf_w'),
-                          &new_text_box_for_int (\%pr::win, 'addf_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'addf_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'addf_h', \%HPVALUE)),
                      _('Folder select window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_accounts() {
-    return &new_vbox_pack (
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'acco_w'),
-                          &new_text_box_for_int (\%pr::win, 'acco_h')),
+    return new_vbox_pack (
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'acco_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'acco_h', \%HPVALUE)),
                      _('Accounts window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'acce_w'),
-                          &new_text_box_for_int (\%pr::win, 'acce_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'acce_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'acce_h', \%HPVALUE)),
                      _('Edit account window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_filtering() {
-    return &new_vbox_pack (
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'filt_w'),
-                          &new_text_box_for_int (\%pr::win, 'filt_h')),
+    return new_vbox_pack (
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'filt_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'filt_h', \%HPVALUE)),
                      _('Filtering window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'fila_w'),
-                          &new_text_box_for_int (\%pr::win, 'fila_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'fila_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'fila_h', \%HPVALUE)),
                      _('Filtering actions window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'fild_w'),
-                          &new_text_box_for_int (\%pr::win, 'fild_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'fild_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'fild_h', \%HPVALUE)),
                      _('Filtering debug window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'matc_w'),
-                          &new_text_box_for_int (\%pr::win, 'matc_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'matc_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'matc_h', \%HPVALUE)),
                      _('Matcher window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_prefs() {
-    return &new_vbox_pack (
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'pref_w'),
-                          &new_text_box_for_int (\%pr::win, 'pref_h')),
+    return new_vbox_pack (
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'pref_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'pref_h', \%HPVALUE)),
                      _('Preferences window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'temp_w'),
-                          &new_text_box_for_int (\%pr::win, 'temp_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'temp_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'temp_h', \%HPVALUE)),
                      _('Templates window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'acti_w'),
-                          &new_text_box_for_int (\%pr::win, 'acti_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'acti_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'acti_h', \%HPVALUE)),
                      _('Actions window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'tags_w'),
-                          &new_text_box_for_int (\%pr::win, 'tags_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'tags_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'tags_h', \%HPVALUE)),
                      _('Tags window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'plug_w'),
-                          &new_text_box_for_int (\%pr::win, 'plug_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'plug_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'plug_h', \%HPVALUE)),
                      _('Plugins window'), 'not-packed')
            );
 }
 
 sub new_winpos_subpage_misc() {
-    return &new_vbox_pack (
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'logw_w'),
-                          &new_text_box_for_int (\%pr::win, 'logw_h')),
+    return new_vbox_pack (
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'logw_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'logw_h', \%HPVALUE)),
                      _('Log window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'prin_w'),
-                          &new_text_box_for_int (\%pr::win, 'prin_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'prin_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'prin_h', \%HPVALUE)),
                      _('Print preview window'), 'not-packed'),
-                &new_subpage_frame (
-                     &new_hbox_pack (
-                          &new_text_box_for_int (\%pr::win, 'sour_w'),
-                          &new_text_box_for_int (\%pr::win, 'sour_h')),
+                new_subpage_frame (
+                     new_hbox_pack (
+                          new_text_box_for_int (\%pr::win, 'sour_w', \%HPVALUE),
+                          new_text_box_for_int (\%pr::win, 'sour_h', \%HPVALUE)),
                      _('View source window'), 'not-packed')
            );
 }
@@ -1782,200 +1986,532 @@ sub new_winpos_subpage_misc() {
 sub new_winpos_page() {
     my $winbook = Gtk2::Notebook->new;
     $winbook->set_tab_pos ('right');
-    $winbook->append_page (&new_winpos_subpage_main, _('Main'));
-    $winbook->append_page (&new_winpos_subpage_msgs, _('Message'));
-    $winbook->append_page (&new_winpos_subpage_sendrecv, _('Send/Receive'));
-    $winbook->append_page (&new_winpos_subpage_fold, _('Folder'));
-    $winbook->append_page (&new_winpos_subpage_addrbook, _('Addressbook'));
-    $winbook->append_page (&new_winpos_subpage_accounts, _('Accounts'));
-    $winbook->append_page (&new_winpos_subpage_filtering, _('Filtering'));
-    $winbook->append_page (&new_winpos_subpage_prefs, _('Preferences'));
-    $winbook->append_page (&new_winpos_subpage_misc, _('Other'));
+    $winbook->append_page (new_winpos_subpage_main, _('Main'));
+    $winbook->append_page (new_winpos_subpage_msgs, _('Message'));
+    $winbook->append_page (new_winpos_subpage_sendrecv, _('Send/Receive'));
+    $winbook->append_page (new_winpos_subpage_fold, _('Folder'));
+    $winbook->append_page (new_winpos_subpage_addrbook, _('Addressbook'));
+    $winbook->append_page (new_winpos_subpage_accounts, _('Accounts'));
+    $winbook->append_page (new_winpos_subpage_filtering, _('Filtering'));
+    $winbook->append_page (new_winpos_subpage_prefs, _('Preferences'));
+    $winbook->append_page (new_winpos_subpage_misc, _('Other'));
     return $winbook;
 }
 
+%pr::acc = ( # per account hidden preferences
+    tls_set => [
+        'gnutls_set_priority',
+        $xl::s{l_acc_gtls_set},
+        $xl::s{h_acc_gtls_set},
+        'bool',
+        '3.9.0.181',
+        '0',
+    ],
+    tls_pri => [
+        'gnutls_priority',
+        $xl::s{l_acc_gtls_pri},
+        $xl::s{h_acc_gtls_pri},
+        'char,0,256,32',
+        '3.9.0.181',
+        '0',
+    ],
+);
+
+sub new_account_subpage($) {
+    my ($akey) = @_;
+    return new_vbox_pack (
+                new_subpage_frame (
+                    new_vbox_pack (
+                        new_check_button_for (\%pr::acc, 'tls_set', $ACHPVALUE{$akey}),
+                        new_text_box_for_nchar (\%pr::acc, 'tls_pri', $ACHPVALUE{$akey})),
+                    _('GnuTLS priority'), 'not-packed')
+           );
+}
+
+sub new_accounts_page() {
+    my $accbook = Gtk2::Notebook->new;
+    $accbook->set_tab_pos ('right');
+    my @akeys = sort {
+        $ACPREFS{$a}{'account_name'} cmp $ACPREFS{$b}{'account_name'}
+    } keys %ACPREFS;
+    foreach (@akeys) {
+        my $name = $ACPREFS{$_}{'account_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);
+        }
+    }
+    $accbook->set_scrollable (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";
+    my $clawsver = ($CLAWSV eq "") ?
+                _("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 _("    --help                         Prints this help screen.\n");
-    print _("    --version                      Prints version infos.\n");
-    print _("    --verbose                      More messages on standard output.\n");
-    print _("    --alternate-config-dir <dir>   Uses <dir> as Claws Mail config dir.\n");
-    print _("    --clawsrc <file>               Uses <file> as full resource name.\n");
-}
-
-# handle errors which don't allow to run
-sub command_line_fatal() {
-    my $reason = shift;
-    my $emsg = $xl::s{e_error} . $reason;
-    error_dialog ($emsg);
-    log_message ("$emsg", 'die');
-}
-
-# parse the command line
-sub parse_command_line() {
-    $CLAWSV = &get_claws_version;
-    my $arg = 0;
-    while (defined($ARGV[$arg])) {
-        for ($ARGV[$arg]) {
-            /--help/ && do { 
-                &print_help; 
-                return FALSE;
-            };
-            /--version/ && do { 
-                &print_version; 
-                return FALSE;
-            };
-            /--verbose/ && do {
-                $VERBOSE = TRUE;
-                last;
-            };
-            /--use-claws-version/ && do {
-                ++$arg;
-                &command_line_fatal ("required version")
-                    unless defined($ARGV[$arg]);
-                &command_line_fatal ("required a dotted numeric value")
-                    unless ($ARGV[$arg] =~ /[\d\.]+/);
-                $CLAWSV = $ARGV[$arg];
-                last;
-            };
-            /--alternate-config-dir/ && do {
-                ++$arg;
-                &command_line_fatal ($xl::s{e_requireddir})
-                    unless defined($ARGV[$arg]);
-                &command_line_fatal ($xl::s{e_notadir})
-                    unless -d $ARGV[$arg];
-                $CONFIGDIR = $ARGV[$arg];
-                $CONFIGDIR .= "/" 
-                    unless ($CONFIGDIR =~ /.*\/$/);
-                $ALTCONFIGDIR = TRUE;
-                last;
-            };
-            /--clawsrc/ && do {
-                ++$arg;
-                &command_line_fatal($xl::s{e_requiredfile}) 
-                    unless defined($ARGV[$arg]);
-                &command_line_fatal($xl::s{e_notafile}) 
-                    unless -f $ARGV[$arg];
-                &set_rc_filename ($ARGV[$arg]);
-                last;
-            };
-            /.*/ && &command_line_fatal (
-                _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
+    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 {
+    my $cont = TRUE;
+    $CLAWSV = get_claws_version ();
+    eval {
+        GetOptions('h|help' => sub { print_help (); $cont = FALSE },
+            'v|version' => sub { print_version (); $cont = FALSE },
+            'b|verbose' => sub { $VERBOSE = TRUE },
+            'r|read-only' => sub { $READONLY = TRUE },
+            'u|use-claws-version=s' => \&opt_use_claws_version,
+            'a|alternate-config-dir=s' => \&opt_alternate_config_dir,
+            'c|clawsrc=s' => \&opt_clawsrc)
+        or die _("try -h or --help for syntax.\n");
+    };
+    if ($@) {
+        my $msg = _("Error in options: {msg}\n", msg => $@);
+        if (defined $ENV{'DISPLAY'} and $ENV{'DISPLAY'} ne '') {
+            eval { Gtk2->init };
+            error_dialog ($msg) unless $@;
         }
-        ++$arg;
+        die $msg;
     }
-    # eveything continues...
-    return TRUE;
+    return $cont;
+}
+
+sub opt_use_claws_version {
+    my ($name, $value) = @_;
+    die _("Error: {opt} requires a dotted numeric value argument\n", opt => $name)
+        unless ($value =~ /^[\d\.]+$/);
+    $CLAWSV = $value;
+}
+
+sub opt_alternate_config_dir {
+    my ($name, $value) = @_;
+    die _("Error: '{dir}' is not a directory or does not exist\n", dir => $value)
+        unless -d $value;
+    $CONFIGDIR = $value;
+    $CONFIGDIR .= "/" unless ($CONFIGDIR =~ /.*\/$/);
+    $ALTCONFIGDIR = TRUE;
+}
+
+sub opt_clawsrc {
+    my ($name, $value) = @_;
+    die _("Error: '{value}' is not a file or does not exist\n", value => $value)
+        unless -f $value;
+    set_rc_filename ($value);
 }
 
 # update the hidden preferences status from loaded values
-sub init_hidden_preferences() {
+sub init_hidden_preferences {
     foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
-        foreach my $key (keys %$hash) { 
+        foreach my $key (keys %$hash) {
             $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
         }
     }
+    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;
 }
 
-# load current status from disc
-sub load_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");
+# 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;
-        if (/^([8a-z_]+)=(.*)$/) {
-            $PREFS{$1} = "$2";
+        ++$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_rc_preferences {
+    my $rc = get_rc_filename ();
+    log_message ("Loading preferences from $rc\n");
+    return FALSE unless check_rc_file ($rc);
+    ($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}{$_};
+            }
+        }
+    }
     return TRUE;
 }
 
+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);
+    ($ACCOUNTDATA, $ACCOUNTMETA) = load_resource ($rc);
+    foreach my $asect (keys %$ACCOUNTDATA) {
+        if ($asect =~ /^Account: (\d+)$/) {
+            foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+                $ACPREFS{$1}{$_} = $ACCOUNTDATA->{$asect}{$_};
+            }
+        }
+    }
+    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;
-    &log_message ("Saving preferences to $rc\n");
-    return FALSE unless &check_rc_file ($rc);
-    return FALSE unless &check_claws_not_running;
+sub save_preferences {
+    my $rc = get_rc_filename ();
+    log_message ("Saving preferences to $rc\n");
+    return FALSE unless check_rc_file ($rc);
+    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{$_};
+        }
+    }
+    foreach my $plugin (@AVPLUGINS) {
+        foreach (keys %{$CONFIGDATA->{$plugin}}) {
+            if (defined $PLHPVALUE{$plugin}{$_}) {
+                $CONFIGDATA->{$plugin}{$_} = $PLHPVALUE{$plugin}{$_};
             }
         }
-        else {
-            print RCF $_ . "\n";
+    }
+    save_resource ($rc, $CONFIGDATA, $CONFIGMETA);
+    return TRUE;
+}
+
+sub save_ac_preferences {
+    my $rc = get_ac_rc_filename ();
+    log_message ("Saving account preferences to $rc\n");
+    return FALSE unless check_rc_file ($rc);
+    return FALSE unless check_claws_not_running ();
+    my $rcbak = "$rc.backup";
+    rename ($rc, $rcbak);
+    foreach my $asect (keys %$ACCOUNTDATA) {
+        if ($asect =~ /^Account: (\d+)$/) {
+            foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+                if (defined $ACHPVALUE{$1}{$_}) {
+                    $ACCOUNTDATA->{$asect}{$_} = $ACHPVALUE{$1}{$_};
+                }
+            }
         }
     }
-    close (RCB);
-    close (RCF);
+    save_resource ($rc, $ACCOUNTDATA, $ACCOUNTMETA);
     return TRUE;
 }
 
 # create notebook
-sub new_notebook() {
+sub new_notebook {
     my $nb = Gtk2::Notebook->new;
-    # 
-    $nb->append_page (&new_behaviour_page, $xl::s{tab_behaviour});
-    $nb->append_page (&new_colours_page, $xl::s{tab_colours});
-    $nb->append_page (&new_gui_page, $xl::s{tab_gui});
-    $nb->append_page (&new_other_page, $xl::s{tab_other});
-    $nb->append_page (&new_winpos_page, $xl::s{tab_winpos});
+    #
+    $nb->append_page (new_behaviour_page (), $xl::s{tab_behaviour});
+    $nb->append_page (new_colours_page (), $xl::s{tab_colours});
+    $nb->append_page (new_gui_page (), $xl::s{tab_gui});
+    $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;
 }
 
 # create an about dialog
-sub new_about_dialog() {
+sub new_about_dialog {
     my ($parent) = @_;
     my $title = $xl::s{about_title};
     my $lic = $xl::s{about_license};
     my $vers = $xl::s{about_version} . " $VERSION";
-    my $license = 
+    my $license =
 "This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
@@ -1988,13 +2524,13 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.";
-    my $year = "2007-2012";
+    my $year = "2007-2016";
     my $holder = "Ricardo Mones &lt;ricardo\@mones.org&gt;";
     my $url = "http://www.claws-mail.org/clawsker.php";
 
-    my $dialog = Gtk2::MessageDialog->new_with_markup ($parent, 
-                    [qw/modal destroy-with-parent/], 
-                    'info', 'close', 
+    my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
+                    [qw/modal destroy-with-parent/],
+                    'info', 'close',
                     "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
                     . "<span size=\"large\">$vers</span>\n\n"
                     . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
@@ -2002,12 +2538,19 @@ 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;
 }
 
 # create buttons box
-sub new_button_box() {
+sub new_button_box {
     my ($parent, $adlg) = @_;
     my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
     my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
@@ -2015,10 +2558,14 @@ sub new_button_box() {
     # disable button until is really implemented
     # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
     my $hbox = Gtk2::HBox->new (FALSE, 5);
-    # signal handlers 
+    # signal handlers
     $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
-    $b_apply->signal_connect (clicked => sub { &save_preferences ($parent) });
-    # $b_undo->signal_connect (clicked => sub { &undo_current_changes });
+    $b_apply->set_sensitive (not $READONLY);
+    $b_apply->signal_connect (clicked => sub {
+        save_preferences ($parent);
+        save_ac_preferences ($parent);
+    });
+    # $b_undo->signal_connect (clicked => sub { undo_current_changes });
     $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
     # package them
     $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
@@ -2029,19 +2576,42 @@ sub new_button_box() {
     return $hbox;
 }
 
+sub get_app_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 @APPICONS, $icon if ($icon);
+    }
+    return @APPICONS;
+}
+
 # initialise
+exit unless parse_command_line ();
+Gtk2->init;
 $main_window = Gtk2::Window->new ('toplevel');
-exit unless &parse_command_line;
-exit unless &load_preferences;
-exit unless &init_hidden_preferences;
+exit unless load_preferences ();
+exit unless init_hidden_preferences ();
 # create main GUI
 my $box = Gtk2::VBox->new (FALSE, 5);
 $box->set_border_width(3);
-my $about = &new_about_dialog;
-$box->pack_start (&new_notebook, FALSE, FALSE, 0);
-$box->pack_end (&new_button_box ($main_window, $about), FALSE, FALSE, 0);
+my $about = new_about_dialog ();
+$box->pack_start (new_notebook (), FALSE, FALSE, 0);
+$box->pack_end (new_button_box ($main_window, $about), FALSE, FALSE, 0);
 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
 $main_window->set_title ($xl::s{win_title});
+$main_window->set_icon_list (get_app_icons ());
 $main_window->add ($box);
 $main_window->show_all;
 Gtk2->main;