3 # Clawsker :: A Claws Mail Tweaker
7 use Glib qw(TRUE FALSE);
9 use POSIX qw(setlocale);
13 my $NAME = 'clawsker';
14 my $PREFIX = '@PREFIX@';
15 my $LIBDIR = '@LIBDIR@';
16 my $VERSION = '@VERSION@';
19 my $main_window = undef;
21 my $locale = (defined($ENV{LC_MESSAGES}) ? $ENV{LC_MESSAGES} : $ENV{LANG});
22 $locale = "C" unless defined($locale);
23 setlocale (LC_ALL, $locale);
24 bindtextdomain ($NAME, sprintf ('%s/share/locale', $PREFIX));
27 my $SHOWHINTS = FALSE;
28 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
33 my $xla = gettext ($str);
34 if (scalar(keys(%par)) > 0) {
35 foreach my $key (keys %par) {
36 $xla =~ s/\{$key\}/$par{$key}/g;
39 return decode_utf8($xla);
44 win_title => _('Claws Mail Hidden Preferences'),
45 about => _('About...'),
46 about_title => _('Clawsker :: A Claws Mail Tweaker'),
47 about_license => _('License:'),
48 about_version => _('Version:'),
50 tab_colours => _('Colours'),
51 tab_behaviour => _('Behaviour'),
53 tab_other => _('Other'),
54 tab_winpos => _('Windows'),
56 ab_frame => _('Addressbook'),
57 mem_frame => _('Memory'),
58 msgview_frame => _('Message View'),
59 log_frame => _('Log window'),
60 dnd_frame => _('Drag \'n\' drop'),
61 ssl_frame => _('Secure Sockets Layer'),
62 msgs_frame => _('Messages'),
63 stripes_frame => _('Coloured stripes'),
64 sbar_frame => _('Scroll bars'),
65 mlist_frame => _('Message List'),
66 mview_frame => _('Message View'),
67 compo_frame => _('Compose window'),
68 netm_frame => _('NetworkManager'),
70 l_oth_use_dlg => _('Use detached address book edit dialogue'),
71 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.'),
72 l_oth_max_use => _('Maximum memory for message cache (kB)'),
73 h_oth_max_use => _('The maximum amount of memory to use to cache messages, in kilobytes.'),
74 l_oth_min_time => _('Minimun time for cache elements (minutes)'),
75 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.'),
76 l_oth_use_netm => _('Use NetworkManager'),
77 h_oth_use_netm => _('Use NetworkManager to switch offline automatically.'),
79 l_gui_b_unread => _('Show unread messages with bold font'),
80 h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
81 l_gui_no_markup => _('Don\'t use markup in compose window'),
82 h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
83 l_gui_dot_lines => _('Use dotted lines in tree view components'),
84 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.'),
85 l_gui_h_scroll => _('Enable horizontal scrollbar'),
86 h_gui_h_scroll => _('Enable the horizontal scrollbar in the Message List.'),
87 l_gui_swp_from => _('Display To column instead From column in Sent folder'),
88 h_gui_swp_from => _('Display the recipient\'s email address in a To column of the Sent folder instead of the originator\'s one in a From column.'),
89 l_gui_v_scroll => _('Folder List scrollbar behaviour'),
90 h_gui_v_scroll => _('Specify the policy of vertical scrollbar of Folder List: show always, automatic or hide always.'),
91 l_gui_v_scroll_show => _('Show always'),
92 l_gui_v_scroll_auto => _('Automatic'),
93 l_gui_v_scroll_hide => _('Hide always'),
94 l_gui_from_show => _('From column displays'),
95 h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both'),
96 l_gui_from_show_name => _('Name only'),
97 l_gui_from_show_addr => _('Address only'),
98 l_gui_from_show_both => _('Both name and address'),
99 l_gui_strip_off => _('Coloured lines contrast'),
100 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.'),
101 l_gui_cursor_v => _('Show cursor'),
102 h_gui_cursor_v => _('Display the cursor in the Message View.'),
103 l_gui_toolbar_d => _('Detachable toolbars'),
104 h_gui_toolbar_d => _('Show handles in the toolbars.'),
105 l_gui_strip_all => _('Use stripes in all tree view components'),
106 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
107 l_gui_strip_sum => _('Use stripes in Folder List and Message List'),
108 h_gui_strip_sum => _('Enable alternately coloured lines in Message List and Folder List.'),
109 l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
110 h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
111 l_gui_margin_co => _('Show compose margin'),
112 h_gui_margin_co => _('Shows a small margin in the Compose View.'),
113 l_gui_mview_date => _('Don\'t display localized date'),
114 h_gui_mview_date => _('Toggles localization of date format in Message View'),
116 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
117 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.'),
118 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
119 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
120 l_beh_flowed => _('Respect format=flowed in messages'),
121 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.'),
122 l_beh_parts_rw => _('Allow writable temporary files'),
123 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
124 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
125 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
126 l_beh_up_step => _('Progress bar update step (items)'),
127 h_beh_up_step => _('Update stepping in progress bars.'),
128 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
129 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
130 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
131 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
132 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
133 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
134 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
135 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
136 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
137 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
138 l_beh_pp_unsel => _('Primary paste unselects selection'),
139 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
140 l_beh_inline_at => _('Show inline attachments'),
141 h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
143 l_col_emphasis => _('X-Mailer header'),
144 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
145 l_col_log_err => _('Error messages'),
146 h_col_log_err => _('Colour for error messages in log window.'),
147 l_col_log_in => _('Server messages'),
148 h_col_log_in => _('Colour for messages received from servers in log window.'),
149 l_col_log_msg => _('Standard messages'),
150 h_col_log_msg => _('Colour for messages in log window.'),
151 l_col_log_out => _('Client messages'),
152 h_col_log_out => _('Colour for messages sent to servers in log window.'),
153 l_col_log_warn => _('Warnings'),
154 h_col_log_warn => _('Colour for warning messages in log window.'),
156 l_win_x => _('X position'),
157 h_win_x => _('X coordinate for window\'s top-left corner.'),
158 l_win_y => _('Y position'),
159 h_win_y => _('Y coordinate for window\'s top-left corner.'),
160 l_win_w => _('Width'),
161 h_win_w => _('Window\'s width in pixels.'),
162 l_win_h => _('Height'),
163 h_win_h => _('Window\'s height in pixels.'),
165 l_win_main_mx => _('Maximized'),
166 h_win_main_mx => _('Changes window maximized status.'),
167 l_win_main_fs => _('Full-screen'),
168 h_win_main_fs => _('Changes full screen status.'),
170 e_error => _('Error: '),
171 e_noclawsrc => _('resource file for Claws Mail was not found.'),
172 e_running => _('seems Claws Mail is currently running, close it first.'),
173 e_requireddir => _('option requires a directory name.'),
174 e_requiredfile => _('option requires a file name.'),
175 e_notadir => _('specified name is not a directory or does not exist.'),
176 e_notafile => _('specified name is not a file or does not exist.'),
179 # all preferences read by load_preferences
181 # values of all preferences handled by clawsker
183 # default config dir and file name
184 my $ALTCONFIGDIR = FALSE;
185 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
186 my $CONFIGRC = 'clawsrc';
188 # index constants for preference arrays
189 use constant NAME => 0; # the name on the rc file
190 use constant LABEL => 1; # the label on the GUI
191 use constant DESC => 2; # the description for the hint/help
192 use constant TYPE => 3; # data type: bool, int, float, string, color
193 use constant CMVER => 4; # lowest Claws Mail version the feature exists
194 use constant CMDEF => 5; # default value for the preference in Claws Mail
195 use constant GUI => 6; # GUI element
197 # constants for GUI spacing
198 use constant HBOX_SPC => 5;
199 use constant FRAME_SPC => 2;
200 use constant PAGE_SPC => 5;
204 sub version_greater_or_equal() {
205 my ($version, $refvers) = @_;
206 my @version = split (/\./, $version);
207 my @refvers = split (/\./, $refvers);
208 while ($#version < $#refvers) {
209 push (@version, '0');
212 while (($idx <= $#refvers)
213 and (int ($version[$idx]) == int ($refvers[$idx]))) {
216 return TRUE if (($idx > $#refvers)
217 or (int ($version[$idx]) >= int ($refvers[$idx])));
221 sub get_claws_version() {
226 foreach my $bin (@cmbin) {
231 return "" unless ($_); # not installed
234 my @fver = split (/ /);
235 die "Invalid version string" unless ($fver[2] eq "version");
236 my @ver = split (/\./, $fver[3]);
239 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
248 # data handlers and auxiliar functions
250 sub handle_bool_value {
251 my ($widget, $event, $dataref) = @_;
252 $$dataref = ($widget->get_active ())? '1': '0';
255 sub handle_int_value {
256 my ($widget, $event, $dataref) = @_;
257 $_ = $widget->get_text ();
262 $widget->set_text ($_);
265 $widget->set_text ($$dataref);
269 sub handle_string_value {
270 my ($widget, $event, $dataref) = @_;
271 $$dataref = $widget->get_text ();
274 sub gdk_color_from_str {
276 my ($rr, $gg, $bb) = (0, 0 ,0);
278 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
283 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
287 sub str_from_gdk_color {
289 my $rr = $color->red / 256;
290 my $gg = $color->green / 256;
291 my $bb = $color->blue / 256;
292 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
296 sub handle_color_value {
297 my ($widget, $event, $dataref) = @_;
298 my $newcol = $widget->get_color;
299 $$dataref = &str_from_gdk_color ($newcol);
302 sub handle_selection_value {
303 my ($widget, $event, $dataref) = @_;
304 $$dataref = $widget->get_active;
307 sub get_rc_filename {
308 return $CONFIGDIR . $CONFIGRC;
311 sub set_rc_filename {
313 my @parts = split ('/', $fullname);
314 $CONFIGRC = $parts[$#parts];
315 $parts[$#parts] = '';
316 $CONFIGDIR = join ('/', @parts);
320 my ($mesg, $fatal) = @_;
321 if (defined($fatal) && $fatal eq 'die') {
322 die "$NAME: $mesg\n";
325 print "$NAME: $mesg\n";
331 my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
332 my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
333 $errordlg->set_title (_('Error message'));
338 sub check_claws_not_running() {
339 my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
340 $socket .= "claws-mail-$<";
342 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
344 error_dialog ($emsg);
350 sub check_rc_file() {
352 (defined($rcfile) && -f $rcfile) or do {
353 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
355 error_dialog ($emsg);
361 sub set_widget_hint() {
363 my ($wdgt, $hint) = @_;
364 $wdgt->set_tooltip_text ($hint);
365 $wdgt->set_has_tooltip (TRUE);
369 sub set_widget_sens() {
370 my ($wdgt, $minver) = @_;
371 $wdgt->set_sensitive (&version_greater_or_equal ($CLAWSV, $minver));
374 # graphic element creation
376 sub new_check_button_for {
377 my ($hash, $key) = @_;
378 my $name = $$hash{$key}[NAME];
379 my $label = $$hash{$key}[LABEL];
381 my $hbox = Gtk2::HBox->new (FALSE, 5);
382 my $cb = Gtk2::CheckButton->new ($label);
383 $$hash{$key}[GUI] = $cb;
384 if (defined ($HPVALUE{$name})) {
385 $cb->set_active ($HPVALUE{$name} eq '1');
387 $cb->signal_connect (clicked => sub {
389 &handle_bool_value($w, $e, \$HPVALUE{$name});
391 &set_widget_hint ($cb, $$hash{$key}[DESC]);
392 &set_widget_sens ($cb, $$hash{$key}[CMVER]);
393 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
398 sub new_text_box_for_int {
399 my ($hash, $key) = @_;
400 my $name = $$hash{$key}[NAME];
401 my $label = $$hash{$key}[LABEL];
402 my @type = split (/,/, $$hash{$key}[TYPE]);
403 push (@type, 0), push (@type, 10000) unless ($#type > 0);
405 my $hbox = Gtk2::HBox->new (FALSE, 5);
406 my $glabel = Gtk2::Label->new ($label);
407 my $pagei = int (($type[2] - $type[1]) / 10);
408 my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
409 $gentry->set_numeric (TRUE);
410 $gentry->set_value ($HPVALUE{$name});
411 $$hash{$key}[GUI] = $gentry;
412 $gentry->signal_connect('value-changed' => sub {
414 &handle_int_value($w, $e, \$HPVALUE{$name});
416 &set_widget_hint ($gentry, $$hash{$key}[DESC]);
417 &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
418 $glabel->set_sensitive ($gentry->sensitive);
419 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
420 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
425 sub new_color_button_for {
426 my ($hash, $key) = @_;
427 my $name = $$hash{$key}[NAME];
428 my $label = $$hash{$key}[LABEL];
430 my $col = &gdk_color_from_str ($HPVALUE{$name});
431 my $hbox = Gtk2::HBox->new (FALSE, 5);
432 my $glabel = Gtk2::Label->new ($label);
433 my $button = Gtk2::ColorButton->new_with_color ($col);
434 $$hash{$key}[GUI] = $button;
435 $button->set_title ($label);
436 $button->set_relief ('none');
437 $button->signal_connect ('color-set' => sub {
439 &handle_color_value($w, $e, \$HPVALUE{$name});
441 &set_widget_hint ($button, $$hash{$key}[DESC]);
442 &set_widget_sens ($button, $$hash{$key}[CMVER]);
443 $glabel->set_sensitive ($button->sensitive);
444 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
445 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
450 sub new_selection_box_for {
451 my ($hash, $key) = @_;
452 my $name = $$hash{$key}[NAME];
453 my $label = $$hash{$key}[LABEL];
455 my $hbox = Gtk2::HBox->new (FALSE, 5);
456 my $glabel = Gtk2::Label->new ($label);
457 my $combo = Gtk2::ComboBox->new_text;
458 $$hash{$key}[GUI] = $combo;
459 my @options = split (';', $$hash{$key}[TYPE]);
460 foreach my $opt (@options) {
461 my ($index, $textkey) = split ('=', $opt);
462 $combo->insert_text ($index, $xl::s{$textkey});
464 $combo->signal_connect ('changed' => sub {
466 &handle_selection_value($w, $e, \$HPVALUE{$name});
468 $combo->set_active ($HPVALUE{$name});
469 &set_widget_hint ($combo, $$hash{$key}[DESC]);
470 &set_widget_sens ($combo, $$hash{$key}[CMVER]);
471 $glabel->set_sensitive ($combo->sensitive);
472 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
473 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
478 # more graphic helpers
480 sub new_hbox_pack() {
481 my $hbox = Gtk2::HBox->new (FALSE, 5);
482 $hbox->set_border_width (PAGE_SPC);
483 foreach my $item (@_) {
484 $hbox->pack_start ($item, FALSE, FALSE, 0);
489 sub new_vbox_pack() {
490 my $vbox = Gtk2::VBox->new (FALSE, 5);
491 $vbox->set_border_width (PAGE_SPC);
492 foreach my $item (@_) {
493 $vbox->pack_start ($item, FALSE, FALSE, 0);
498 sub new_vbox_pack_compact() {
499 my $vbox = Gtk2::VBox->new (FALSE, 0);
500 $vbox->set_border_width (0);
501 foreach my $item (@_) {
502 $vbox->pack_start ($item, FALSE, FALSE, 0);
507 sub new_subpage_frame () {
508 my ($box, $title, $notpacked) = @_;
509 my $frame = Gtk2::Frame->new ($title);
511 return &new_vbox_pack ($frame) unless defined ($notpacked);
515 # preference maps and corresponding page creation subs
517 %pr::oth = ( # other preferences
519 'addressbook_use_editaddress_dialog',
520 $xl::s{l_oth_use_dlg},
521 $xl::s{h_oth_use_dlg},
528 'cache_max_mem_usage',
529 $xl::s{l_oth_max_use},
530 $xl::s{h_oth_max_use},
531 'int,0,262144', # 0 Kb - 256 Mb
537 'cache_min_keep_time',
538 $xl::s{l_oth_min_time},
539 $xl::s{h_oth_min_time},
540 'int,0,120', # 0 minutes - 2 hours
546 'use_networkmanager',
547 $xl::s{l_oth_use_netm},
548 $xl::s{h_oth_use_netm},
556 sub new_other_page() {
557 return &new_vbox_pack (
560 &new_check_button_for(\%pr::oth, 'use_dlg')),
561 $xl::s{ab_frame}, 'not-packed'),
564 &new_text_box_for_int(\%pr::oth, 'max_use'),
565 &new_text_box_for_int(\%pr::oth, 'min_time')),
566 $xl::s{mem_frame}, 'not-packed'),
569 &new_check_button_for(\%pr::oth, 'use_netm')),
570 $xl::s{netm_frame}, 'not-packed')
574 %pr::gui = ( # gui bells and whistles
577 $xl::s{l_gui_b_unread},
578 $xl::s{h_gui_b_unread},
586 $xl::s{l_gui_no_markup},
587 $xl::s{h_gui_no_markup},
594 'enable_dotted_lines',
595 $xl::s{l_gui_dot_lines},
596 $xl::s{h_gui_dot_lines},
604 $xl::s{l_gui_h_scroll},
605 $xl::s{h_gui_h_scroll},
613 $xl::s{l_gui_swp_from},
614 $xl::s{h_gui_swp_from},
621 'folderview_vscrollbar_policy',
622 $xl::s{l_gui_v_scroll},
623 $xl::s{h_gui_v_scroll},
624 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
631 $xl::s{l_gui_from_show},
632 $xl::s{h_gui_from_show},
633 '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
639 'stripes_color_offset',
640 $xl::s{l_gui_strip_off},
641 $xl::s{h_gui_strip_off},
642 'int,0,40000', # no idea what this number means
648 'textview_cursor_visible',
649 $xl::s{l_gui_cursor_v},
650 $xl::s{h_gui_cursor_v},
657 'toolbar_detachable',
658 $xl::s{l_gui_toolbar_d},
659 $xl::s{h_gui_toolbar_d},
666 'use_stripes_everywhere',
667 $xl::s{l_gui_strip_all},
668 $xl::s{h_gui_strip_all},
675 'use_stripes_in_summaries',
676 $xl::s{l_gui_strip_sum},
677 $xl::s{h_gui_strip_sum},
685 $xl::s{l_gui_two_line_v},
686 $xl::s{h_gui_two_line_v},
693 'show_compose_margin',
694 $xl::s{l_gui_margin_co},
695 $xl::s{h_gui_margin_co},
702 'msgview_date_format',
703 $xl::s{l_gui_mview_date},
704 $xl::s{h_gui_mview_date},
713 my $gf = Gtk2::VBox->new (FALSE, 5);
714 $gf->set_border_width (PAGE_SPC);
716 my $cb_dot_lines = &new_check_button_for (\%pr::gui, 'dot_lines');
717 my $cb_toolbar_d = &new_check_button_for (\%pr::gui, 'toolbar_d');
719 $gf->pack_start (&new_subpage_frame (
721 &new_check_button_for (\%pr::gui, 'strip_all'),
722 &new_check_button_for (\%pr::gui, 'strip_sum'),
723 &new_text_box_for_int (\%pr::gui, 'strip_off')),
724 $xl::s{stripes_frame}, 'not-packed'),
725 FALSE, FALSE, FRAME_SPC);
726 $gf->pack_start (&new_subpage_frame (
728 &new_check_button_for (\%pr::gui, 'b_unread'),
729 &new_check_button_for (\%pr::gui, 'swp_from'),
730 &new_check_button_for (\%pr::gui, 'two_linev'),
731 &new_selection_box_for (\%pr::gui, 'from_show')),
732 $xl::s{mlist_frame}, 'not-packed'),
733 FALSE, FALSE, FRAME_SPC);
734 $gf->pack_start (&new_subpage_frame (
736 &new_check_button_for (\%pr::gui, 'cursor_v'),
737 &new_check_button_for (\%pr::gui, 'mview_date')),
738 $xl::s{mview_frame}, 'not-packed'),
739 FALSE, FALSE, FRAME_SPC);
740 $gf->pack_start (&new_subpage_frame (
742 &new_check_button_for (\%pr::gui, 'no_markup'),
743 &new_check_button_for (\%pr::gui, 'margin_co')),
744 $xl::s{compo_frame}, 'not-packed'),
745 FALSE, FALSE, FRAME_SPC);
746 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
747 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
748 $gf->pack_start (&new_subpage_frame (
750 &new_check_button_for (\%pr::gui, 'h_scroll'),
751 &new_selection_box_for (\%pr::gui, 'v_scroll')),
752 $xl::s{sbar_frame}, 'not-packed'),
753 FALSE, FALSE, FRAME_SPC);
758 %pr::beh = ( # tweak some behaviour
761 $xl::s{l_beh_hover_t},
762 $xl::s{h_beh_hover_t},
763 'int,100,3000', # 0.1 seconds - 3 seconds
770 $xl::s{l_beh_dangerous},
771 $xl::s{h_beh_dangerous},
778 'respect_flowed_format',
779 $xl::s{l_beh_flowed},
780 $xl::s{h_beh_flowed},
787 'save_parts_readwrite',
788 $xl::s{l_beh_parts_rw},
789 $xl::s{h_beh_parts_rw},
796 'skip_ssl_cert_check',
797 $xl::s{l_beh_skip_ssl},
798 $xl::s{h_beh_skip_ssl},
805 'statusbar_update_step',
806 $xl::s{l_beh_up_step},
807 $xl::s{h_beh_up_step},
808 'int,1,200', # 1 item - 200 items
814 'thread_by_subject_max_age',
815 $xl::s{l_beh_thread_a},
816 $xl::s{h_beh_thread_a},
817 'int,1,30', # 1 day - 30 days
824 $xl::s{l_beh_unsafe_ssl},
825 $xl::s{h_beh_unsafe_ssl},
832 'utf8_instead_of_locale_for_broken_mail',
833 $xl::s{l_beh_use_utf8},
834 $xl::s{h_beh_use_utf8},
842 $xl::s{l_beh_warn_dnd},
843 $xl::s{h_beh_warn_dnd},
850 'outgoing_fallback_to_ascii',
851 $xl::s{l_beh_out_ascii},
852 $xl::s{h_beh_out_ascii},
859 'primary_paste_unselects',
860 $xl::s{l_beh_pp_unsel},
861 $xl::s{h_beh_pp_unsel},
868 'show_inline_attachments',
869 $xl::s{l_beh_inline_at},
870 $xl::s{h_beh_inline_at},
878 sub new_behaviour_page() {
879 my $bf = Gtk2::VBox->new (FALSE, 5);
880 $bf->set_border_width (PAGE_SPC);
882 my $tb_up_step = &new_text_box_for_int (\%pr::beh, 'up_step');
883 my $tb_thread_a = &new_text_box_for_int (\%pr::beh, 'thread_a');
885 $bf->pack_start (&new_subpage_frame (
887 &new_text_box_for_int (\%pr::beh, 'hover_t'),
888 &new_check_button_for (\%pr::beh, 'warn_dnd')),
889 $xl::s{dnd_frame}, 'not-packed'),
890 FALSE, FALSE, FRAME_SPC);
891 $bf->pack_start (&new_subpage_frame (
893 &new_check_button_for (\%pr::beh, 'skip_ssl'),
894 &new_check_button_for (\%pr::beh, 'unsafe_ssl')),
895 $xl::s{ssl_frame}, 'not-packed'),
896 FALSE, FALSE, FRAME_SPC);
897 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
898 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
899 $bf->pack_start (&new_subpage_frame (
901 &new_check_button_for (\%pr::beh, 'flowed'),
902 &new_check_button_for (\%pr::beh, 'parts_rw'),
903 &new_check_button_for (\%pr::beh, 'use_utf8'),
904 &new_check_button_for (\%pr::beh, 'dangerous'),
905 &new_check_button_for (\%pr::beh, 'out_ascii'),
906 &new_check_button_for (\%pr::beh, 'pp_unsel'),
907 &new_check_button_for (\%pr::beh, 'inline_at')),
908 $xl::s{msgs_frame}, 'not-packed'),
909 FALSE, FALSE, FRAME_SPC);
914 %pr::col = ( # a variety of colours
917 $xl::s{l_col_emphasis},
918 $xl::s{h_col_emphasis},
926 $xl::s{l_col_log_err},
927 $xl::s{h_col_log_err},
935 $xl::s{l_col_log_in},
936 $xl::s{h_col_log_in},
944 $xl::s{l_col_log_msg},
945 $xl::s{h_col_log_msg},
953 $xl::s{l_col_log_out},
954 $xl::s{h_col_log_out},
962 $xl::s{l_col_log_warn},
963 $xl::s{h_col_log_warn},
971 sub new_colours_page() {
972 return &new_vbox_pack (
975 &new_color_button_for (\%pr::col, 'emphasis')),
976 $xl::s{msgview_frame}, 'not-packed'),
979 &new_color_button_for (\%pr::col, 'log_err'),
980 &new_color_button_for (\%pr::col, 'log_in'),
981 &new_color_button_for (\%pr::col, 'log_msg'),
982 &new_color_button_for (\%pr::col, 'log_out'),
983 &new_color_button_for (\%pr::col, 'log_warn')),
984 $xl::s{log_frame}, 'not-packed')
988 %pr::win = ( # tweak window positions and/or sizes
993 'int,0,3000', # 0 pixels - 3000 pixels
1002 'int,0,3000', # 0 pixels - 3000 pixels
1011 'int,0,3000', # 0 pixels - 3000 pixels
1020 'int,0,3000', # 0 pixels - 3000 pixels
1026 'mainwin_maximised',
1027 $xl::s{l_win_main_mx},
1028 $xl::s{h_win_main_mx},
1035 'mainwin_fullscreen',
1036 $xl::s{l_win_main_fs},
1037 $xl::s{h_win_main_fs},
1044 'main_messagewin_x',
1047 'int,0,3000', # 0 pixels - 3000 pixels
1053 'main_messagewin_y',
1056 'int,0,3000', # 0 pixels - 3000 pixels
1065 'int,0,3000', # 0 pixels - 3000 pixels
1071 'messagewin_height',
1074 'int,0,3000', # 0 pixels - 3000 pixels
1083 'int,0,3000', # 0 pixels - 3000 pixels
1092 'int,0,3000', # 0 pixels - 3000 pixels
1101 'int,0,3000', # 0 pixels - 3000 pixels
1107 'receivewin_height',
1110 'int,0,3000', # 0 pixels - 3000 pixels
1119 'int,0,3000', # 0 pixels - 3000 pixels
1128 'int,0,3000', # 0 pixels - 3000 pixels
1134 'folderitemwin_width',
1137 'int,0,3000', # 0 pixels - 3000 pixels
1143 'folderitemwin_height',
1146 'int,0,3000', # 0 pixels - 3000 pixels
1152 'folderselwin_width',
1155 'int,0,3000', # 0 pixels - 3000 pixels
1161 'folderselwin_height',
1164 'int,0,3000', # 0 pixels - 3000 pixels
1173 'int,0,3000', # 0 pixels - 3000 pixels
1182 'int,0,3000', # 0 pixels - 3000 pixels
1188 'addressbookwin_width',
1191 'int,0,3000', # 0 pixels - 3000 pixels
1197 'addressbookwin_height',
1200 'int,0,3000', # 0 pixels - 3000 pixels
1206 'addressbookeditpersonwin_width',
1209 'int,0,3000', # 0 pixels - 3000 pixels
1215 'addressbookeditpersonwin_height',
1218 'int,0,3000', # 0 pixels - 3000 pixels
1224 'addressbookeditgroupwin_width',
1227 'int,0,3000', # 0 pixels - 3000 pixels
1233 'addressbookeditgroupwin_height',
1236 'int,0,3000', # 0 pixels - 3000 pixels
1242 'addressaddwin_width',
1245 'int,0,3000', # 0 pixels - 3000 pixels
1251 'addressaddwin_height',
1254 'int,0,3000', # 0 pixels - 3000 pixels
1260 'addressbook_folderselwin_width',
1263 'int,0,3000', # 0 pixels - 3000 pixels
1269 'addressbook_folderselwin_height',
1272 'int,0,3000', # 0 pixels - 3000 pixels
1278 'editaccountwin_width',
1281 'int,0,3000', # 0 pixels - 3000 pixels
1287 'editaccountwin_height',
1290 'int,0,3000', # 0 pixels - 3000 pixels
1296 'accountswin_width',
1299 'int,0,3000', # 0 pixels - 3000 pixels
1305 'accountswin_height',
1308 'int,0,3000', # 0 pixels - 3000 pixels
1314 'filteringwin_width',
1317 'int,0,3000', # 0 pixels - 3000 pixels
1323 'filteringwin_height',
1326 'int,0,3000', # 0 pixels - 3000 pixels
1332 'filteringactionwin_width',
1335 'int,0,3000', # 0 pixels - 3000 pixels
1341 'filteringactionwin_height',
1344 'int,0,3000', # 0 pixels - 3000 pixels
1350 'filtering_debugwin_width',
1353 'int,0,3000', # 0 pixels - 3000 pixels
1359 'filtering_debugwin_height',
1362 'int,0,3000', # 0 pixels - 3000 pixels
1371 'int,0,3000', # 0 pixels - 3000 pixels
1377 'matcherwin_height',
1380 'int,0,3000', # 0 pixels - 3000 pixels
1389 'int,0,3000', # 0 pixels - 3000 pixels
1398 'int,0,3000', # 0 pixels - 3000 pixels
1404 'templateswin_width',
1407 'int,0,3000', # 0 pixels - 3000 pixels
1413 'templateswin_height',
1416 'int,0,3000', # 0 pixels - 3000 pixels
1425 'int,0,3000', # 0 pixels - 3000 pixels
1431 'actionswin_height',
1434 'int,0,3000', # 0 pixels - 3000 pixels
1443 'int,0,3000', # 0 pixels - 3000 pixels
1452 'int,0,3000', # 0 pixels - 3000 pixels
1461 'int,0,3000', # 0 pixels - 3000 pixels
1467 'pluginswin_height',
1470 'int,0,3000', # 0 pixels - 3000 pixels
1479 'int,0,3000', # 0 pixels - 3000 pixels
1488 'int,0,3000', # 0 pixels - 3000 pixels
1494 'print_previewwin_width',
1497 'int,0,3000', # 0 pixels - 3000 pixels
1503 'print_previewwin_height',
1506 'int,0,3000', # 0 pixels - 3000 pixels
1513 sub new_winpos_subpage_main() {
1514 return &new_subpage_frame (
1515 &new_vbox_pack_compact (
1517 &new_text_box_for_int (\%pr::win, 'main_x'),
1518 &new_text_box_for_int (\%pr::win, 'main_y')),
1520 &new_text_box_for_int (\%pr::win, 'main_w'),
1521 &new_text_box_for_int (\%pr::win, 'main_h')),
1523 &new_check_button_for (\%pr::win, 'main_fs'),
1524 &new_check_button_for (\%pr::win, 'main_mx'))),
1529 sub new_winpos_subpage_msgs() {
1530 return &new_subpage_frame (
1531 &new_vbox_pack_compact (
1533 &new_text_box_for_int (\%pr::win, 'msgs_x'),
1534 &new_text_box_for_int (\%pr::win, 'msgs_y')),
1536 &new_text_box_for_int (\%pr::win, 'msgs_w'),
1537 &new_text_box_for_int (\%pr::win, 'msgs_h'))),
1542 sub new_winpos_subpage_sendrecv() {
1543 return &new_vbox_pack (
1544 &new_subpage_frame (
1546 &new_text_box_for_int (\%pr::win, 'send_w'),
1547 &new_text_box_for_int (\%pr::win, 'send_h')),
1548 _('Send window'), 'not-packed'),
1549 &new_subpage_frame (
1551 &new_text_box_for_int (\%pr::win, 'recv_w'),
1552 &new_text_box_for_int (\%pr::win, 'recv_h')),
1553 _('Receive window'), 'not-packed')
1557 sub new_winpos_subpage_fold() {
1558 return &new_vbox_pack (
1559 &new_subpage_frame (
1560 &new_vbox_pack_compact (
1562 &new_text_box_for_int (\%pr::win, 'fold_x'),
1563 &new_text_box_for_int (\%pr::win, 'fold_y')),
1565 &new_text_box_for_int (\%pr::win, 'fold_w'),
1566 &new_text_box_for_int (\%pr::win, 'fold_h'))),
1567 _('Folder window'), 'not-packed'),
1568 &new_subpage_frame (
1570 &new_text_box_for_int (\%pr::win, 'fsel_w'),
1571 &new_text_box_for_int (\%pr::win, 'fsel_h')),
1572 _('Folder selection window'), 'not-packed')
1576 sub new_winpos_subpage_addrbook() {
1577 return &new_vbox_pack (
1578 &new_subpage_frame (
1580 &new_text_box_for_int (\%pr::win, 'addr_w'),
1581 &new_text_box_for_int (\%pr::win, 'addr_h')),
1582 _('Addressbook main window'), 'not-packed'),
1583 &new_subpage_frame (
1585 &new_text_box_for_int (\%pr::win, 'adep_w'),
1586 &new_text_box_for_int (\%pr::win, 'adep_h')),
1587 _('Edit person window'), 'not-packed'),
1588 &new_subpage_frame (
1590 &new_text_box_for_int (\%pr::win, 'adeg_w'),
1591 &new_text_box_for_int (\%pr::win, 'adeg_h')),
1592 _('Edit group window'), 'not-packed'),
1593 &new_subpage_frame (
1595 &new_text_box_for_int (\%pr::win, 'adda_w'),
1596 &new_text_box_for_int (\%pr::win, 'adda_h')),
1597 _('Add address window'), 'not-packed'),
1598 &new_subpage_frame (
1600 &new_text_box_for_int (\%pr::win, 'addf_w'),
1601 &new_text_box_for_int (\%pr::win, 'addf_h')),
1602 _('Folder select window'), 'not-packed')
1606 sub new_winpos_subpage_accounts() {
1607 return &new_vbox_pack (
1608 &new_subpage_frame (
1610 &new_text_box_for_int (\%pr::win, 'acco_w'),
1611 &new_text_box_for_int (\%pr::win, 'acco_h')),
1612 _('Accounts window'), 'not-packed'),
1613 &new_subpage_frame (
1615 &new_text_box_for_int (\%pr::win, 'acce_w'),
1616 &new_text_box_for_int (\%pr::win, 'acce_h')),
1617 _('Edit account window'), 'not-packed')
1621 sub new_winpos_subpage_filtering() {
1622 return &new_vbox_pack (
1623 &new_subpage_frame (
1625 &new_text_box_for_int (\%pr::win, 'filt_w'),
1626 &new_text_box_for_int (\%pr::win, 'filt_h')),
1627 _('Filtering window'), 'not-packed'),
1628 &new_subpage_frame (
1630 &new_text_box_for_int (\%pr::win, 'fila_w'),
1631 &new_text_box_for_int (\%pr::win, 'fila_h')),
1632 _('Filtering actions window'), 'not-packed'),
1633 &new_subpage_frame (
1635 &new_text_box_for_int (\%pr::win, 'fild_w'),
1636 &new_text_box_for_int (\%pr::win, 'fild_h')),
1637 _('Filtering debug window'), 'not-packed'),
1638 &new_subpage_frame (
1640 &new_text_box_for_int (\%pr::win, 'matc_w'),
1641 &new_text_box_for_int (\%pr::win, 'matc_h')),
1642 _('Matcher window'), 'not-packed')
1646 sub new_winpos_subpage_prefs() {
1647 return &new_vbox_pack (
1648 &new_subpage_frame (
1650 &new_text_box_for_int (\%pr::win, 'pref_w'),
1651 &new_text_box_for_int (\%pr::win, 'pref_h')),
1652 _('Preferences window'), 'not-packed'),
1653 &new_subpage_frame (
1655 &new_text_box_for_int (\%pr::win, 'temp_w'),
1656 &new_text_box_for_int (\%pr::win, 'temp_h')),
1657 _('Templates window'), 'not-packed'),
1658 &new_subpage_frame (
1660 &new_text_box_for_int (\%pr::win, 'acti_w'),
1661 &new_text_box_for_int (\%pr::win, 'acti_h')),
1662 _('Actions window'), 'not-packed'),
1663 &new_subpage_frame (
1665 &new_text_box_for_int (\%pr::win, 'tags_w'),
1666 &new_text_box_for_int (\%pr::win, 'tags_h')),
1667 _('Tags window'), 'not-packed'),
1668 &new_subpage_frame (
1670 &new_text_box_for_int (\%pr::win, 'plug_w'),
1671 &new_text_box_for_int (\%pr::win, 'plug_h')),
1672 _('Plugins window'), 'not-packed')
1676 sub new_winpos_subpage_misc() {
1677 return &new_vbox_pack (
1678 &new_subpage_frame (
1680 &new_text_box_for_int (\%pr::win, 'logw_w'),
1681 &new_text_box_for_int (\%pr::win, 'logw_h')),
1682 _('Log window'), 'not-packed'),
1683 &new_subpage_frame (
1685 &new_text_box_for_int (\%pr::win, 'prin_w'),
1686 &new_text_box_for_int (\%pr::win, 'prin_h')),
1687 _('Print preview window'), 'not-packed'),
1688 &new_subpage_frame (
1690 &new_text_box_for_int (\%pr::win, 'sour_w'),
1691 &new_text_box_for_int (\%pr::win, 'sour_h')),
1692 _('View source window'), 'not-packed')
1696 sub new_winpos_page() {
1697 my $winbook = Gtk2::Notebook->new;
1698 $winbook->set_tab_pos ('right');
1699 $winbook->append_page (&new_winpos_subpage_main, _('Main'));
1700 $winbook->append_page (&new_winpos_subpage_msgs, _('Message'));
1701 $winbook->append_page (&new_winpos_subpage_sendrecv, _('Send/Receive'));
1702 $winbook->append_page (&new_winpos_subpage_fold, _('Folder'));
1703 $winbook->append_page (&new_winpos_subpage_addrbook, _('Addressbook'));
1704 $winbook->append_page (&new_winpos_subpage_accounts, _('Accounts'));
1705 $winbook->append_page (&new_winpos_subpage_filtering, _('Filtering'));
1706 $winbook->append_page (&new_winpos_subpage_prefs, _('Preferences'));
1707 $winbook->append_page (&new_winpos_subpage_misc, _('Other'));
1712 sub print_version() {
1713 print $xl::s{about_title} . "\n";
1714 print $xl::s{about_version} . " $VERSION\n";
1715 print "Perl-GLib " . $Glib::VERSION;
1716 # version info stuff appeared in 1.040
1717 if ($Glib::VERSION >= 1.040) {
1718 print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
1719 . _(", running with ") . join(".", &Glib::major_version,
1720 &Glib::minor_version, &Glib::micro_version);
1723 print "Perl-GTK2 " . $Gtk2::VERSION;
1724 if ($Gtk2::VERSION >= 1.040) {
1725 print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1726 . _(", running with ") . join(".", &Gtk2::major_version,
1727 &Gtk2::minor_version, &Gtk2::micro_version);
1730 my $clawsver = ($CLAWSV eq "") ?
1731 _("was not found!") :
1732 (_("returned version ") . $CLAWSV);
1733 print "Claws Mail " . $clawsver . "\n";
1736 # the command line help
1738 my $line = '-' x length ($xl::s{about_title}) . "\n";
1740 print $xl::s{about_title} . "\n";
1742 print _("Syntax:\n");
1743 print _(" clawsker [options]\n");
1744 print _("Options:\n");
1745 print _(" --help Prints this help screen.\n");
1746 print _(" --version Prints version infos.\n");
1747 print _(" --verbose More messages on standard output.\n");
1748 print _(" --alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1749 print _(" --clawsrc <file> Uses <file> as full resource name.\n");
1752 # handle errors which don't allow to run
1753 sub command_line_fatal() {
1755 my $emsg = $xl::s{e_error} . $reason;
1756 error_dialog ($emsg);
1757 log_message ("$emsg", 'die');
1760 # parse the command line
1761 sub parse_command_line() {
1762 $CLAWSV = &get_claws_version;
1764 while (defined($ARGV[$arg])) {
1778 /--use-claws-version/ && do {
1780 &command_line_fatal ("required version")
1781 unless defined($ARGV[$arg]);
1782 &command_line_fatal ("required a dotted numeric value")
1783 unless ($ARGV[$arg] =~ /[\d\.]+/);
1784 $CLAWSV = $ARGV[$arg];
1787 /--alternate-config-dir/ && do {
1789 &command_line_fatal ($xl::s{e_requireddir})
1790 unless defined($ARGV[$arg]);
1791 &command_line_fatal ($xl::s{e_notadir})
1792 unless -d $ARGV[$arg];
1793 $CONFIGDIR = $ARGV[$arg];
1795 unless ($CONFIGDIR =~ /.*\/$/);
1796 $ALTCONFIGDIR = TRUE;
1801 &command_line_fatal($xl::s{e_requiredfile})
1802 unless defined($ARGV[$arg]);
1803 &command_line_fatal($xl::s{e_notafile})
1804 unless -f $ARGV[$arg];
1805 &set_rc_filename ($ARGV[$arg]);
1808 /.*/ && &command_line_fatal (
1809 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1813 # eveything continues...
1817 # update the hidden preferences status from loaded values
1818 sub init_hidden_preferences() {
1819 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1820 foreach my $key (keys %$hash) {
1821 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1827 # load current status from disc
1828 sub load_preferences() {
1829 my $rc = &get_rc_filename;
1830 &log_message ("Loading preferences from $rc\n");
1831 return FALSE unless &check_rc_file ($rc);
1832 return FALSE unless &check_claws_not_running;
1836 if (/^([8a-z_]+)=(.*)$/) {
1844 # save current preferences to disc
1845 sub save_preferences() {
1846 my $rc = &get_rc_filename;
1847 &log_message ("Saving preferences to $rc\n");
1848 return FALSE unless &check_rc_file ($rc);
1849 return FALSE unless &check_claws_not_running;
1850 my $rcbak = "$rc.backup";
1851 rename ($rc, $rcbak);
1853 open (RCB, "<$rcbak");
1856 if (/^([8a-z_]+)=(.*)$/) {
1857 if (defined($HPVALUE{$1})) {
1858 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1861 print RCF $_ . "\n";
1865 print RCF $_ . "\n";
1874 sub new_notebook() {
1875 my $nb = Gtk2::Notebook->new;
1877 $nb->append_page (&new_behaviour_page, $xl::s{tab_behaviour});
1878 $nb->append_page (&new_colours_page, $xl::s{tab_colours});
1879 $nb->append_page (&new_gui_page, $xl::s{tab_gui});
1880 $nb->append_page (&new_other_page, $xl::s{tab_other});
1881 $nb->append_page (&new_winpos_page, $xl::s{tab_winpos});
1886 # create an about dialog
1887 sub new_about_dialog() {
1889 my $title = $xl::s{about_title};
1890 my $lic = $xl::s{about_license};
1891 my $vers = $xl::s{about_version} . " $VERSION";
1893 "This program is free software: you can redistribute it and/or modify
1894 it under the terms of the GNU General Public License as published by
1895 the Free Software Foundation, either version 3 of the License, or
1896 (at your option) any later version.
1898 This program is distributed in the hope that it will be useful,
1899 but WITHOUT ANY WARRANTY; without even the implied warranty of
1900 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1901 GNU General Public License for more details.
1903 You should have received a copy of the GNU General Public License
1904 along with this program. If not, see <http://www.gnu.org/licenses/>.";
1905 my $year = "2007-2012";
1906 my $holder = "Ricardo Mones <ricardo\@mones.org>";
1907 my $url = "http://www.claws-mail.org/clawsker";
1909 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
1910 [qw/modal destroy-with-parent/],
1912 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
1913 . "<span size=\"large\">$vers</span>\n\n"
1914 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
1915 . "<span>Copyright $year by $holder</span>\n\n"
1916 . "<span size=\"large\">$lic</span>\n\n"
1917 . "<span size=\"small\">$license</span>");
1918 $dialog->set_title ($xl::s{about});
1923 # create buttons box
1924 sub new_button_box() {
1925 my ($parent, $adlg) = @_;
1926 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
1927 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
1928 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
1929 # disable button until is really implemented
1930 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
1931 my $hbox = Gtk2::HBox->new (FALSE, 5);
1933 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
1934 $b_apply->signal_connect (clicked => sub { &save_preferences ($parent) });
1935 # $b_undo->signal_connect (clicked => sub { &undo_current_changes });
1936 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
1938 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
1939 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
1940 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
1941 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
1947 $main_window = Gtk2::Window->new ('toplevel');
1948 exit unless &parse_command_line;
1949 exit unless &load_preferences;
1950 exit unless &init_hidden_preferences;
1952 my $box = Gtk2::VBox->new (FALSE, 5);
1953 $box->set_border_width(3);
1954 my $about = &new_about_dialog;
1955 $box->pack_start (&new_notebook, FALSE, FALSE, 0);
1956 $box->pack_end (&new_button_box ($main_window, $about), FALSE, FALSE, 0);
1957 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
1958 $main_window->set_title ($xl::s{win_title});
1959 $main_window->add ($box);
1960 $main_window->show_all;