10 Clawsker - A Claws Mail Tweaker
18 Clawsker is an applet to edit the so called Claws Mail hidden preferences.
20 Claws Mail is a fast, lightweight and feature-rich MUA with a high number
21 of configurable options. To keep the binary small and fast some of these
22 preferences which not widely used are not provided with a graphical interface
23 for inspection and/or modification.
25 Users wanting to edit such preferences had to face raw edition of their
26 configuration files, now you can do it with a convenient GTK2 interface
31 No options are currently available.
35 Alternate configuration directories are not (yet) supported.
39 Ricardo Mones E<lt>ricardo@mones.orgE<gt>
43 Copyright (c) 2007 by Ricardo Mones
45 This program is free software: you can redistribute it and/or modify
46 it under the terms of the GNU General Public License as published by
47 the Free Software Foundation, either version 3 of the License, or
48 (at your option) any later version.
50 This program is distributed in the hope that it will be useful,
51 but WITHOUT ANY WARRANTY; without even the implied warranty of
52 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
53 GNU General Public License for more details.
55 You should have received a copy of the GNU General Public License
56 along with this program. If not, see E<lt>http://www.gnu.org/licenses/E<gt>.
61 use POSIX qw(setlocale);
63 use Glib qw(TRUE FALSE);
66 my $NAME = 'clawsker';
67 my $PREFIX = '@PREFIX@';
68 my $LIBDIR = '@LIBDIR@';
69 my $VERSION = '@VERSION@';
71 my $locale = (defined($ENV{LC_MESSAGES}) ? $ENV{LC_MESSAGES} : $ENV{LANG});
72 setlocale(LC_ALL, $locale);
73 bindtextdomain(lc($NAME), sprintf('%s/share/locale', $PREFIX));
74 textdomain(lc($NAME));
79 my $xla = gettext($str);
80 if (scalar(keys(%par)) > 0) {
81 foreach my $key (keys %par) {
82 $xla =~ s/\{$key\}/$par{$key}/g;
90 win_title => _('Claws Mail Hidden Preferences'),
91 about => _('About...'),
92 about_title => _('Clawsker :: A Claws Mail Tweaker'),
93 about_license => _('License:'),
94 about_version => _('Version:'),
96 tab_colours => _('Colours'),
97 tab_behaviour => _('Behaviour'),
99 tab_other => _('Other'),
101 ab_frame => _('Addressbook'),
102 mem_frame => _('Memory'),
103 msgview_frame => _('Message view'),
104 log_frame => _('Log window'),
105 dnd_frame => _('Drag and drop'),
106 ssl_frame => _('Secure Sockets Layer'),
107 msgs_frame => _('Messages'),
108 stripes_frame => _('Coloured stripes'),
109 sbar_frame => _('Scroll bars'),
110 mlist_frame => _('Message list'),
112 l_oth_use_dlg => _('Use address book dialog'),
113 h_oth_use_dlg => _('If true use a separate dialogue to edit a person\'s details. Otherwise will use a form embedded in the addressbook\'s main window.'),
114 l_oth_max_use => _('Maximum memory for message cache (Kb)'),
115 h_oth_max_use => _('The maximum amount of memory to use to cache messages, in kB.'),
116 l_oth_min_time => _('Minimun time for cache elements (minutes)'),
117 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.'),
119 l_gui_b_unread => _('Show unread messages with bold font'),
120 h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
121 l_gui_no_markup => _('Don\'t use markup in compose window'),
122 h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
123 l_gui_dot_lines => _('Use dotted lines in tree views'),
124 h_gui_dot_lines => _('Use the old dotted line look in the main window tree views (folder and message lists) instead of the modern lineless look.'),
125 l_gui_h_scroll => _('Enable horizontal scrollbar'),
126 h_gui_h_scroll => _('Enable the horizontal scrollbar in the Message List.'),
127 l_gui_swp_from => _('Swap From field in Sent folder'),
128 h_gui_swp_from => _('Display the sender\'s email address in the To column of the Sent folder instead of the recipient\'s.'),
129 l_gui_v_scroll => _('Folder list scrollbar behaviour'),
130 h_gui_v_scroll => _('Specify the policy of vertical scrollbar of Folder List: show always, automatic or hide always.'),
131 l_gui_v_scroll_show => _('Show always'),
132 l_gui_v_scroll_auto => _('Automatic'),
133 l_gui_v_scroll_hide => _('Hide always'),
134 l_gui_strip_off => _('Striped lines contrast'),
135 h_gui_strip_off => _('Specify the value to use when creating alternately coloured lines in tree view components. The smaller the value, the less visible the difference in the alternating colours of the lines.'),
136 l_gui_cursor_v => _('Cursor visible in message view'),
137 h_gui_cursor_v => _('Display the cursor in the message view.'),
138 l_gui_toolbar_d => _('Detachable toolbars'),
139 h_gui_toolbar_d => _('Show handles in the toolbars.'),
140 l_gui_strip_all => _('Use stripes in tree view components'),
141 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
142 l_gui_strip_sum => _('Use stripes in summary view'),
143 h_gui_strip_sum => _('Enable alternately coloured lines in summary view and folder list'),
145 l_beh_hover_t => _('Drag and drop hover timeout (ms)'),
146 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.'),
147 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
148 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
149 l_beh_flowed => _('Respect flowed format in messages'),
150 h_beh_flowed => _('Respect format=flowed on text/plain message parts. This will cause some mails to have long lines, but will fix some URLs that would otherwise be wrapped.'),
151 l_beh_parts_rw => _('Allow writable temporary files'),
152 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
153 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
154 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
155 l_beh_up_step => _('Progress update step (items)'),
156 h_beh_up_step => _('Update stepping in progress bars.'),
157 l_beh_thread_a => _('Maximum age in threading by subject (days)'),
158 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
159 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
160 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
161 l_beh_use_utf8 => _('Use UTF-8 in broken mails'),
162 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
163 l_beh_warn_dnd => _('Warning on drag and drop'),
164 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
166 l_col_emphasis => _('Emphasised X-Mailer colour'),
167 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
168 l_col_log_err => _('Errors colour'),
169 h_col_log_err => _('Colour for error messages in log window.'),
170 l_col_log_in => _('Input colour'),
171 h_col_log_in => _('Colour for input messages in log window.'),
172 l_col_log_msg => _('Messages colour'),
173 h_col_log_msg => _('Colour for messages in log window.'),
174 l_col_log_out => _('Output colour'),
175 h_col_log_out => _('Colour for output messages in log window.'),
176 l_col_log_warn => _('Warnings colour'),
177 h_col_log_warn => _('Colour for warning messages in log window.'),
179 e_error => _('Error: '),
180 e_noclawsrc => _('no $HOME/.claws-mail/clawsrc file found.'),
181 e_running => _('seems Claws Mail is currently running, close it first.'),
184 # check if claws is running
185 my $socket = "/tmp/claws-mail-$<";
186 -S $socket and die "$xl::s{e_error}$xl::s{e_running}\n";
188 # all preferences read by load_preferences
190 # values of all preferences handled by clawsker
193 # index constants for preference arrays
194 use constant NAME => 0; # the name on the rc file
195 use constant LABEL => 1; # the label on the GUI
196 use constant DESC => 2; # the description for the hint/help
197 use constant TYPE => 3; # data type: bool, int, float, string, color
198 use constant GUI => 4; # GUI element
200 # constants for GUI spacing
201 use constant HBOX_SPC => 5;
202 use constant FRAME_SPC => 2;
203 use constant PAGE_SPC => 5;
205 # data handlers and auxiliar functions
207 sub handle_bool_value {
208 my ($widget, $event, $dataref) = @_;
209 $$dataref = ($widget->get_active ())? '1': '0';
212 sub handle_int_value {
213 my ($widget, $event, $dataref) = @_;
214 $_ = $widget->get_text ();
219 $widget->set_text ($_);
222 $widget->set_text ($$dataref);
226 sub handle_string_value {
227 my ($widget, $event, $dataref) = @_;
228 $$dataref = $widget->get_text ();
231 sub gdk_color_from_str {
233 my ($rr, $gg, $bb) = (0, 0 ,0);
235 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
240 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
244 sub str_from_gdk_color {
246 my $rr = $color->red / 256;
247 my $gg = $color->green / 256;
248 my $bb = $color->blue / 256;
249 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
253 sub handle_color_value {
254 my ($widget, $event, $dataref) = @_;
255 my $newcol = $widget->get_color;
256 $$dataref = &str_from_gdk_color ($newcol);
259 sub handle_selection_value {
260 my ($widget, $event, $dataref) = @_;
261 $$dataref = $widget->get_active;
264 # graphic element creation
266 sub new_check_button_for {
267 my ($hash, $key) = @_;
268 my $name = $$hash{$key}[NAME];
269 my $label = $$hash{$key}[LABEL];
271 my $hbox = Gtk2::HBox->new (FALSE, 5);
272 my $cb = Gtk2::CheckButton->new ($label);
273 $$hash{$key}[GUI] = $cb;
274 $cb->set_active ($HPVALUE{$name} eq '1');
275 $cb->signal_connect (clicked => sub {
277 &handle_bool_value($w, $e, \$HPVALUE{$name});
279 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
284 sub new_text_box_for {
285 my ($hash, $key) = @_;
286 my $name = $$hash{$key}[NAME];
287 my $label = $$hash{$key}[LABEL];
289 my $hbox = Gtk2::HBox->new (FALSE, 5);
290 my $glabel = Gtk2::Label->new ($label);
291 my $gentry = Gtk2::Entry->new;
292 $gentry->set_width_chars (8);
293 $$hash{$key}[GUI] = $gentry;
294 $gentry->set_text($HPVALUE{$name});
295 $gentry->signal_connect(changed => sub {
297 &handle_int_value($w, $e, \$HPVALUE{$name}); # FIXME int only
299 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
300 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
305 sub new_color_button_for {
306 my ($hash, $key) = @_;
307 my $name = $$hash{$key}[NAME];
308 my $label = $$hash{$key}[LABEL];
310 my $col = &gdk_color_from_str ($HPVALUE{$name});
311 my $hbox = Gtk2::HBox->new (FALSE, 5);
312 my $glabel = Gtk2::Label->new ($label);
313 my $button = Gtk2::ColorButton->new_with_color ($col);
314 $$hash{$key}[GUI] = $button;
315 $button->set_title ($label);
316 $button->set_relief ('none');
317 $button->signal_connect ('color-set' => sub {
319 &handle_color_value($w, $e, \$HPVALUE{$name});
321 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
322 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
327 sub new_selection_box_for {
328 my ($hash, $key) = @_;
329 my $name = $$hash{$key}[NAME];
330 my $label = $$hash{$key}[LABEL];
332 my $hbox = Gtk2::HBox->new (FALSE, 5);
333 my $glabel = Gtk2::Label->new ($label);
334 my $combo = Gtk2::ComboBox->new_text;
335 $$hash{$key}[GUI] = $combo;
336 my @options = split (';', $$hash{$key}[TYPE]);
337 foreach my $opt (@options) {
338 my ($index, $textkey) = split ('=', $opt);
339 $combo->insert_text ($index, $xl::s{$textkey});
341 $combo->signal_connect ('changed' => sub {
343 &handle_selection_value($w, $e, \$HPVALUE{$name});
345 $combo->set_active ($HPVALUE{$name});
346 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
347 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
352 # preference maps and corresponding page creation subs
354 %pr::oth = ( # other preferences
356 'addressbook_use_editaddress_dialog',
357 $xl::s{l_oth_use_dlg},
358 $xl::s{h_oth_use_dlg},
363 'cache_max_mem_usage',
364 $xl::s{l_oth_max_use},
365 $xl::s{h_oth_max_use},
370 'cache_min_keep_time',
371 $xl::s{l_oth_min_time},
372 $xl::s{h_oth_min_time},
378 sub new_other_page() {
379 my $of = Gtk2::VBox->new (FALSE, 5);
380 $of->set_border_width (PAGE_SPC);
382 my $ab_frame = Gtk2::Frame->new ($xl::s{ab_frame});
383 my $cb_use_dlg = &new_check_button_for(\%pr::oth, 'use_dlg');
384 my $vb1 = Gtk2::VBox->new (FALSE, 5);
385 $vb1->set_border_width (PAGE_SPC);
386 $vb1->pack_start ($cb_use_dlg, FALSE, FALSE, 0);
387 $ab_frame->add ($vb1);
389 my $mem_frame = Gtk2::Frame->new ($xl::s{mem_frame});
390 my $tb_max_use = &new_text_box_for(\%pr::oth, 'max_use');
391 my $tb_min_time = &new_text_box_for(\%pr::oth, 'min_time');
392 my $vb2 = Gtk2::VBox->new (FALSE, 5);
393 $vb2->set_border_width (PAGE_SPC);
394 $vb2->pack_start ($tb_max_use, FALSE, FALSE, 0);
395 $vb2->pack_start ($tb_min_time, FALSE, FALSE, 0);
396 $mem_frame->add ($vb2);
398 $of->pack_start ($ab_frame, FALSE, FALSE, FRAME_SPC);
399 $of->pack_start ($mem_frame, FALSE, FALSE, FRAME_SPC);
404 %pr::gui = ( # gui bells and whistles
407 $xl::s{l_gui_b_unread},
408 $xl::s{h_gui_b_unread},
414 $xl::s{l_gui_no_markup},
415 $xl::s{h_gui_no_markup},
420 'enable_dotted_lines',
421 $xl::s{l_gui_dot_lines},
422 $xl::s{h_gui_dot_lines},
428 $xl::s{l_gui_h_scroll},
429 $xl::s{h_gui_h_scroll},
435 $xl::s{l_gui_swp_from},
436 $xl::s{h_gui_swp_from},
441 'folderview_vscrollbar_policy',
442 $xl::s{l_gui_v_scroll},
443 $xl::s{h_gui_v_scroll},
444 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
448 'stripes_color_offset',
449 $xl::s{l_gui_strip_off},
450 $xl::s{h_gui_strip_off},
455 'textview_cursor_visible',
456 $xl::s{l_gui_cursor_v},
457 $xl::s{h_gui_cursor_v},
462 'toolbar_detachable',
463 $xl::s{l_gui_toolbar_d},
464 $xl::s{h_gui_toolbar_d},
469 'use_stripes_everywhere',
470 $xl::s{l_gui_strip_all},
471 $xl::s{h_gui_strip_all},
476 'use_stripes_in_summaries',
477 $xl::s{l_gui_strip_sum},
478 $xl::s{h_gui_strip_sum},
485 my $gf = Gtk2::VBox->new (FALSE, 5);
486 $gf->set_border_width (PAGE_SPC);
488 my $stripes_frame = Gtk2::Frame->new ($xl::s{stripes_frame});
489 my $cb_strip_all = &new_check_button_for (\%pr::gui, 'strip_all');
490 my $cb_strip_sum = &new_check_button_for (\%pr::gui, 'strip_sum');
491 my $tb_strip_off = &new_text_box_for (\%pr::gui, 'strip_off');
492 my $vb1 = Gtk2::VBox->new (FALSE, 5);
493 $vb1->set_border_width (PAGE_SPC);
494 $vb1->pack_start ($cb_strip_all, FALSE, FALSE, 0);
495 $vb1->pack_start ($cb_strip_sum, FALSE, FALSE, 0);
496 $vb1->pack_start ($tb_strip_off, FALSE, FALSE, 0);
497 $stripes_frame->add ($vb1);
499 my $mlist_frame = Gtk2::Frame->new ($xl::s{mlist_frame});
500 my $cb_b_unread = &new_check_button_for (\%pr::gui, 'b_unread');
501 my $cb_swp_from = &new_check_button_for (\%pr::gui, 'swp_from');
502 my $vb3 = Gtk2::VBox->new (FALSE, 5);
503 $vb3->set_border_width (PAGE_SPC);
504 $vb3->pack_start ($cb_b_unread, FALSE, FALSE, 0);
505 $vb3->pack_start ($cb_swp_from, FALSE, FALSE, 0);
506 $mlist_frame->add ($vb3);
508 my $sbar_frame = Gtk2::Frame->new ($xl::s{sbar_frame});
509 my $cb_h_scroll = &new_check_button_for (\%pr::gui, 'h_scroll');
510 my $sb_v_scroll = &new_selection_box_for (\%pr::gui, 'v_scroll');
511 my $vb2 = Gtk2::VBox->new (FALSE, 5);
512 $vb2->set_border_width (PAGE_SPC);
513 $vb2->pack_start ($cb_h_scroll, FALSE, FALSE, 0);
514 $vb2->pack_start ($sb_v_scroll, FALSE, FALSE, 0);
515 $sbar_frame->add ($vb2);
517 my $cb_no_markup = &new_check_button_for (\%pr::gui, 'no_markup');
518 my $cb_dot_lines = &new_check_button_for (\%pr::gui, 'dot_lines');
519 my $cb_cursor_v = &new_check_button_for (\%pr::gui, 'cursor_v');
520 my $cb_toolbar_d = &new_check_button_for (\%pr::gui, 'toolbar_d');
522 $gf->pack_start ($stripes_frame, FALSE, FALSE, FRAME_SPC);
523 $gf->pack_start ($mlist_frame, FALSE, FALSE, FRAME_SPC);
524 $gf->pack_start ($cb_no_markup, FALSE, FALSE, 0);
525 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
526 $gf->pack_start ($cb_cursor_v, FALSE, FALSE, 0);
527 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
528 $gf->pack_start ($sbar_frame, FALSE, FALSE, FRAME_SPC);
533 %pr::beh = ( # tweak some behaviour
536 $xl::s{l_beh_hover_t},
537 $xl::s{h_beh_hover_t},
543 $xl::s{l_beh_dangerous},
544 $xl::s{h_beh_dangerous},
549 'respect_flowed_format',
550 $xl::s{l_beh_flowed},
551 $xl::s{h_beh_flowed},
556 'save_parts_readwrite',
557 $xl::s{l_beh_parts_rw},
558 $xl::s{h_beh_parts_rw},
563 'skip_ssl_cert_check',
564 $xl::s{l_beh_skip_ssl},
565 $xl::s{h_beh_skip_ssl},
570 'statusbar_update_step',
571 $xl::s{l_beh_up_step},
572 $xl::s{h_beh_up_step},
577 'thread_by_subject_max_age',
578 $xl::s{l_beh_thread_a},
579 $xl::s{h_beh_thread_a},
585 $xl::s{l_beh_unsafe_ssl},
586 $xl::s{h_beh_unsafe_ssl},
591 'utf8_instead_of_locale_for_broken_mail',
592 $xl::s{l_beh_use_utf8},
593 $xl::s{h_beh_use_utf8},
599 $xl::s{l_beh_warn_dnd},
600 $xl::s{h_beh_warn_dnd},
606 sub new_behaviour_page() {
607 my $bf = Gtk2::VBox->new (FALSE, 5);
608 $bf->set_border_width (PAGE_SPC);
610 my $dnd_frame = Gtk2::Frame->new ($xl::s{dnd_frame});
611 my $tb_hoover_t = &new_text_box_for (\%pr::beh, 'hover_t');
612 my $cb_warn_dnd = &new_check_button_for (\%pr::beh, 'warn_dnd');
613 my $vb1 = Gtk2::VBox->new (FALSE, 5);
614 $vb1->set_border_width (PAGE_SPC);
615 $vb1->pack_start ($cb_warn_dnd, FALSE, FALSE, 0);
616 $vb1->pack_start ($tb_hoover_t, FALSE, FALSE, 0);
617 $dnd_frame->add ($vb1);
619 my $ssl_frame = Gtk2::Frame->new ($xl::s{ssl_frame});
620 my $cb_skip_ssl = &new_check_button_for (\%pr::beh, 'skip_ssl');
621 my $cb_unsafe_ssl = &new_check_button_for (\%pr::beh, 'unsafe_ssl');
622 my $hb1 = Gtk2::HBox->new (FALSE, 5);
623 $hb1->set_border_width (PAGE_SPC);
624 $hb1->pack_start ($cb_skip_ssl, FALSE, FALSE, 0);
625 $hb1->pack_start ($cb_unsafe_ssl, FALSE, FALSE, 0);
626 $ssl_frame->add ($hb1);
628 my $tb_up_step = &new_text_box_for (\%pr::beh, 'up_step');
629 my $tb_thread_a = &new_text_box_for (\%pr::beh, 'thread_a');
631 my $msgs_frame = Gtk2::Frame->new ($xl::s{msgs_frame});
632 my $cb_flowed = &new_check_button_for (\%pr::beh, 'flowed');
633 my $cb_parts_rw = &new_check_button_for (\%pr::beh, 'parts_rw');
634 my $cb_use_utf8 = &new_check_button_for (\%pr::beh, 'use_utf8');
635 my $cb_dangerous = &new_check_button_for (\%pr::beh, 'dangerous');
636 my $vb2 = Gtk2::VBox->new (FALSE, 5);
637 $vb2->set_border_width (PAGE_SPC);
638 $vb2->pack_start ($cb_flowed, FALSE, FALSE, 0);
639 $vb2->pack_start ($cb_parts_rw, FALSE, FALSE, 0);
640 $vb2->pack_start ($cb_use_utf8, FALSE, FALSE, 0);
641 $vb2->pack_start ($cb_dangerous, FALSE, FALSE, 0);
642 $msgs_frame->add ($vb2);
644 $bf->pack_start ($dnd_frame, FALSE, FALSE, FRAME_SPC);
645 $bf->pack_start ($ssl_frame, FALSE, FALSE, FRAME_SPC);
646 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
647 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
648 $bf->pack_start ($msgs_frame, FALSE, FALSE, FRAME_SPC);
653 %pr::col = ( # a variety of colours
656 $xl::s{l_col_emphasis},
657 $xl::s{h_col_emphasis},
663 $xl::s{l_col_log_err},
664 $xl::s{h_col_log_err},
670 $xl::s{l_col_log_in},
671 $xl::s{h_col_log_in},
677 $xl::s{l_col_log_msg},
678 $xl::s{h_col_log_msg},
684 $xl::s{l_col_log_out},
685 $xl::s{h_col_log_out},
691 $xl::s{l_col_log_warn},
692 $xl::s{h_col_log_warn},
698 sub new_colours_page() {
699 my $cf = Gtk2::VBox->new (FALSE, 5);
700 $cf->set_border_width (PAGE_SPC);
702 my $msgview_frame = Gtk2::Frame->new ($xl::s{msgview_frame});
703 my $cb_emphasis = &new_color_button_for (\%pr::col, 'emphasis');
704 my $vb1 = Gtk2::VBox->new (FALSE, 5);
705 $vb1->set_border_width (PAGE_SPC);
706 $vb1->pack_start ($cb_emphasis, FALSE, FALSE, 0);
707 $msgview_frame->add ($vb1);
709 my $log_frame = Gtk2::Frame->new ($xl::s{log_frame});
710 my $cb_log_err = &new_color_button_for (\%pr::col, 'log_err');
711 my $cb_log_in = &new_color_button_for (\%pr::col, 'log_in');
712 my $cb_log_msg = &new_color_button_for (\%pr::col, 'log_msg');
713 my $cb_log_out = &new_color_button_for (\%pr::col, 'log_out');
714 my $cb_log_warn = &new_color_button_for (\%pr::col, 'log_warn');
715 my $vb2 = Gtk2::VBox->new (FALSE, 5);
716 $vb2->set_border_width (PAGE_SPC);
717 $vb2->pack_start ($cb_log_err, FALSE, FALSE, 0);
718 $vb2->pack_start ($cb_log_in, FALSE, FALSE, 0);
719 $vb2->pack_start ($cb_log_msg, FALSE, FALSE, 0);
720 $vb2->pack_start ($cb_log_out, FALSE, FALSE, 0);
721 $vb2->pack_start ($cb_log_warn, FALSE, FALSE, 0);
722 $log_frame->add ($vb2);
724 $cf->pack_start ($msgview_frame, FALSE, FALSE, 0);
725 $cf->pack_start ($log_frame, FALSE, FALSE, 0);
730 # update the hidden preferences status from loaded values
731 sub init_hidden_preferences() {
732 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth) {
733 foreach my $key (keys %$hash) {
734 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
739 # load current status from disc
740 sub load_preferences() {
741 my $rc = $ENV{HOME} . '/.claws-mail/clawsrc';
742 -f $rc or die "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
746 if (/^([8a-z_]+)=(.*)$/) {
753 # save current preferences to disc
754 sub save_preferences() {
755 my $rc = $ENV{HOME} . '/.claws-mail/clawsrc';
756 my $rcbak = "$rc.backup";
757 rename ($rc, $rcbak);
759 open (RCB, "<$rcbak");
762 if (/^([8a-z_]+)=(.*)$/) {
763 if (defined($HPVALUE{$1})) {
764 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
780 my $nb = Gtk2::Notebook->new;
782 $nb->append_page (&new_behaviour_page, $xl::s{tab_behaviour});
783 $nb->append_page (&new_colours_page, $xl::s{tab_colours});
784 $nb->append_page (&new_gui_page, $xl::s{tab_gui});
785 $nb->append_page (&new_other_page, $xl::s{tab_other});
790 # create an about dialog
791 sub new_about_dialog() {
793 my $title = $xl::s{about_title};
794 my $lic = $xl::s{about_license};
795 my $vers = $xl::s{about_version} . " $VERSION";
797 "This program is free software: you can redistribute it and/or modify
798 it under the terms of the GNU General Public License as published by
799 the Free Software Foundation, either version 3 of the License, or
800 (at your option) any later version.
802 This program is distributed in the hope that it will be useful,
803 but WITHOUT ANY WARRANTY; without even the implied warranty of
804 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
805 GNU General Public License for more details.
807 You should have received a copy of the GNU General Public License
808 along with this program. If not, see <http://www.gnu.org/licenses/>.";
810 my $holder = "Ricardo Mones <ricardo\@mones.org>";
812 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
813 [qw/modal destroy-with-parent/],
815 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
816 . "<span size=\"large\">$vers</span>\n"
817 . "<span>Copyright $year by $holder</span>\n\n"
818 . "<span size=\"large\">$lic</span>\n\n"
819 . "<span size=\"small\">$license</span>");
820 $dialog->set_title ($xl::s{about});
826 sub new_button_box() {
828 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
829 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
830 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
831 # disable button until is really implemented
832 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
833 my $hbox = Gtk2::HBox->new (FALSE, 5);
835 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
836 $b_apply->signal_connect (clicked => sub { &save_preferences });
837 # $b_undo->signal_connect (clicked => sub { &undo_current_changes });
838 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
840 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
841 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
842 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
843 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
850 &init_hidden_preferences;
852 my $window = Gtk2::Window->new ('toplevel');
853 my $box = Gtk2::VBox->new (FALSE, 5);
854 $box->set_border_width(3);
855 my $about = &new_about_dialog;
856 $box->pack_start (&new_notebook, FALSE, FALSE, 0);
857 $box->pack_end (&new_button_box ($about), FALSE, FALSE, 0);
858 $window->signal_connect (delete_event => sub { Gtk2->main_quit });
859 $window->set_title ($xl::s{win_title});