tab_winpos => _('Windows'),
tab_accounts => _('Accounts'),
tab_plugins => _('Plugins'),
+ tab_hotkeys => _('Hotkeys'),
tab_info => _('Info'),
ab_frame => _('Addressbook'),
# supported and available plugins lists
my @PLUGINS = qw(AttRemover GPG ManageSieve Libravatar PerlPlugin);
my @AVPLUGINS = ();
+# loaded hotkeys from load_menurc
+my $HOTKEYS;
+# current tree selection
+my $SELHOTKEY;
# loaded icons
my @APPICONS = ();
return $CONFIGDIR . $ACCOUNTRC;
}
+sub get_menurc_filename {
+ return $CONFIGDIR . "menurc";
+}
+
sub set_rc_filename {
my ($fullname) = @_;
my @parts = split ('/', $fullname);
'cache_max_mem_usage',
[ $xl::s{l_oth_max_use}, $xl::s{l_oth_max_use_units} ],
$xl::s{h_oth_max_use},
- 'int,0,262144', # 0 Kb - 256 Mb
+ 'int,0,524288', # 0 Kb - 512 Mb
'0.7.8.36',
'4096',
],
$xl::s{h_gui_warn_send_multi},
'int,0,1000',
'3.14.1.125',
- '0',
+ '3.15.0.28',
],
next_del => [
'next_on_delete',
'#000000',
],
qs_error_bg => [
- '',
+ 'qs_error_bgcolor',
$xl::s{l_col_qs_error_bg},
$xl::s{h_col_qs_error_bg},
- 'qs_error_bgcolor',
+ 'color',
'3.14.1.31',
'#ff7070',
],
qs_error_text => [
- '',
+ 'qs_error_color',
$xl::s{l_col_qs_error_text},
$xl::s{h_col_qs_error_text},
- 'qs_error_color',
+ 'color',
'3.14.1.31',
'#000000',
],
$frame{'PerlPlugin'});
}
+use constant {
+ C_LABEL => 0,
+ C_HOTKEY => 1,
+ C_GROUP => 2,
+ C_ACCEL => 3,
+ C_BCOLOR => 4,
+ # cell backgrounds
+ BG_LIGHTER => '#ffffff',
+ BG_DARKER => '#eeeeee'
+};
+
+sub new_hotkeys_list_label {
+ my $renderer = Gtk2::CellRendererText->new ();
+ $renderer->set_property('alignment' => 'left');
+ $renderer->set_property('editable' => FALSE);
+ $renderer->set_property('size-points' => 8);
+ $renderer->set_property('size-set' => TRUE);
+ return $renderer;
+}
+
+sub new_hotkeys_list_hotkey {
+ my $renderer = Gtk2::CellRendererAccel->new ();
+ $renderer->set_property ('accel-mode' => 'gtk');
+ $renderer->set_property ('editable' => TRUE);
+ $renderer->signal_connect ('accel-edited' => sub {
+ my ($w, $path, $key, $mods, $keycode) = @_;
+ my $accel = Gtk2::Accelerator->name ($key, $mods);
+ my ($model, $iter) = $SELHOTKEY->get_selected ();
+ $model->set($iter, C_HOTKEY, "\"$accel\"");
+ my $gkey = $model->get_value ($iter, C_GROUP);
+ my $akey = $model->get_value ($iter, C_ACCEL);
+ my $data = $HOTKEYS->{$gkey}->{$akey};
+ $data->{'key'} = "\"$accel\"";
+ $data->{'enabled'} = TRUE;
+ });
+ $renderer->signal_connect ('accel-cleared' => sub {
+ my ($w, $path) = @_;
+ my ($model, $iter) = $SELHOTKEY->get_selected ();
+ $model->set($iter, C_HOTKEY, "\"\"");
+ my $gkey = $model->get_value ($iter, C_GROUP);
+ my $akey = $model->get_value ($iter, C_ACCEL);
+ my $data = $HOTKEYS->{$gkey}->{$akey};
+ $data->{'key'} = "\"\"";
+ $data->{'enabled'} = FALSE;
+ });
+ return $renderer;
+}
+
+sub new_hotkeys_list {
+ my ($gkey, $group) = @_;
+ my $store = Gtk2::ListStore->new(
+ qw/Glib::String Glib::String Glib::String Glib::String Glib::String/);
+ my $even = FALSE;
+ foreach my $akey (sort keys %$group) {
+ my $iter = $store->append ();
+ my $hotkey = $group->{$akey}->{'key'};
+ my $label = $akey;
+ $label =~ s/[<>]//g; # <rrsyl> and <IMAPFolder> !?
+ my $bgcol = $even ? BG_DARKER: BG_LIGHTER;
+ $store->set ($iter, C_LABEL, $label, C_HOTKEY, $hotkey,
+ C_GROUP, $gkey, C_ACCEL, $akey, C_BCOLOR, $bgcol);
+ $even = not $even;
+ }
+ my $treeview = Gtk2::TreeView->new_with_model ($store);
+ # labels column
+ $treeview->insert_column_with_data_func (
+ 0, _("Menu path"), new_hotkeys_list_label (),
+ sub {
+ my ($col, $renderer, $model, $iter, $data) = @_;
+ $renderer->set_property (
+ 'text' => $model->get_value ($iter, C_LABEL));
+ $renderer->set_property (
+ 'background' => $model->get_value ($iter, C_BCOLOR));
+ }
+ );
+ # hotkeys column
+ $treeview->insert_column_with_data_func (
+ 1, _('Hotkey'), new_hotkeys_list_hotkey (),
+ sub {
+ my ($col, $renderer, $model, $iter, $data) = @_;
+ my $hkey = $model->get_value ($iter, C_HOTKEY);
+ $hkey =~ s/\"//g;
+ my ($acckey, $accmod) = Gtk2::Accelerator->parse ($hkey);
+ $renderer->set_property ('accel-key' => $acckey);
+ $renderer->set_property ('accel-mods' => $accmod);
+ $renderer->set_property (
+ 'background' => $model->get_value ($iter, C_BCOLOR));
+ }
+ );
+ # callback for saving current selection
+ my $selection = $treeview->get_selection ();
+ $selection->signal_connect ('changed' => sub { $SELHOTKEY = shift });
+ return $treeview;
+}
+
+sub new_hotkeys_page() {
+ my $swin = Gtk2::ScrolledWindow->new ();
+ my $vbox = Gtk2::VBox->new (FALSE, 5);
+ foreach my $gkey (sort keys %$HOTKEYS) {
+ my $group = $HOTKEYS->{$gkey};
+ # group title
+ my $glabel = Gtk2::Label->new ('<b>' . $gkey . '</b>');
+ $glabel->set_use_markup (TRUE);
+ $glabel->set_alignment (0, 0.5);
+ $glabel->set_padding (5, 1);
+ $vbox->pack_start ($glabel, FALSE, FALSE, 0);
+ # group key list
+ my $keylist = new_hotkeys_list ($gkey, $group);
+ $vbox->pack_start ($keylist, FALSE, FALSE, 0);
+ }
+ $swin->set_border_width (5);
+ $swin->set_shadow_type ('none');
+ $swin->set_policy ('automatic', 'always');
+ $swin->add_with_viewport ($vbox);
+ return $swin;
+}
+
sub new_info_page() {
my $t0 = Gtk2::Table->new (7, 2, FALSE);
my $v = get_toolkit_versions ();
close (RCF);
}
+# specific loaders
+sub load_menurc {
+ my $rc = shift;
+ open (RCF, '<:encoding(utf8)', $rc)
+ or die _("Error: opening '{file}' for reading", file => $rc) . ": $!\n";
+ my %groups = ();
+ my $line = 0;
+ while (<RCF>) {
+ chomp;
+ if (/^; \(gtk_accel_path "<([A-Za-z]+)>([^"]+)" ([^\)]+)\)$/) {
+ my %data = ('key' => $3, 'enabled' => FALSE, 'line' => $line);
+ $groups{$1}{$2} = \%data;
+ # say "group -> $1 | path -> $2 | key -> $3";
+ } elsif (/^\(gtk_accel_path "<([A-Za-z]+)>([^"]+)" ([^\)]+)\)$/) {
+ my %data = ('key' => $3, 'enabled' => TRUE, 'line' => $line);
+ $groups{$1}{$2} = \%data;
+ # say "group -> $1 | path -> $2 | key -> $3";
+ }
+ ++$line;
+ }
+ close (RCF);
+ return \%groups;
+}
+
+sub save_menurc {
+ my ($rc, $groups) = @_;
+ my @lines = ();
+ foreach my $gkey (keys %$groups) {
+ my $group = $groups->{$gkey};
+ foreach my $akey (keys %$group) {
+ my $data = $group->{$akey};
+ my $key = $data->{'key'};
+ my $line = $data->{'line'};
+ $lines[$line] = ($data->{'enabled'})? '': '; ';
+ $lines[$line] .= '(gtk_accel_path "<'
+ . $gkey . '>' . $akey . '" ' . $key . ')';
+ }
+ }
+ open (RCF, '>:utf8', $rc)
+ or die _("Error: opening '{file}' for writing", file => $rc) . ": $!\n";
+ say RCF '; claws-mail GtkAccelMap rc-file -*- scheme -*-';
+ say RCF '; this file is an automated accelerator map dump';
+ say RCF ';';
+ foreach (@lines) { say RCF $_ if $_ }
+ close (RCF);
+}
+
# load current status from disc
sub load_rc_preferences {
my $rc = get_rc_filename ();
return TRUE;
}
+sub load_hk_preferences {
+ my $rc = get_menurc_filename ();
+ return FALSE unless check_rc_file ($rc);
+ $HOTKEYS = load_menurc ($rc);
+ return TRUE;
+}
+
sub load_preferences {
return FALSE unless check_claws_not_running ();
- return (load_rc_preferences () and load_ac_preferences ());
+ return (load_rc_preferences ()
+ and load_ac_preferences ()
+ and load_hk_preferences ()
+ );
}
# save current preferences to disc
return TRUE;
}
+sub save_hk_preferences {
+ my $rc = get_menurc_filename ();
+ log_message ("Saving hotkey preferences to $rc\n");
+ return FALSE unless check_rc_file ($rc);
+ return FALSE unless check_claws_not_running ();
+ save_menurc ($rc, $HOTKEYS);
+ return TRUE;
+}
+
# create notebook
sub new_notebook {
my $nb = Gtk2::Notebook->new;
$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_hotkeys_page (), $xl::s{tab_hotkeys});
$nb->append_page (new_info_page (), $xl::s{tab_info});
return $nb;
$b_apply->signal_connect (clicked => sub {
save_preferences ($parent);
save_ac_preferences ($parent);
+ save_hk_preferences ($parent);
});
# $b_undo->signal_connect (clicked => sub { undo_current_changes });
$b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
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_start (new_notebook (), TRUE, TRUE, 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});