3 # Clawsker :: A Claws Mail Tweaker
8 use Glib qw(TRUE FALSE);
10 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;
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_strip_off => _('Coloured lines contrast'),
95 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.'),
96 l_gui_cursor_v => _('Show cursor in message view'),
97 h_gui_cursor_v => _('Display the cursor in the message view.'),
98 l_gui_toolbar_d => _('Detachable toolbars'),
99 h_gui_toolbar_d => _('Show handles in the toolbars.'),
100 l_gui_strip_all => _('Use stripes in all tree view components'),
101 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
102 l_gui_strip_sum => _('Use stripes in Folder List and Message List'),
103 h_gui_strip_sum => _('Enable alternately coloured lines in Message list and Folder list.'),
104 l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
105 h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
106 l_gui_margin_co => _('Show compose margin'),
107 h_gui_margin_co => _('Shows a small margin in the compose view.'),
109 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
110 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.'),
111 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
112 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
113 l_beh_flowed => _('Respect format=flowed in messages'),
114 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.'),
115 l_beh_parts_rw => _('Allow writable temporary files'),
116 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
117 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
118 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
119 l_beh_up_step => _('Progress bar update step (items)'),
120 h_beh_up_step => _('Update stepping in progress bars.'),
121 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
122 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
123 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
124 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
125 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
126 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
127 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
128 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
129 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
130 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
131 l_beh_pp_unsel => _('Primary paste unselects selection'),
132 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
134 l_col_emphasis => _('X-Mailer header'),
135 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
136 l_col_log_err => _('Error messages'),
137 h_col_log_err => _('Colour for error messages in log window.'),
138 l_col_log_in => _('Server messages'),
139 h_col_log_in => _('Colour for messages received from servers in log window.'),
140 l_col_log_msg => _('Standard messages'),
141 h_col_log_msg => _('Colour for messages in log window.'),
142 l_col_log_out => _('Client messages'),
143 h_col_log_out => _('Colour for messages sent to servers in log window.'),
144 l_col_log_warn => _('Warnings'),
145 h_col_log_warn => _('Colour for warning messages in log window.'),
147 l_win_x => _('X position'),
148 h_win_x => _('X coordinate for window\'s top-left corner.'),
149 l_win_y => _('Y position'),
150 h_win_y => _('Y coordinate for window\'s top-left corner.'),
151 l_win_w => _('Width'),
152 h_win_w => _('Window\'s width in pixels.'),
153 l_win_h => _('Height'),
154 h_win_h => _('Window\'s height in pixels.'),
156 l_win_main_mx => _('Maximized'),
157 h_win_main_mx => _('Changes window maximized status.'),
158 l_win_main_fs => _('Full-screen'),
159 h_win_main_fs => _('Changes full screen status.'),
161 e_error => _('Error: '),
162 e_noclawsrc => _('resource file for Claws Mail was not found.'),
163 e_running => _('seems Claws Mail is currently running, close it first.'),
164 e_requireddir => _('option requires a directory name.'),
165 e_requiredfile => _('option requires a file name.'),
166 e_notadir => _('specified name is not a directory or does not exist.'),
167 e_notafile => _('specified name is not a file or does not exist.'),
170 # all preferences read by load_preferences
172 # values of all preferences handled by clawsker
174 # default config dir and file name
175 my $ALTCONFIGDIR = FALSE;
176 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
177 my $CONFIGRC = 'clawsrc';
179 # index constants for preference arrays
180 use constant NAME => 0; # the name on the rc file
181 use constant LABEL => 1; # the label on the GUI
182 use constant DESC => 2; # the description for the hint/help
183 use constant TYPE => 3; # data type: bool, int, float, string, color
184 use constant CMVER => 4; # lowest Claws Mail version the feature exists
185 use constant CMDEF => 5; # default value for the preference in Claws Mail
186 use constant GUI => 6; # GUI element
188 # constants for GUI spacing
189 use constant HBOX_SPC => 5;
190 use constant FRAME_SPC => 2;
191 use constant PAGE_SPC => 5;
195 sub version_greater_or_equal() {
196 my ($version, $refvers) = @_;
197 my @version = split (/\./, $version);
198 my @refvers = split (/\./, $refvers);
199 while ($#version < $#refvers) {
200 push (@version, '0');
203 while (($idx <= $#refvers)
204 and (int ($version[$idx]) == int ($refvers[$idx]))) {
207 return TRUE if (($idx > $#refvers)
208 or (int ($version[$idx]) >= int ($refvers[$idx])));
212 sub get_claws_version() {
217 foreach my $bin (@cmbin) {
222 return "" unless ($_); # not installed
225 my @fver = split (/ /);
226 die "Invalid version string" unless ($fver[2] eq "version");
227 my @ver = split (/\./, $fver[3]);
230 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
239 # data handlers and auxiliar functions
241 sub handle_bool_value {
242 my ($widget, $event, $dataref) = @_;
243 $$dataref = ($widget->get_active ())? '1': '0';
246 sub handle_int_value {
247 my ($widget, $event, $dataref) = @_;
248 $_ = $widget->get_text ();
253 $widget->set_text ($_);
256 $widget->set_text ($$dataref);
260 sub handle_string_value {
261 my ($widget, $event, $dataref) = @_;
262 $$dataref = $widget->get_text ();
265 sub gdk_color_from_str {
267 my ($rr, $gg, $bb) = (0, 0 ,0);
269 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
274 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
278 sub str_from_gdk_color {
280 my $rr = $color->red / 256;
281 my $gg = $color->green / 256;
282 my $bb = $color->blue / 256;
283 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
287 sub handle_color_value {
288 my ($widget, $event, $dataref) = @_;
289 my $newcol = $widget->get_color;
290 $$dataref = &str_from_gdk_color ($newcol);
293 sub handle_selection_value {
294 my ($widget, $event, $dataref) = @_;
295 $$dataref = $widget->get_active;
298 sub get_rc_filename {
299 return $CONFIGDIR . $CONFIGRC;
302 sub set_rc_filename {
304 my @parts = split ('/', $fullname);
305 $CONFIGRC = $parts[$#parts];
306 $parts[$#parts] = '';
307 $CONFIGDIR = join ('/', @parts);
311 my ($mesg, $fatal) = @_;
312 if (defined($fatal) && $fatal eq 'die') {
313 die "$NAME: $mesg\n";
316 print "$NAME: $mesg\n";
322 my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
323 my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
324 $errordlg->set_title (_('Error message'));
329 sub check_claws_not_running() {
330 my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
331 $socket .= "claws-mail-$<";
333 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
335 error_dialog ($emsg);
341 sub check_rc_file() {
343 (defined($rcfile) && -f $rcfile) or do {
344 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
346 error_dialog ($emsg);
352 sub set_widget_hint() {
354 my ($wdgt, $hint) = @_;
355 $wdgt->set_tooltip_text ($hint);
356 $wdgt->set_has_tooltip (TRUE);
360 sub set_widget_sens() {
361 my ($wdgt, $minver) = @_;
362 $wdgt->set_sensitive (&version_greater_or_equal ($CLAWSV, $minver));
365 # graphic element creation
367 sub new_check_button_for {
368 my ($hash, $key) = @_;
369 my $name = $$hash{$key}[NAME];
370 my $label = $$hash{$key}[LABEL];
372 my $hbox = Gtk2::HBox->new (FALSE, 5);
373 my $cb = Gtk2::CheckButton->new ($label);
374 $$hash{$key}[GUI] = $cb;
375 if (defined ($HPVALUE{$name})) {
376 $cb->set_active ($HPVALUE{$name} eq '1');
378 $cb->signal_connect (clicked => sub {
380 &handle_bool_value($w, $e, \$HPVALUE{$name});
382 &set_widget_hint ($cb, $$hash{$key}[DESC]);
383 &set_widget_sens ($cb, $$hash{$key}[CMVER]);
384 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
389 sub new_text_box_for_int {
390 my ($hash, $key) = @_;
391 my $name = $$hash{$key}[NAME];
392 my $label = $$hash{$key}[LABEL];
393 my @type = split (/,/, $$hash{$key}[TYPE]);
394 push (@type, 0), push (@type, 10000) unless ($#type > 0);
396 my $hbox = Gtk2::HBox->new (FALSE, 5);
397 my $glabel = Gtk2::Label->new ($label);
398 my $pagei = int (($type[2] - $type[1]) / 10);
399 my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
400 $gentry->set_numeric (TRUE);
401 $$hash{$key}[GUI] = $gentry;
402 $gentry->signal_connect('value-changed' => sub {
404 &handle_int_value($w, $e, \$HPVALUE{$name});
406 &set_widget_hint ($gentry, $$hash{$key}[DESC]);
407 &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
408 $glabel->set_sensitive ($gentry->sensitive);
409 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
410 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
415 sub new_color_button_for {
416 my ($hash, $key) = @_;
417 my $name = $$hash{$key}[NAME];
418 my $label = $$hash{$key}[LABEL];
420 my $col = &gdk_color_from_str ($HPVALUE{$name});
421 my $hbox = Gtk2::HBox->new (FALSE, 5);
422 my $glabel = Gtk2::Label->new ($label);
423 my $button = Gtk2::ColorButton->new_with_color ($col);
424 $$hash{$key}[GUI] = $button;
425 $button->set_title ($label);
426 $button->set_relief ('none');
427 $button->signal_connect ('color-set' => sub {
429 &handle_color_value($w, $e, \$HPVALUE{$name});
431 &set_widget_hint ($button, $$hash{$key}[DESC]);
432 &set_widget_sens ($button, $$hash{$key}[CMVER]);
433 $glabel->set_sensitive ($button->sensitive);
434 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
435 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
440 sub new_selection_box_for {
441 my ($hash, $key) = @_;
442 my $name = $$hash{$key}[NAME];
443 my $label = $$hash{$key}[LABEL];
445 my $hbox = Gtk2::HBox->new (FALSE, 5);
446 my $glabel = Gtk2::Label->new ($label);
447 my $combo = Gtk2::ComboBox->new_text;
448 $$hash{$key}[GUI] = $combo;
449 my @options = split (';', $$hash{$key}[TYPE]);
450 foreach my $opt (@options) {
451 my ($index, $textkey) = split ('=', $opt);
452 $combo->insert_text ($index, $xl::s{$textkey});
454 $combo->signal_connect ('changed' => sub {
456 &handle_selection_value($w, $e, \$HPVALUE{$name});
458 $combo->set_active ($HPVALUE{$name});
459 &set_widget_hint ($combo, $$hash{$key}[DESC]);
460 &set_widget_sens ($combo, $$hash{$key}[CMVER]);
461 $glabel->set_sensitive ($combo->sensitive);
462 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
463 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
468 # more graphic helpers
470 sub new_hbox_pack() {
471 my $hbox = Gtk2::HBox->new (FALSE, 5);
472 $hbox->set_border_width (PAGE_SPC);
473 foreach my $item (@_) {
474 $hbox->pack_start ($item, FALSE, FALSE, 0);
479 sub new_vbox_pack() {
480 my $vbox = Gtk2::VBox->new (FALSE, 5);
481 $vbox->set_border_width (PAGE_SPC);
482 foreach my $item (@_) {
483 $vbox->pack_start ($item, FALSE, FALSE, 0);
488 sub new_vbox_pack_compact() {
489 my $vbox = Gtk2::VBox->new (FALSE, 0);
490 $vbox->set_border_width (0);
491 foreach my $item (@_) {
492 $vbox->pack_start ($item, FALSE, FALSE, 0);
497 sub new_subpage_frame () {
498 my ($box, $title, $notpacked) = @_;
499 my $frame = Gtk2::Frame->new ($title);
501 return &new_vbox_pack ($frame) unless defined ($notpacked);
505 # preference maps and corresponding page creation subs
507 %pr::oth = ( # other preferences
509 'addressbook_use_editaddress_dialog',
510 $xl::s{l_oth_use_dlg},
511 $xl::s{h_oth_use_dlg},
518 'cache_max_mem_usage',
519 $xl::s{l_oth_max_use},
520 $xl::s{h_oth_max_use},
521 'int,0,262144', # 0 Kb - 256 Mb
527 'cache_min_keep_time',
528 $xl::s{l_oth_min_time},
529 $xl::s{h_oth_min_time},
530 'int,0,120', # 0 minutes - 2 hours
536 'use_networkmanager',
537 $xl::s{l_oth_use_netm},
538 $xl::s{h_oth_use_netm},
546 sub new_other_page() {
547 return &new_vbox_pack (
550 &new_check_button_for(\%pr::oth, 'use_dlg')),
551 $xl::s{ab_frame}, 'not-packed'),
554 &new_text_box_for_int(\%pr::oth, 'max_use'),
555 &new_text_box_for_int(\%pr::oth, 'min_time')),
556 $xl::s{mem_frame}, 'not-packed'),
559 &new_check_button_for(\%pr::oth, 'use_netm')),
560 $xl::s{netm_frame}, 'not-packed')
564 %pr::gui = ( # gui bells and whistles
567 $xl::s{l_gui_b_unread},
568 $xl::s{h_gui_b_unread},
576 $xl::s{l_gui_no_markup},
577 $xl::s{h_gui_no_markup},
584 'enable_dotted_lines',
585 $xl::s{l_gui_dot_lines},
586 $xl::s{h_gui_dot_lines},
594 $xl::s{l_gui_h_scroll},
595 $xl::s{h_gui_h_scroll},
603 $xl::s{l_gui_swp_from},
604 $xl::s{h_gui_swp_from},
611 'folderview_vscrollbar_policy',
612 $xl::s{l_gui_v_scroll},
613 $xl::s{h_gui_v_scroll},
614 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
620 'stripes_color_offset',
621 $xl::s{l_gui_strip_off},
622 $xl::s{h_gui_strip_off},
623 'int,0,10000', # no idea what this number means
629 'textview_cursor_visible',
630 $xl::s{l_gui_cursor_v},
631 $xl::s{h_gui_cursor_v},
638 'toolbar_detachable',
639 $xl::s{l_gui_toolbar_d},
640 $xl::s{h_gui_toolbar_d},
647 'use_stripes_everywhere',
648 $xl::s{l_gui_strip_all},
649 $xl::s{h_gui_strip_all},
656 'use_stripes_in_summaries',
657 $xl::s{l_gui_strip_sum},
658 $xl::s{h_gui_strip_sum},
666 $xl::s{l_gui_two_line_v},
667 $xl::s{h_gui_two_line_v},
674 'show_compose_margin',
675 $xl::s{l_gui_margin_co},
676 $xl::s{h_gui_margin_co},
685 my $gf = Gtk2::VBox->new (FALSE, 5);
686 $gf->set_border_width (PAGE_SPC);
688 my $cb_dot_lines = &new_check_button_for (\%pr::gui, 'dot_lines');
689 my $cb_toolbar_d = &new_check_button_for (\%pr::gui, 'toolbar_d');
691 $gf->pack_start (&new_subpage_frame (
693 &new_check_button_for (\%pr::gui, 'strip_all'),
694 &new_check_button_for (\%pr::gui, 'strip_sum'),
695 &new_text_box_for_int (\%pr::gui, 'strip_off')),
696 $xl::s{stripes_frame}, 'not-packed'),
697 FALSE, FALSE, FRAME_SPC);
698 $gf->pack_start (&new_subpage_frame (
700 &new_check_button_for (\%pr::gui, 'b_unread'),
701 &new_check_button_for (\%pr::gui, 'swp_from'),
702 &new_check_button_for (\%pr::gui, 'two_linev')),
703 $xl::s{mlist_frame}, 'not-packed'),
704 FALSE, FALSE, FRAME_SPC);
705 $gf->pack_start (&new_subpage_frame (
707 &new_check_button_for (\%pr::gui, 'cursor_v')),
708 $xl::s{mview_frame}, 'not-packed'),
709 FALSE, FALSE, FRAME_SPC);
710 $gf->pack_start (&new_subpage_frame (
712 &new_check_button_for (\%pr::gui, 'no_markup'),
713 &new_check_button_for (\%pr::gui, 'margin_co')),
714 $xl::s{compo_frame}, 'not-packed'),
715 FALSE, FALSE, FRAME_SPC);
716 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
717 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
718 $gf->pack_start (&new_subpage_frame (
720 &new_check_button_for (\%pr::gui, 'h_scroll'),
721 &new_selection_box_for (\%pr::gui, 'v_scroll')),
722 $xl::s{sbar_frame}, 'not-packed'),
723 FALSE, FALSE, FRAME_SPC);
728 %pr::beh = ( # tweak some behaviour
731 $xl::s{l_beh_hover_t},
732 $xl::s{h_beh_hover_t},
733 'int,100,3000', # 0.1 seconds - 3 seconds
740 $xl::s{l_beh_dangerous},
741 $xl::s{h_beh_dangerous},
748 'respect_flowed_format',
749 $xl::s{l_beh_flowed},
750 $xl::s{h_beh_flowed},
757 'save_parts_readwrite',
758 $xl::s{l_beh_parts_rw},
759 $xl::s{h_beh_parts_rw},
766 'skip_ssl_cert_check',
767 $xl::s{l_beh_skip_ssl},
768 $xl::s{h_beh_skip_ssl},
775 'statusbar_update_step',
776 $xl::s{l_beh_up_step},
777 $xl::s{h_beh_up_step},
778 'int,1,200', # 1 item - 200 items
784 'thread_by_subject_max_age',
785 $xl::s{l_beh_thread_a},
786 $xl::s{h_beh_thread_a},
787 'int,1,30', # 1 day - 30 days
794 $xl::s{l_beh_unsafe_ssl},
795 $xl::s{h_beh_unsafe_ssl},
802 'utf8_instead_of_locale_for_broken_mail',
803 $xl::s{l_beh_use_utf8},
804 $xl::s{h_beh_use_utf8},
812 $xl::s{l_beh_warn_dnd},
813 $xl::s{h_beh_warn_dnd},
820 'outgoing_fallback_to_ascii',
821 $xl::s{l_beh_out_ascii},
822 $xl::s{h_beh_out_ascii},
829 'primary_paste_unselects',
830 $xl::s{l_beh_pp_unsel},
831 $xl::s{h_beh_pp_unsel},
839 sub new_behaviour_page() {
840 my $bf = Gtk2::VBox->new (FALSE, 5);
841 $bf->set_border_width (PAGE_SPC);
843 my $tb_up_step = &new_text_box_for_int (\%pr::beh, 'up_step');
844 my $tb_thread_a = &new_text_box_for_int (\%pr::beh, 'thread_a');
846 $bf->pack_start (&new_subpage_frame (
848 &new_text_box_for_int (\%pr::beh, 'hover_t'),
849 &new_check_button_for (\%pr::beh, 'warn_dnd')),
850 $xl::s{dnd_frame}, 'not-packed'),
851 FALSE, FALSE, FRAME_SPC);
852 $bf->pack_start (&new_subpage_frame (
854 &new_check_button_for (\%pr::beh, 'skip_ssl'),
855 &new_check_button_for (\%pr::beh, 'unsafe_ssl')),
856 $xl::s{ssl_frame}, 'not-packed'),
857 FALSE, FALSE, FRAME_SPC);
858 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
859 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
860 $bf->pack_start (&new_subpage_frame (
862 &new_check_button_for (\%pr::beh, 'flowed'),
863 &new_check_button_for (\%pr::beh, 'parts_rw'),
864 &new_check_button_for (\%pr::beh, 'use_utf8'),
865 &new_check_button_for (\%pr::beh, 'dangerous'),
866 &new_check_button_for (\%pr::beh, 'out_ascii'),
867 &new_check_button_for (\%pr::beh, 'pp_unsel')),
868 $xl::s{msgs_frame}, 'not-packed'),
869 FALSE, FALSE, FRAME_SPC);
874 %pr::col = ( # a variety of colours
877 $xl::s{l_col_emphasis},
878 $xl::s{h_col_emphasis},
886 $xl::s{l_col_log_err},
887 $xl::s{h_col_log_err},
895 $xl::s{l_col_log_in},
896 $xl::s{h_col_log_in},
904 $xl::s{l_col_log_msg},
905 $xl::s{h_col_log_msg},
913 $xl::s{l_col_log_out},
914 $xl::s{h_col_log_out},
922 $xl::s{l_col_log_warn},
923 $xl::s{h_col_log_warn},
931 sub new_colours_page() {
932 return &new_vbox_pack (
935 &new_color_button_for (\%pr::col, 'emphasis')),
936 $xl::s{msgview_frame}, 'not-packed'),
939 &new_color_button_for (\%pr::col, 'log_err'),
940 &new_color_button_for (\%pr::col, 'log_in'),
941 &new_color_button_for (\%pr::col, 'log_msg'),
942 &new_color_button_for (\%pr::col, 'log_out'),
943 &new_color_button_for (\%pr::col, 'log_warn')),
944 $xl::s{log_frame}, 'not-packed')
948 %pr::win = ( # tweak window positions and/or sizes
953 'int,0,3000', # 0 pixels - 3000 pixels
962 'int,0,3000', # 0 pixels - 3000 pixels
971 'int,0,3000', # 0 pixels - 3000 pixels
980 'int,0,3000', # 0 pixels - 3000 pixels
987 $xl::s{l_win_main_mx},
988 $xl::s{h_win_main_mx},
995 'mainwin_fullscreen',
996 $xl::s{l_win_main_fs},
997 $xl::s{h_win_main_fs},
1004 'main_messagewin_x',
1007 'int,0,3000', # 0 pixels - 3000 pixels
1013 'main_messagewin_y',
1016 'int,0,3000', # 0 pixels - 3000 pixels
1025 'int,0,3000', # 0 pixels - 3000 pixels
1031 'messagewin_height',
1034 'int,0,3000', # 0 pixels - 3000 pixels
1043 'int,0,3000', # 0 pixels - 3000 pixels
1052 'int,0,3000', # 0 pixels - 3000 pixels
1061 'int,0,3000', # 0 pixels - 3000 pixels
1067 'receivewin_height',
1070 'int,0,3000', # 0 pixels - 3000 pixels
1079 'int,0,3000', # 0 pixels - 3000 pixels
1088 'int,0,3000', # 0 pixels - 3000 pixels
1094 'folderitemwin_width',
1097 'int,0,3000', # 0 pixels - 3000 pixels
1103 'folderitemwin_height',
1106 'int,0,3000', # 0 pixels - 3000 pixels
1112 'folderselwin_width',
1115 'int,0,3000', # 0 pixels - 3000 pixels
1121 'folderselwin_height',
1124 'int,0,3000', # 0 pixels - 3000 pixels
1133 'int,0,3000', # 0 pixels - 3000 pixels
1142 'int,0,3000', # 0 pixels - 3000 pixels
1148 'addressbookwin_width',
1151 'int,0,3000', # 0 pixels - 3000 pixels
1157 'addressbookwin_height',
1160 'int,0,3000', # 0 pixels - 3000 pixels
1166 'addressbookeditpersonwin_width',
1169 'int,0,3000', # 0 pixels - 3000 pixels
1175 'addressbookeditpersonwin_height',
1178 'int,0,3000', # 0 pixels - 3000 pixels
1184 'addressbookeditgroupwin_width',
1187 'int,0,3000', # 0 pixels - 3000 pixels
1193 'addressbookeditgroupwin_height',
1196 'int,0,3000', # 0 pixels - 3000 pixels
1202 'addressaddwin_width',
1205 'int,0,3000', # 0 pixels - 3000 pixels
1211 'addressaddwin_height',
1214 'int,0,3000', # 0 pixels - 3000 pixels
1220 'addressbook_folderselwin_width',
1223 'int,0,3000', # 0 pixels - 3000 pixels
1229 'addressbook_folderselwin_height',
1232 'int,0,3000', # 0 pixels - 3000 pixels
1238 'editaccountwin_width',
1241 'int,0,3000', # 0 pixels - 3000 pixels
1247 'editaccountwin_height',
1250 'int,0,3000', # 0 pixels - 3000 pixels
1256 'accountswin_width',
1259 'int,0,3000', # 0 pixels - 3000 pixels
1265 'accountswin_height',
1268 'int,0,3000', # 0 pixels - 3000 pixels
1274 'filteringwin_width',
1277 'int,0,3000', # 0 pixels - 3000 pixels
1283 'filteringwin_height',
1286 'int,0,3000', # 0 pixels - 3000 pixels
1292 'filteringactionwin_width',
1295 'int,0,3000', # 0 pixels - 3000 pixels
1301 'filteringactionwin_height',
1304 'int,0,3000', # 0 pixels - 3000 pixels
1310 'filtering_debugwin_width',
1313 'int,0,3000', # 0 pixels - 3000 pixels
1319 'filtering_debugwin_height',
1322 'int,0,3000', # 0 pixels - 3000 pixels
1331 'int,0,3000', # 0 pixels - 3000 pixels
1337 'matcherwin_height',
1340 'int,0,3000', # 0 pixels - 3000 pixels
1349 'int,0,3000', # 0 pixels - 3000 pixels
1358 'int,0,3000', # 0 pixels - 3000 pixels
1364 'templateswin_width',
1367 'int,0,3000', # 0 pixels - 3000 pixels
1373 'templateswin_height',
1376 'int,0,3000', # 0 pixels - 3000 pixels
1385 'int,0,3000', # 0 pixels - 3000 pixels
1391 'actionswin_height',
1394 'int,0,3000', # 0 pixels - 3000 pixels
1403 'int,0,3000', # 0 pixels - 3000 pixels
1412 'int,0,3000', # 0 pixels - 3000 pixels
1421 'int,0,3000', # 0 pixels - 3000 pixels
1427 'pluginswin_height',
1430 'int,0,3000', # 0 pixels - 3000 pixels
1439 'int,0,3000', # 0 pixels - 3000 pixels
1448 'int,0,3000', # 0 pixels - 3000 pixels
1454 'print_previewwin_width',
1457 'int,0,3000', # 0 pixels - 3000 pixels
1463 'print_previewwin_height',
1466 'int,0,3000', # 0 pixels - 3000 pixels
1473 sub new_winpos_subpage_main() {
1474 return &new_subpage_frame (
1475 &new_vbox_pack_compact (
1477 &new_text_box_for_int (\%pr::win, 'main_x'),
1478 &new_text_box_for_int (\%pr::win, 'main_y')),
1480 &new_text_box_for_int (\%pr::win, 'main_w'),
1481 &new_text_box_for_int (\%pr::win, 'main_h')),
1483 &new_check_button_for (\%pr::win, 'main_fs'),
1484 &new_check_button_for (\%pr::win, 'main_mx'))),
1489 sub new_winpos_subpage_msgs() {
1490 return &new_subpage_frame (
1491 &new_vbox_pack_compact (
1493 &new_text_box_for_int (\%pr::win, 'msgs_x'),
1494 &new_text_box_for_int (\%pr::win, 'msgs_y')),
1496 &new_text_box_for_int (\%pr::win, 'msgs_w'),
1497 &new_text_box_for_int (\%pr::win, 'msgs_h'))),
1502 sub new_winpos_subpage_sendrecv() {
1503 return &new_vbox_pack (
1504 &new_subpage_frame (
1506 &new_text_box_for_int (\%pr::win, 'send_w'),
1507 &new_text_box_for_int (\%pr::win, 'send_h')),
1508 _('Send window'), 'not-packed'),
1509 &new_subpage_frame (
1511 &new_text_box_for_int (\%pr::win, 'recv_w'),
1512 &new_text_box_for_int (\%pr::win, 'recv_h')),
1513 _('Receive window'), 'not-packed')
1517 sub new_winpos_subpage_fold() {
1518 return &new_vbox_pack (
1519 &new_subpage_frame (
1520 &new_vbox_pack_compact (
1522 &new_text_box_for_int (\%pr::win, 'fold_x'),
1523 &new_text_box_for_int (\%pr::win, 'fold_y')),
1525 &new_text_box_for_int (\%pr::win, 'fold_w'),
1526 &new_text_box_for_int (\%pr::win, 'fold_h'))),
1527 _('Folder window'), 'not-packed'),
1528 &new_subpage_frame (
1530 &new_text_box_for_int (\%pr::win, 'fsel_w'),
1531 &new_text_box_for_int (\%pr::win, 'fsel_h')),
1532 _('Folder selection window'), 'not-packed')
1536 sub new_winpos_subpage_addrbook() {
1537 return &new_vbox_pack (
1538 &new_subpage_frame (
1540 &new_text_box_for_int (\%pr::win, 'addr_w'),
1541 &new_text_box_for_int (\%pr::win, 'addr_h')),
1542 _('Addressbook main window'), 'not-packed'),
1543 &new_subpage_frame (
1545 &new_text_box_for_int (\%pr::win, 'adep_w'),
1546 &new_text_box_for_int (\%pr::win, 'adep_h')),
1547 _('Edit person window'), 'not-packed'),
1548 &new_subpage_frame (
1550 &new_text_box_for_int (\%pr::win, 'adeg_w'),
1551 &new_text_box_for_int (\%pr::win, 'adeg_h')),
1552 _('Edit group window'), 'not-packed'),
1553 &new_subpage_frame (
1555 &new_text_box_for_int (\%pr::win, 'adda_w'),
1556 &new_text_box_for_int (\%pr::win, 'adda_h')),
1557 _('Add address window'), 'not-packed'),
1558 &new_subpage_frame (
1560 &new_text_box_for_int (\%pr::win, 'addf_w'),
1561 &new_text_box_for_int (\%pr::win, 'addf_h')),
1562 _('Folder select window'), 'not-packed')
1566 sub new_winpos_subpage_accounts() {
1567 return &new_vbox_pack (
1568 &new_subpage_frame (
1570 &new_text_box_for_int (\%pr::win, 'acco_w'),
1571 &new_text_box_for_int (\%pr::win, 'acco_h')),
1572 _('Accounts window'), 'not-packed'),
1573 &new_subpage_frame (
1575 &new_text_box_for_int (\%pr::win, 'acce_w'),
1576 &new_text_box_for_int (\%pr::win, 'acce_h')),
1577 _('Edit account window'), 'not-packed')
1581 sub new_winpos_subpage_filtering() {
1582 return &new_vbox_pack (
1583 &new_subpage_frame (
1585 &new_text_box_for_int (\%pr::win, 'filt_w'),
1586 &new_text_box_for_int (\%pr::win, 'filt_h')),
1587 _('Filtering window'), 'not-packed'),
1588 &new_subpage_frame (
1590 &new_text_box_for_int (\%pr::win, 'fila_w'),
1591 &new_text_box_for_int (\%pr::win, 'fila_h')),
1592 _('Filtering actions window'), 'not-packed'),
1593 &new_subpage_frame (
1595 &new_text_box_for_int (\%pr::win, 'fild_w'),
1596 &new_text_box_for_int (\%pr::win, 'fild_h')),
1597 _('Filtering debug window'), 'not-packed'),
1598 &new_subpage_frame (
1600 &new_text_box_for_int (\%pr::win, 'matc_w'),
1601 &new_text_box_for_int (\%pr::win, 'matc_h')),
1602 _('Matcher window'), 'not-packed')
1606 sub new_winpos_subpage_prefs() {
1607 return &new_vbox_pack (
1608 &new_subpage_frame (
1610 &new_text_box_for_int (\%pr::win, 'pref_w'),
1611 &new_text_box_for_int (\%pr::win, 'pref_h')),
1612 _('Preferences window'), 'not-packed'),
1613 &new_subpage_frame (
1615 &new_text_box_for_int (\%pr::win, 'temp_w'),
1616 &new_text_box_for_int (\%pr::win, 'temp_h')),
1617 _('Templates window'), 'not-packed'),
1618 &new_subpage_frame (
1620 &new_text_box_for_int (\%pr::win, 'acti_w'),
1621 &new_text_box_for_int (\%pr::win, 'acti_h')),
1622 _('Actions window'), 'not-packed'),
1623 &new_subpage_frame (
1625 &new_text_box_for_int (\%pr::win, 'tags_w'),
1626 &new_text_box_for_int (\%pr::win, 'tags_h')),
1627 _('Tags window'), 'not-packed'),
1628 &new_subpage_frame (
1630 &new_text_box_for_int (\%pr::win, 'plug_w'),
1631 &new_text_box_for_int (\%pr::win, 'plug_h')),
1632 _('Plugins window'), 'not-packed')
1636 sub new_winpos_subpage_misc() {
1637 return &new_vbox_pack (
1638 &new_subpage_frame (
1640 &new_text_box_for_int (\%pr::win, 'logw_w'),
1641 &new_text_box_for_int (\%pr::win, 'logw_h')),
1642 _('Log window'), 'not-packed'),
1643 &new_subpage_frame (
1645 &new_text_box_for_int (\%pr::win, 'prin_w'),
1646 &new_text_box_for_int (\%pr::win, 'prin_h')),
1647 _('Print preview window'), 'not-packed'),
1648 &new_subpage_frame (
1650 &new_text_box_for_int (\%pr::win, 'sour_w'),
1651 &new_text_box_for_int (\%pr::win, 'sour_h')),
1652 _('View source window'), 'not-packed')
1656 sub new_winpos_page() {
1657 my $winbook = Gtk2::Notebook->new;
1658 $winbook->set_tab_pos ('right');
1659 $winbook->append_page (&new_winpos_subpage_main, _('Main'));
1660 $winbook->append_page (&new_winpos_subpage_msgs, _('Message'));
1661 $winbook->append_page (&new_winpos_subpage_sendrecv, _('Send/Receive'));
1662 $winbook->append_page (&new_winpos_subpage_fold, _('Folder'));
1663 $winbook->append_page (&new_winpos_subpage_addrbook, _('Addressbook'));
1664 $winbook->append_page (&new_winpos_subpage_accounts, _('Accounts'));
1665 $winbook->append_page (&new_winpos_subpage_filtering, _('Filtering'));
1666 $winbook->append_page (&new_winpos_subpage_prefs, _('Preferences'));
1667 $winbook->append_page (&new_winpos_subpage_misc, _('Other'));
1672 sub print_version() {
1673 print $xl::s{about_title} . "\n";
1674 print $xl::s{about_version} . " $VERSION\n";
1675 print "Perl-GLib " . $Glib::VERSION;
1676 # version info stuff appeared in 1.040
1677 if ($Glib::VERSION >= 1.040) {
1678 print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
1679 . _(", running with ") . join(".", &Glib::major_version,
1680 &Glib::minor_version, &Glib::micro_version);
1683 print "Perl-GTK2 " . $Gtk2::VERSION;
1684 if ($Gtk2::VERSION >= 1.040) {
1685 print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1686 . _(", running with ") . join(".", &Gtk2::major_version,
1687 &Gtk2::minor_version, &Gtk2::micro_version);
1690 my $clawsver = ($CLAWSV eq "") ?
1691 _("was not found!") :
1692 (_("returned version ") . $CLAWSV);
1693 print "Claws Mail " . $clawsver . "\n";
1696 # the command line help
1698 my $line = '-' x length ($xl::s{about_title}) . "\n";
1700 print $xl::s{about_title} . "\n";
1702 print _("Syntax:\n");
1703 print _(" clawsker [options]\n");
1704 print _("Options:\n");
1705 print _(" --help Prints this help screen.\n");
1706 print _(" --version Prints version infos.\n");
1707 print _(" --verbose More messages on standard output.\n");
1708 print _(" --alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1709 print _(" --clawsrc <file> Uses <file> as full resource name.\n");
1712 # handle errors which don't allow to run
1713 sub command_line_fatal() {
1715 my $emsg = $xl::s{e_error} . $reason;
1716 error_dialog ($emsg);
1717 log_message ("$emsg", 'die');
1720 # parse the command line
1721 sub parse_command_line() {
1722 $CLAWSV = &get_claws_version;
1724 while (defined($ARGV[$arg])) {
1738 /--use-claws-version/ && do {
1740 &command_line_fatal ("required version")
1741 unless defined($ARGV[$arg]);
1742 &command_line_fatal ("required a dotted numeric value")
1743 unless ($ARGV[$arg] =~ /[\d\.]+/);
1744 $CLAWSV = $ARGV[$arg];
1747 /--alternate-config-dir/ && do {
1749 &command_line_fatal ($xl::s{e_requireddir})
1750 unless defined($ARGV[$arg]);
1751 &command_line_fatal ($xl::s{e_notadir})
1752 unless -d $ARGV[$arg];
1753 $CONFIGDIR = $ARGV[$arg];
1755 unless ($CONFIGDIR =~ /.*\/$/);
1756 $ALTCONFIGDIR = TRUE;
1761 &command_line_fatal($xl::s{e_requiredfile})
1762 unless defined($ARGV[$arg]);
1763 &command_line_fatal($xl::s{e_notafile})
1764 unless -f $ARGV[$arg];
1765 &set_rc_filename ($ARGV[$arg]);
1768 /.*/ && &command_line_fatal (
1769 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1773 # eveything continues...
1777 # update the hidden preferences status from loaded values
1778 sub init_hidden_preferences() {
1779 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1780 foreach my $key (keys %$hash) {
1781 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1787 # load current status from disc
1788 sub load_preferences() {
1789 my $rc = &get_rc_filename;
1790 &log_message ("Loading preferences from $rc\n");
1791 return FALSE unless &check_rc_file ($rc);
1792 return FALSE unless &check_claws_not_running;
1796 if (/^([8a-z_]+)=(.*)$/) {
1804 # save current preferences to disc
1805 sub save_preferences() {
1806 my $rc = &get_rc_filename;
1807 &log_message ("Saving preferences to $rc\n");
1808 return FALSE unless &check_rc_file ($rc);
1809 return FALSE unless &check_claws_not_running;
1810 my $rcbak = "$rc.backup";
1811 rename ($rc, $rcbak);
1813 open (RCB, "<$rcbak");
1816 if (/^([8a-z_]+)=(.*)$/) {
1817 if (defined($HPVALUE{$1})) {
1818 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1821 print RCF $_ . "\n";
1825 print RCF $_ . "\n";
1834 sub new_notebook() {
1835 my $nb = Gtk2::Notebook->new;
1837 $nb->append_page (&new_behaviour_page, $xl::s{tab_behaviour});
1838 $nb->append_page (&new_colours_page, $xl::s{tab_colours});
1839 $nb->append_page (&new_gui_page, $xl::s{tab_gui});
1840 $nb->append_page (&new_other_page, $xl::s{tab_other});
1841 $nb->append_page (&new_winpos_page, $xl::s{tab_winpos});
1846 # create an about dialog
1847 sub new_about_dialog() {
1849 my $title = $xl::s{about_title};
1850 my $lic = $xl::s{about_license};
1851 my $vers = $xl::s{about_version} . " $VERSION";
1853 "This program is free software: you can redistribute it and/or modify
1854 it under the terms of the GNU General Public License as published by
1855 the Free Software Foundation, either version 3 of the License, or
1856 (at your option) any later version.
1858 This program is distributed in the hope that it will be useful,
1859 but WITHOUT ANY WARRANTY; without even the implied warranty of
1860 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1861 GNU General Public License for more details.
1863 You should have received a copy of the GNU General Public License
1864 along with this program. If not, see <http://www.gnu.org/licenses/>.";
1865 my $year = "2007-2010";
1866 my $holder = "Ricardo Mones <ricardo\@mones.org>";
1867 my $url = "http://www.claws-mail.org/clawsker";
1869 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
1870 [qw/modal destroy-with-parent/],
1872 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
1873 . "<span size=\"large\">$vers</span>\n\n"
1874 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
1875 . "<span>Copyright $year by $holder</span>\n\n"
1876 . "<span size=\"large\">$lic</span>\n\n"
1877 . "<span size=\"small\">$license</span>");
1878 $dialog->set_title ($xl::s{about});
1883 # create buttons box
1884 sub new_button_box() {
1885 my ($parent, $adlg) = @_;
1886 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
1887 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
1888 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
1889 # disable button until is really implemented
1890 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
1891 my $hbox = Gtk2::HBox->new (FALSE, 5);
1893 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
1894 $b_apply->signal_connect (clicked => sub { &save_preferences ($parent) });
1895 # $b_undo->signal_connect (clicked => sub { &undo_current_changes });
1896 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
1898 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
1899 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
1900 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
1901 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
1907 $main_window = Gtk2::Window->new ('toplevel');
1908 exit unless &parse_command_line;
1909 exit unless &load_preferences;
1910 exit unless &init_hidden_preferences;
1912 my $box = Gtk2::VBox->new (FALSE, 5);
1913 $box->set_border_width(3);
1914 my $about = &new_about_dialog;
1915 $box->pack_start (&new_notebook, FALSE, FALSE, 0);
1916 $box->pack_end (&new_button_box ($main_window, $about), FALSE, FALSE, 0);
1917 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
1918 $main_window->set_title ($xl::s{win_title});
1919 $main_window->add ($box);
1920 $main_window->show_all;