tab_other => _('Other'),
tab_winpos => _('Windows'),
tab_accounts => _('Accounts'),
+ tab_plugins => _('Plugins'),
+ tab_info => _('Info'),
ab_frame => _('Addressbook'),
mem_frame => _('Memory'),
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.'),
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, acumulative.'),
+ l_plu_prl_none => _('None'),
+ l_plu_prl_manual => _('Manual'),
+ l_plu_prl_action => _('Actions'),
+ l_plu_prl_match => _('Matches'),
+
e_error => _('Error: '),
e_noclawsrc => _('resource file for Claws Mail was not found.'),
e_running => _('seems Claws Mail is currently running, close it first.'),
);
+# 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 TYPE => 3; # data type: bool, int, float, string, color
use constant CMVER => 4; # lowest[,highest] Claws Mail version(s) the feature exists
use constant CMDEF => 5; # default value for the preference in Claws Mail
-use constant GUI => 6; # GUI element
+use constant PLUGIN => 6; # plugin section (only in plugin preferences)
# constants for GUI spacing
use constant HBOX_SPC => 5;
'bool',
'2.7.0',
'0',
- undef,
],
max_use => [
'cache_max_mem_usage',
'int,0,262144', # 0 Kb - 256 Mb
'0.0.0',
'4096',
- undef,
],
min_time => [
'cache_min_keep_time',
'int,0,120', # 0 minutes - 2 hours
'0.0.0',
'15',
- undef,
],
use_netm => [
'use_networkmanager',
'bool',
'3.3.1',
'1',
- undef,
],
mp_rounds => [
'master_passphrase_pbkdf2_rounds',
'int,50000,1000000',
'3.13.2.110',
'50000',
- undef,
],
);
'bool',
'0.0.0',
'1',
- undef,
],
no_markup => [
'compose_no_markup',
'bool',
'0.0.0',
'0',
- undef,
],
dot_lines => [
'enable_dotted_lines',
'bool',
'0.0.0,3.7.10.44',
'0',
- undef,
],
h_scroll => [
'enable_hscrollbar',
'bool',
'0.0.0',
'1',
- undef,
],
swp_from => [
'enable_swap_from',
'bool',
'0.0.0',
'0',
- undef,
],
v_scroll => [
'folderview_vscrollbar_policy',
'0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
'0.0.0',
'0',
- undef,
],
from_show => [
'summary_from_show',
'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',
'int,0,40000', # no idea what this number means
'0.0.0',
'4000',
- undef,
],
cursor_v => [
'textview_cursor_visible',
'bool',
'0.0.0',
'0',
- undef,
],
toolbar_d => [
'toolbar_detachable',
'bool',
'0.0.0',
'0',
- undef,
],
strip_all => [
'use_stripes_everywhere',
'bool',
'0.0.0',
'1',
- undef,
],
strip_sum => [
'use_stripes_in_summaries',
'bool',
'0.0.0',
'1',
- undef,
],
two_linev => [
'two_line_vertical',
'bool',
'3.4.0.7',
'0',
- undef,
],
margin_co => [
'show_compose_margin',
'bool',
'3.7.6.7',
'0',
- undef,
],
mview_date => [
'msgview_date_format',
'bool',
'3.7.8.42',
'0',
- undef,
],
zero_char => [
'zero_replacement_char',
'char,1,1',
'2.8.1.77',
'0',
- undef,
],
type_any => [
'type_any_header',
'bool',
'3.12.0.44',
'0',
- undef,
],
next_del => [
'next_on_delete',
'bool',
'3.13.0.5',
'0',
- undef,
],
);
'int,100,3000', # 0.1 seconds - 3 seconds
'0.0.0',
'500',
- undef,
],
dangerous => [
'live_dangerously',
'bool',
'0.0.0',
'0',
- undef,
],
flowed => [
'respect_flowed_format',
'bool',
'0.0.0',
'0',
- undef,
],
parts_rw => [
'save_parts_readwrite',
'bool',
'0.0.0',
'0',
- undef,
],
skip_ssl => [
'skip_ssl_cert_check',
'bool',
'0.0.0',
'0',
- undef,
],
up_step => [
'statusbar_update_step',
'int,1,200', # 1 item - 200 items
'0.0.0',
'10',
- undef,
],
thread_a => [
'thread_by_subject_max_age',
'int,1,30', # 1 day - 30 days
'0.0.0',
'10',
- undef,
],
unsafe_ssl => [
'unsafe_ssl_certs',
'bool',
'0.0.0',
'0',
- undef,
],
use_utf8 => [
'utf8_instead_of_locale_for_broken_mail',
'bool',
'0.0.0',
'0',
- undef,
],
warn_dnd => [
'warn_dnd',
'bool',
'0.0.0',
'1',
- undef,
],
out_ascii => [
'outgoing_fallback_to_ascii',
'bool',
'3.4.0.37',
'1',
- undef,
],
pp_unsel => [
'primary_paste_unselects',
'bool',
'3.6.1.35',
'0',
- undef,
],
inline_at => [
'show_inline_attachments',
'bool',
'3.7.8.48',
'1',
- undef,
],
addr_swc => [
'address_search_wildcard',
'bool',
'3.9.3.18',
'0',
- undef,
],
fold_swc => [
'folder_search_wildcard',
'bool',
'3.9.3.18',
'0',
- undef,
+ ],
+ rewrite_ff => [
+ 'rewrite_first_from',
+ $xl::s{l_beh_rewrite_ff},
+ $xl::s{h_beh_rewrite_ff},
+ 'bool',
+ '3.14.0.94',
+ '0',
],
);
new_check_button_for (\%pr::beh, 'dangerous', \%HPVALUE),
new_check_button_for (\%pr::beh, 'out_ascii', \%HPVALUE),
new_check_button_for (\%pr::beh, 'pp_unsel', \%HPVALUE),
- new_check_button_for (\%pr::beh, 'inline_at', \%HPVALUE)),
+ new_check_button_for (\%pr::beh, 'inline_at', \%HPVALUE),
+ new_check_button_for (\%pr::beh, 'rewrite_ff', \%HPVALUE)),
$xl::s{msgs_frame}, 'not-packed'),
FALSE, FALSE, FRAME_SPC);
$bf->pack_start (new_subpage_frame (
'color',
'0.0.0',
'#0000cf',
- undef,
],
log_err => [
'log_error_color',
'color',
'0.0.0',
'#af0000',
- undef,
],
log_in => [
'log_in_color',
'color',
'0.0.0',
'#000000',
- undef,
],
log_msg => [
'log_msg_color',
'color',
'0.0.0',
'#00af00',
- undef,
],
log_out => [
'log_out_color',
'color',
'0.0.0',
'#0000ef',
- undef,
],
log_warn => [
'log_warn_color',
'color',
'0.0.0',
'#af0000',
- undef,
],
diff_add => [
'diff_added_color',
'color',
'3.8.0.54',
'#008b8b',
- undef,
],
diff_del => [
'diff_deleted_color',
'color',
'3.8.0.54',
'#6a5acd',
- undef,
],
diff_hunk => [
'diff_hunk_color',
'color',
'3.8.0.54',
'#a52a2a',
- undef,
],
);
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'16',
- undef,
],
main_y => [
'mainwin_y',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'16',
- undef,
],
main_w => [
'mainwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'779',
- undef,
],
main_h => [
'mainwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'568',
- undef,
],
main_mx => [
'mainwin_maximised',
'bool',
'0.0.0',
'0',
- undef,
],
main_fs => [
'mainwin_fullscreen',
'bool',
'0.0.0',
'0',
- undef,
],
msgs_x => [
'main_messagewin_x',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'256',
- undef,
],
msgs_y => [
'main_messagewin_y',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'210',
- undef,
],
msgs_w => [
'messagewin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'600',
- undef,
],
msgs_h => [
'messagewin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'540',
- undef,
],
send_w => [
'sendwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'460',
- undef,
],
send_h => [
'sendwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
recv_w => [
'receivewin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'460',
- undef,
],
recv_h => [
'receivewin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
fold_x => [
'folderwin_x',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'16',
- undef,
],
fold_y => [
'folderwin_y',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'16',
- undef,
],
fold_w => [
'folderitemwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'500',
- undef,
],
fold_h => [
'folderitemwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
fsel_w => [
'folderselwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'300',
- undef,
],
fsel_h => [
'folderselwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
sour_w => [
'sourcewin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'600',
- undef,
],
sour_h => [
'sourcewin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'500',
- undef,
],
addr_w => [
'addressbookwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'520',
- undef,
],
addr_h => [
'addressbookwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
adep_w => [
'addressbookeditpersonwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'640',
- undef,
],
adep_h => [
'addressbookeditpersonwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'320',
- undef,
],
adeg_w => [
'addressbookeditgroupwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'580',
- undef,
],
adeg_h => [
'addressbookeditgroupwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'340',
- undef,
],
adda_w => [
'addressaddwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'300',
- undef,
],
adda_h => [
'addressaddwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
addf_w => [
'addressbook_folderselwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'300',
- undef,
],
addf_h => [
'addressbook_folderselwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
acce_w => [
'editaccountwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'500',
- undef,
],
acce_h => [
'editaccountwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
acco_w => [
'accountswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'500',
- undef,
],
acco_h => [
'accountswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
filt_w => [
'filteringwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'500',
- undef,
],
filt_h => [
'filteringwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
fila_w => [
'filteringactionwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'490',
- undef,
],
fila_h => [
'filteringactionwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
fild_w => [
'filtering_debugwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'600',
- undef,
],
fild_h => [
'filtering_debugwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
matc_w => [
'matcherwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'520',
- undef,
],
matc_h => [
'matcherwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
pref_w => [
'prefswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'600',
- undef,
],
pref_h => [
'prefswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
temp_w => [
'templateswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'480',
- undef,
],
temp_h => [
'templateswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
acti_w => [
'actionswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'486',
- undef,
],
acti_h => [
'actionswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
tags_w => [
'tagswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'486',
- undef,
],
tags_h => [
'tagswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
plug_w => [
'pluginswin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
plug_h => [
'pluginswin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
logw_w => [
'logwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'520',
- undef,
],
logw_h => [
'logwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
prin_w => [
'print_previewwin_width',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'600',
- undef,
],
prin_h => [
'print_previewwin_height',
'int,0,3000', # 0 pixels - 3000 pixels
'0.0.0',
'-1',
- undef,
],
);
'bool',
'3.9.0.181',
'0',
- undef,
],
tls_pri => [
'gnutls_priority',
'char,0,256,32',
'3.9.0.181',
'0',
- undef,
],
);
sub new_accounts_page() {
my $accbook = Gtk2::Notebook->new;
$accbook->set_tab_pos ('right');
- foreach (keys %ACPREFS) {
+ my @akeys = sort {
+ $ACPREFS{$a}{'account_name'} cmp $ACPREFS{$b}{'account_name'}
+ } keys %ACPREFS;
+ foreach (@akeys) {
my $name = $ACPREFS{$_}{'account_name'};
- $accbook->append_page (new_account_subpage ($_), $name);
+ my $isdef = ($ACPREFS{$_}{'is_default'} eq '1');
+ my $page = new_account_subpage ($_);
+ $accbook->append_page ($page, $isdef? '<b>' . $name . '</b>': $name);
+ if ($isdef) {
+ my $label = $accbook->get_tab_label ($page);
+ $label->set_use_markup (TRUE);
+ }
}
return $accbook;
}
+%pr::plu = ( # plugins hidden preferences
+ # att_remover
+ arm_winw => [
+ 'win_width',
+ $xl::s{l_win_w},
+ $xl::s{h_win_w},
+ 'int,0,3000', # 0 pixels - 3000 pixels
+ '3.9.0.74',
+ '-1',
+ 'AttRemover',
+ ],
+ arm_winh => [
+ 'win_height',
+ $xl::s{l_win_h},
+ $xl::s{h_win_h},
+ 'int,0,3000', # 0 pixels - 3000 pixels
+ '3.9.0.74',
+ '-1',
+ 'AttRemover',
+ ],
+ # GPG
+ gpg_alimit => [
+ 'autocompletion_limit',
+ $xl::s{l_plu_gpg_alimit},
+ $xl::s{h_plu_gpg_alimit},
+ 'int,0,100',
+ '3.12.0.75',
+ '0',
+ 'GPG',
+ ],
+ # managesieve
+ msv_winw => [
+ 'manager_win_width',
+ $xl::s{l_win_w},
+ $xl::s{h_win_w},
+ 'int,0,3000', # 0 pixels - 3000 pixels
+ '3.11.1.210',
+ '-1',
+ 'ManageSieve',
+ ],
+ msv_winh => [
+ 'manager_win_height',
+ $xl::s{l_win_h},
+ $xl::s{h_win_h},
+ 'int,0,3000', # 0 pixels - 3000 pixels
+ '3.11.1.210',
+ '-1',
+ 'ManageSieve',
+ ],
+ # libravatar
+ lav_burl => [
+ 'base_url',
+ $xl::s{l_plu_lav_burl},
+ $xl::s{h_plu_lav_burl},
+ 'char,0,1024,32',
+ '3.9.3.32',
+ 'http://cdn.libravatar.org/avatar',
+ 'Libravatar',
+ ],
+ # perl
+ prl_flvb => [
+ 'filter_log_verbosity',
+ $xl::s{l_plu_prl_flvb},
+ $xl::s{h_plu_prl_flvb},
+ '0=l_plu_prl_none;1=l_plu_prl_manual;2=l_plu_prl_action;3=l_plu_prl_match',
+ '3.9.0.75',
+ '2',
+ 'PerlPlugin',
+ ],
+);
+
+sub new_plugins_page() {
+ my %frame = ();
+ $frame{'AttRemover'} =
+ new_subpage_frame (
+ new_hbox_pack (
+ new_text_box_for_int (\%pr::plu, 'arm_winw', $PLHPVALUE{'AttRemover'}),
+ new_text_box_for_int (\%pr::plu, 'arm_winh', $PLHPVALUE{'AttRemover'})),
+ _('Attachment remover'), 'not-packed');
+ $frame{'GPG'} =
+ new_subpage_frame (
+ new_hbox_pack (
+ new_text_box_for_int (\%pr::plu, 'gpg_alimit', $PLHPVALUE{'GPG'})),
+ _('GPG'), 'not-packed');
+ $frame{'ManageSieve'} =
+ new_subpage_frame (
+ new_hbox_pack (
+ new_text_box_for_int (\%pr::plu, 'msv_winw', $PLHPVALUE{'ManageSieve'}),
+ new_text_box_for_int (\%pr::plu, 'msv_winh', $PLHPVALUE{'ManageSieve'})),
+ _('Sieve manager'), 'not-packed');
+ $frame{'Libravatar'} =
+ new_subpage_frame (
+ new_hbox_pack (
+ new_text_box_for_nchar (\%pr::plu, 'lav_burl', $PLHPVALUE{'Libravatar'})),
+ _('Libravatar'), 'not-packed');
+ $frame{'PerlPlugin'} =
+ new_subpage_frame (
+ new_hbox_pack (
+ new_selection_box_for (\%pr::plu, 'prl_flvb', $PLHPVALUE{'PerlPlugin'})),
+ _('Perl'), 'not-packed');
+ foreach (@PLUGINS) {
+ $frame{$_}->set_sensitive (defined $PLHPVALUE{$_});
+ }
+ return new_vbox_pack (
+ $frame{'AttRemover'},
+ $frame{'GPG'},
+ $frame{'ManageSieve'},
+ $frame{'Libravatar'},
+ $frame{'PerlPlugin'});
+}
+
+sub new_info_page() {
+ my $t0 = Gtk2::Table->new (7, 2, FALSE);
+ my $v = get_toolkit_versions ();
+ my %labels = (
+ 'glib' => 'Perl-GLib',
+ 'glib-r' => _('GLib runtime'),
+ 'glib-b' => _('GLib built'),
+ 'gtk2' => 'Perl-GTK2',
+ 'gtk2-r' => _('GTK2 runtime'),
+ 'gtk2-b' => _('GTK2 built'),
+ );
+ my $row = 0;
+ foreach (sort keys %$v) {
+ if (defined $v->{$_}) {
+ my $label = Gtk2::Label->new ($labels{$_});
+ my $value = Gtk2::Label->new ('<b>' . $v->{$_} . '</b>');
+ $label->set_alignment (0, 0.5);
+ $value->set_alignment (0, 0.5);
+ $value->set_use_markup (TRUE);
+ $t0->attach ($label, 0, 1, $row, $row + 1, 'fill', 'shrink', 8, 6);
+ $t0->attach ($value, 1, 2, $row, $row + 1, 'fill', 'shrink', 8, 6);
+ ++$row;
+ }
+ }
+ my $t1 = Gtk2::Table->new (2, 2, FALSE);
+ my @lbl = map { $_->set_alignment (0, 0.5); $_ } (
+ Gtk2::Label->new (_('Binary')),
+ Gtk2::Label->new (_('Configuration'))
+ );
+ my $cfgv = $CONFIGDATA->{'Common'}{'config_version'};
+ $cfgv //= '';
+ my @val = map { $_->set_alignment (0, 0.5); $_->set_use_markup (TRUE); $_ } (
+ Gtk2::Label->new ('<b>' . $CLAWSV . '</b>'),
+ Gtk2::Label->new ('<b>' . $cfgv . '</b>')
+ );
+ for (my $i = 0; $i <= $#lbl; ++$i) {
+ $t1->attach ($lbl[$i], 0, 1, $i, $i + 1, 'fill', 'shrink', 8, 6);
+ $t1->attach ($val[$i], 1, 2, $i, $i + 1, 'fill', 'shrink', 8, 6);
+ }
+ return new_vbox_pack (
+ new_subpage_frame ($t0, _('Library versions'), 'not-packed'),
+ new_subpage_frame ($t1, _('Claws Mail versions'), 'not-packed'));
+}
+
# version info
-sub print_version() {
- print $xl::s{about_title} . "\n";
- print $xl::s{about_version} . " $VERSION\n";
- print "Perl-GLib " . $Glib::VERSION;
+sub get_toolkit_versions {
+ my %versions = ();
+ $versions{'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);
+ $versions{'glib-b'} = join('.', Glib->GET_VERSION_INFO);
+ $versions{'glib-r'} = join('.',
+ &Glib::major_version, &Glib::minor_version, &Glib::micro_version);
}
- print "\n";
- print "Perl-GTK2 " . $Gtk2::VERSION;
+ $versions{'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);
+ $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";
+ my $v = get_toolkit_versions ();
+ print "Perl-GLib " . $v->{'glib'};
+ print _(", built for ") . $v->{'glib-b'}
+ . _(", running with ") . $v->{'glib-r'} if $v->{'glib-b'};
+ print "\n";
+ print "Perl-GTK2 " . $v->{'gtk2'};
+ print _(", built for ") . $v->{'gtk2-b'}
+ . _(", running with ") . $v->{'gtk2-r'} if $v->{'gtk2-b'};
print "\n";
my $clawsver = ($CLAWSV eq "") ?
_("was not found!") :
print _("Syntax:\n");
print _(" clawsker [options]\n");
print _("Options:\n");
- print _(" -h|--help Prints this help screen.\n");
- print _(" -v|--version Prints version infos.\n");
- print _(" -b|--verbose More messages on standard output.\n");
print _(" -a|--alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
+ print _(" -b|--verbose More messages on standard output.\n");
print _(" -c|--clawsrc <file> Uses <file> as full resource name.\n");
+ print _(" -h|--help Prints this help screen.\n");
+ print _(" -r|--read-only Disables writing changes to disk.\n");
+ print _(" -v|--version Prints version infos.\n");
}
sub parse_command_line {
return TRUE;
}
+sub init_plu_hidden_preferences {
+ foreach my $key (keys %pr::plu) {
+ my $plugin = $pr::plu{$key}[PLUGIN];
+ my $pname = $pr::plu{$key}[NAME];
+ if (defined $PLPREFS{$plugin}) {
+ $PLHPVALUE{$plugin}{$pname} = $PLPREFS{$plugin}{$pname};
+ }
+ }
+ return TRUE;
+}
+
+# generic load/save resource files
+sub load_resource {
+ my $rc = shift;
+ my %data = ();
+ my %meta = ();
+ my $line = 0;
+ open (RCF, '<:encoding(utf8)', $rc)
+ or die _("Error: opening '{file}' for reading", file => $rc) . ": $!\n";
+ my $section = '_'; # default unnamed section
+ while (<RCF>) {
+ chomp;
+ ++$line;
+ next if (/^\s*$/);
+ if (/^\[([^\]]+)\]$/) { # new section
+ $section = $1;
+ die _("Error: duplicate section '{sect}' in resource file '{file}'\n",
+ sect => $section, file => $rc) if ($data{$section});
+ $data{$section} = {};
+ $meta{$section}{'#'} = $line;
+ }
+ elsif (/^([0-9a-z_]+)=(.*)$/) { # key=value
+ $data{$section}{$1} = $2;
+ $meta{$section}{$1} = $line;
+ }
+ elsif (/^(.*)$/) { # lone value
+ push (@{$data{$section}{'_'}}, $1);
+ }
+ }
+ close (RCF);
+ return (\%data, \%meta);
+}
+
+sub save_resource {
+ my ($rc, $data, $meta) = @_;
+ open (RCF, '>:utf8', $rc)
+ or die _("Error: opening '{file}' for writing", file => $rc) . ": $!\n";
+ my @sections = keys %$data;
+ if (defined $meta) {
+ @sections = sort {
+ $meta->{$a}{'#'} <=> $meta->{$b}{'#'}
+ } @sections
+ }
+ foreach my $section (@sections) {
+ say RCF "[$section]";
+ if (ref ($data->{$section}{'_'}) eq 'ARRAY') {
+ foreach my $val (@{$data->{$section}{'_'}}) {
+ say RCF $val;
+ }
+ } else {
+ my @keys = keys %{$data->{$section}};
+ if (defined $meta) {
+ @keys = sort {
+ $meta->{$section}{$a} <=> $meta->{$section}{$b}
+ } @keys
+ }
+ foreach my $key (@keys) {
+ my $val = $data->{$section}{$key};
+ say RCF "$key=$val";
+ }
+ }
+ say RCF "";
+ }
+ close (RCF);
+}
+
# load current status from disc
sub load_preferences {
my $rc = get_rc_filename ();
log_message ("Loading preferences from $rc\n");
return FALSE unless check_rc_file ($rc);
return FALSE unless check_claws_not_running ();
- open (RCF, "<$rc");
- while (<RCF>) {
- chomp;
- if (/^([8a-z_]+)=(.*)$/) {
- $PREFS{$1} = decode('UTF-8', $2);
+ ($CONFIGDATA, $CONFIGMETA) = load_resource ($rc);
+ foreach (keys %{$CONFIGDATA->{'Common'}}) {
+ $PREFS{$_} = $CONFIGDATA->{'Common'}{$_};
+ }
+ foreach my $plugin (@PLUGINS) {
+ if (defined $CONFIGDATA->{$plugin}) {
+ push (@AVPLUGINS, $plugin);
+ foreach (keys %{$CONFIGDATA->{$plugin}}) {
+ $PLPREFS{$plugin}{$_} = $CONFIGDATA->{$plugin}{$_};
+ }
}
}
- close (RCF);
return TRUE;
}
log_message ("Loading account preferences from $rc\n");
return FALSE unless check_rc_file ($rc);
return FALSE unless check_claws_not_running ();
- open (RCF, "<$rc");
- my $akey;
- while (<RCF>) {
- chomp;
- if (/^\[Account: (\d+)\]$/) {
- $akey = $1;
- next;
- }
- if (/^([8a-z_]+)=(.*)$/) {
- $ACPREFS{$akey}{$1} = decode('UTF-8', $2);
+ ($ACCOUNTDATA, $ACCOUNTMETA) = load_resource ($rc);
+ foreach my $asect (keys %$ACCOUNTDATA) {
+ if ($asect =~ /^Account: (\d+)$/) {
+ foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+ $ACPREFS{$1}{$_} = $ACCOUNTDATA->{$asect}{$_};
+ }
}
}
- close (RCF);
return TRUE;
}
return FALSE unless check_claws_not_running ();
my $rcbak = "$rc.backup";
rename ($rc, $rcbak);
- open (RCF, ">$rc");
- open (RCB, "<$rcbak");
- while (<RCB>) {
- chomp;
- if (/^([8a-z_]+)=(.*)$/) {
- if (defined($HPVALUE{$1})) {
- print RCF $1 . "=" . $HPVALUE{$1} . "\n";
- }
- else {
- print RCF $_ . "\n";
- }
+ foreach (keys %PREFS) {
+ if (defined $HPVALUE{$_}) {
+ $CONFIGDATA->{'Common'}{$_} = $HPVALUE{$_};
}
- else {
- print RCF $_ . "\n";
+ }
+ foreach my $plugin (@AVPLUGINS) {
+ foreach (keys %{$CONFIGDATA->{$plugin}}) {
+ if (defined $PLHPVALUE{$plugin}{$_}) {
+ $CONFIGDATA->{$plugin}{$_} = $PLHPVALUE{$plugin}{$_};
+ }
}
}
- close (RCB);
- close (RCF);
+ save_resource ($rc, $CONFIGDATA, $CONFIGMETA);
return TRUE;
}
return FALSE unless check_claws_not_running ();
my $rcbak = "$rc.backup";
rename ($rc, $rcbak);
- open (RCF, ">$rc");
- open (RCB, "<$rcbak");
- my $akey;
- while (<RCB>) {
- chomp;
- if (/^\[Account: (\d+)\]$/) {
- $akey = $1;
- print RCF $_ . "\n";
- next;
- }
- if (/^([8a-z_]+)=(.*)$/) {
- if (defined($ACHPVALUE{$akey}{$1})) {
- print RCF $1 . "=" . $ACHPVALUE{$akey}{$1} . "\n";
- }
- else {
- print RCF $_ . "\n";
+ foreach my $asect (keys %$ACCOUNTDATA) {
+ if ($asect =~ /^Account: (\d+)$/) {
+ foreach (keys %{$ACCOUNTDATA->{$asect}}) {
+ if (defined $ACHPVALUE{$1}{$_}) {
+ $ACCOUNTDATA->{$asect}{$_} = $ACHPVALUE{$1}{$_};
+ }
}
}
- else {
- print RCF $_ . "\n";
- }
}
- close (RCB);
- close (RCF);
+ save_resource ($rc, $ACCOUNTDATA, $ACCOUNTMETA);
return TRUE;
}
$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;
}
. "<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;
}
}
sub get_app_icons {
- my $dir = $DATADIR . '/icons/hicolor';
- my @names = map {
- join ('/', ($dir, , $_ . 'x' . $_, 'apps', $NAME . '.png'))
- } (64, 128);
- my @icons = ();
+ return @APPICONS if (@APPICONS);
+ my @names;
+ if (-d $DATADIR) { # installed
+ my $dir = $DATADIR . '/icons/hicolor';
+ @names = map {
+ join ('/', ($dir, $_ . 'x' . $_, 'apps', $NAME . '.png'))
+ } (64, 128);
+ } else { # unpacked tarball or git clone
+ @names = map {
+ join ('/', ('./icons', $NAME . '-' . $_ . '.png'));
+ } (64, 128);
+ }
foreach (@names) {
my $icon = undef;
$icon = Gtk2::Gdk::Pixbuf->new_from_file($_) if (-f $_);
- push @icons, $icon if ($icon);
+ push @APPICONS, $icon if ($icon);
}
- return @icons;
+ return @APPICONS;
}
# initialise
exit unless load_ac_preferences ();
exit unless init_hidden_preferences ();
exit unless init_ac_hidden_preferences ();
+exit unless init_plu_hidden_preferences ();
# create main GUI
my $box = Gtk2::VBox->new (FALSE, 5);
$box->set_border_width(3);