2547bf63da28b0ef2e8eb3fa63f75aeb8d23cf2b
[clawsker.git] / clawsker
1 #!/usr/bin/perl -w
2 #
3 # Clawsker :: A Claws Mail Tweaker
4 #
5 use strict;
6 use encoding 'utf8';
7 use Glib qw(TRUE FALSE);
8 use Gtk2 -init;
9 use POSIX qw(setlocale);
10 use Locale::gettext;
11 use Encode;
12
13 my $NAME = 'clawsker';
14 my $PREFIX = '@PREFIX@';
15 my $LIBDIR = '@LIBDIR@';
16 my $VERSION = '@VERSION@';
17 my $VERBOSE = FALSE;
18 my $CLAWSV = undef;
19 my $main_window = undef;
20
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));
25 textdomain ($NAME);
26
27 my $SHOWHINTS = FALSE;
28 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
29
30 sub _ {
31     my $str = shift;
32     my %par = @_;
33     my $xla = gettext ($str);
34     if (scalar(keys(%par)) > 0) {
35         foreach my $key (keys %par) {
36             $xla =~ s/\{$key\}/$par{$key}/g;
37         }
38     }
39     return decode_utf8($xla);
40 }
41
42 # default messages
43 %xl::s = (
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:'),
49
50     tab_colours => _('Colours'),
51     tab_behaviour => _('Behaviour'),
52     tab_gui => _('GUI'),
53     tab_other => _('Other'),
54     tab_winpos => _('Windows'),
55
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'),
69
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.'),
78     
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'),
115     l_gui_zero_char => _('Zero replacement character'),
116     h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List'),
117
118     l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
119     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.'),
120     l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
121     h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
122     l_beh_flowed => _('Respect format=flowed in messages'),
123     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.'),
124     l_beh_parts_rw => _('Allow writable temporary files'),
125     h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
126     l_beh_skip_ssl => _('Don\'t check SSL certificates'),
127     h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
128     l_beh_up_step => _('Progress bar update step (items)'),
129     h_beh_up_step => _('Update stepping in progress bars.'),
130     l_beh_thread_a => _('Maximum age when threading by subject (days)'),
131     h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
132     l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
133     h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
134     l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
135     h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
136     l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
137     h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
138     l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
139     h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
140     l_beh_pp_unsel => _('Primary paste unselects selection'),
141     h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
142     l_beh_inline_at => _('Show inline attachments'),
143     h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
144
145     l_col_emphasis => _('X-Mailer header'),
146     h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
147     l_col_log_err => _('Error messages'),
148     h_col_log_err => _('Colour for error messages in log window.'),
149     l_col_log_in => _('Server messages'),
150     h_col_log_in => _('Colour for messages received from servers in log window.'),
151     l_col_log_msg => _('Standard messages'),
152     h_col_log_msg => _('Colour for messages in log window.'),
153     l_col_log_out => _('Client messages'),
154     h_col_log_out => _('Colour for messages sent to servers in log window.'),
155     l_col_log_warn => _('Warnings'),
156     h_col_log_warn => _('Colour for warning messages in log window.'),
157
158     l_win_x => _('X position'),
159     h_win_x => _('X coordinate for window\'s top-left corner.'),
160     l_win_y => _('Y position'),
161     h_win_y => _('Y coordinate for window\'s top-left corner.'),
162     l_win_w => _('Width'),
163     h_win_w => _('Window\'s width in pixels.'),
164     l_win_h => _('Height'),
165     h_win_h => _('Window\'s height in pixels.'),
166
167     l_win_main_mx => _('Maximized'),
168     h_win_main_mx => _('Changes window maximized status.'),
169     l_win_main_fs => _('Full-screen'),
170     h_win_main_fs => _('Changes full screen status.'),
171
172     e_error => _('Error: '),
173     e_noclawsrc => _('resource file for Claws Mail was not found.'),
174     e_running => _('seems Claws Mail is currently running, close it first.'),
175     e_requireddir => _('option requires a directory name.'),
176     e_requiredfile => _('option requires a file name.'),
177     e_notadir => _('specified name is not a directory or does not exist.'),
178     e_notafile => _('specified name is not a file or does not exist.'),
179 );
180
181 # all preferences read by load_preferences
182 my %PREFS = ();
183 # values of all preferences handled by clawsker
184 my %HPVALUE = ();
185 # default config dir and file name
186 my $ALTCONFIGDIR = FALSE;
187 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
188 my $CONFIGRC = 'clawsrc';
189
190 # index constants for preference arrays
191 use constant NAME  => 0; # the name on the rc file
192 use constant LABEL => 1; # the label on the GUI
193 use constant DESC  => 2; # the description for the hint/help
194 use constant TYPE  => 3; # data type: bool, int, float, string, color
195 use constant CMVER => 4; # lowest Claws Mail version the feature exists
196 use constant CMDEF => 5; # default value for the preference in Claws Mail
197 use constant GUI   => 6; # GUI element
198
199 # constants for GUI spacing
200 use constant HBOX_SPC => 5;
201 use constant FRAME_SPC => 2;
202 use constant PAGE_SPC => 5;
203
204 # version functions
205
206 sub version_greater_or_equal() {
207     my ($version, $refvers) = @_;
208     my @version = split (/\./, $version);
209     my @refvers = split (/\./, $refvers);
210     while ($#version < $#refvers) {
211         push (@version, '0');
212     }
213     my $idx = 0;
214     while (($idx <= $#refvers) 
215             and (int ($version[$idx]) == int ($refvers[$idx]))) {
216         ++$idx;
217     }
218     return TRUE if (($idx > $#refvers)
219         or (int ($version[$idx]) >= int ($refvers[$idx])));
220     return FALSE;
221 }
222
223 sub get_claws_version() {
224     my @cmbin = (
225         'claws-mail',
226     );
227     my $res = "";
228     foreach my $bin (@cmbin) {
229         $_ = qx/which $bin/;
230         chomp;
231         last if ($_ ne "");
232     }
233     return "" unless ($_); # not installed
234     $_ = qx/$_ -v/;
235     chomp;
236     my @fver = split (/ /);
237     die "Invalid version string" unless ($fver[2] eq "version");
238     my @ver = split (/\./, $fver[3]);
239     $res .= "$ver[0].";
240     $res .= "$ver[1].";
241     if ($ver[2] =~ /(\d+)cvs(\d+)/) {
242         $res .= "$1.$2";
243     }
244     else {
245         $res .= "$ver[2].0";
246     }
247     return $res;
248 }
249
250 # data handlers and auxiliar functions
251
252 sub handle_bool_value {
253     my ($widget, $event, $dataref) = @_;
254     $$dataref = ($widget->get_active ())? '1': '0';
255 }
256
257 sub handle_int_value {
258     my ($widget, $event, $dataref) = @_;
259     $_ = $widget->get_text ();
260     s/^\s+//;
261     s/\s+$//;
262     if (/^[0-9]+$/) {
263         $$dataref = $_;
264         $widget->set_text ($_);
265     }
266     else {
267         $widget->set_text ($$dataref);
268     }
269 }
270
271 sub handle_string_value {
272     my ($widget, $event, $dataref) = @_;
273     $$dataref = $widget->get_text ();
274 }
275
276 sub handle_nchar_value {
277     my ($widget, $event, $dataref, $minlen) = @_;
278     $_ = substr ($widget->get_text (), 0, $minlen);
279     $widget->set_text ($_);
280     $$dataref = $_;
281 }
282
283 sub gdk_color_from_str {
284     my ($str) = @_;
285     my ($rr, $gg, $bb) = (0, 0 ,0);
286     $_ = uc ($str);
287     if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
288         $rr = hex($1) * 256;
289         $gg = hex($2) * 256; 
290         $bb = hex($3) * 256;
291     }
292     my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
293     return $color;
294 }
295
296 sub str_from_gdk_color {
297     my ($color) = @_;
298     my $rr = $color->red / 256;
299     my $gg = $color->green / 256;
300     my $bb = $color->blue / 256;
301     my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
302     return $str;
303 }
304
305 sub handle_color_value {
306     my ($widget, $event, $dataref) = @_;
307     my $newcol = $widget->get_color;
308     $$dataref = &str_from_gdk_color ($newcol);
309 }
310
311 sub handle_selection_value {
312     my ($widget, $event, $dataref) = @_;
313     $$dataref = $widget->get_active;
314 }
315
316 sub get_rc_filename {
317     return $CONFIGDIR . $CONFIGRC;
318 }
319
320 sub set_rc_filename {
321     my ($fullname) = @_;
322     my @parts = split ('/', $fullname);
323     $CONFIGRC = $parts[$#parts];
324     $parts[$#parts] = '';
325     $CONFIGDIR = join ('/', @parts);
326 }
327
328 sub log_message {
329     my ($mesg, $fatal) = @_;
330     if (defined($fatal) && $fatal eq 'die') {
331         die "$NAME: $mesg\n";
332     }
333     if ($VERBOSE) {
334         print "$NAME: $mesg\n";
335     }
336 }
337
338 sub error_dialog {
339     my ($emsg) = @_;
340     my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
341     my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
342     $errordlg->set_title (_('Error message'));
343     $errordlg->run;
344     $errordlg->destroy;
345 }
346
347 sub check_claws_not_running() {
348     my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
349     $socket .= "claws-mail-$<";
350     -S $socket and do {
351         my $emsg = "$xl::s{e_error}$xl::s{e_running}";
352         log_message ($emsg);
353         error_dialog ($emsg);
354         return FALSE;
355      };
356      return TRUE;
357 }
358
359 sub check_rc_file() {
360     my ($rcfile) = @_;
361     (defined($rcfile) && -f $rcfile) or do {
362        my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
363         log_message ($emsg);
364         error_dialog ($emsg);
365         return FALSE;
366     };
367     return TRUE;
368 }
369
370 sub set_widget_hint() {
371     if ($SHOWHINTS) {
372         my ($wdgt, $hint) = @_;    
373         $wdgt->set_tooltip_text ($hint);
374         $wdgt->set_has_tooltip (TRUE);
375     }
376 }
377
378 sub set_widget_sens() {
379     my ($wdgt, $minver) = @_;
380     $wdgt->set_sensitive (&version_greater_or_equal ($CLAWSV, $minver));
381 }
382
383 # graphic element creation 
384
385 sub new_check_button_for {
386     my ($hash, $key) = @_;
387     my $name = $$hash{$key}[NAME];
388     my $label = $$hash{$key}[LABEL];
389     #
390     my $hbox = Gtk2::HBox->new (FALSE, 5);
391     my $cb = Gtk2::CheckButton->new ($label);
392     $$hash{$key}[GUI] = $cb;
393     if (defined ($HPVALUE{$name})) {
394         $cb->set_active ($HPVALUE{$name} eq '1');
395     }
396     $cb->signal_connect (clicked => sub {
397             my ($w, $e) = @_;
398             &handle_bool_value($w, $e, \$HPVALUE{$name});
399         });
400     &set_widget_hint ($cb, $$hash{$key}[DESC]);
401     &set_widget_sens ($cb, $$hash{$key}[CMVER]);
402     $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
403     #
404     return $hbox;
405 }
406
407 sub new_text_box_for_int {
408     my ($hash, $key) = @_;
409     my $name = $$hash{$key}[NAME];
410     my $label = $$hash{$key}[LABEL];
411     my @type = split (/,/, $$hash{$key}[TYPE]);
412     push (@type, 0), push (@type, 10000) unless ($#type > 0); 
413     #
414     my $hbox = Gtk2::HBox->new (FALSE, 5);
415     my $glabel = Gtk2::Label->new ($label);
416     my $pagei = int (($type[2] - $type[1]) / 10);
417     my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
418     $gentry->set_numeric (TRUE);
419     $gentry->set_value ($HPVALUE{$name});
420     $$hash{$key}[GUI] = $gentry;
421     $gentry->signal_connect('value-changed' => sub {
422             my ($w, $e) = @_;
423             &handle_int_value($w, $e, \$HPVALUE{$name});
424         });
425     &set_widget_hint ($gentry, $$hash{$key}[DESC]);
426     &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
427     $glabel->set_sensitive ($gentry->sensitive);
428     $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
429     $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
430     #
431     return $hbox;
432 }
433
434 sub new_text_box_for_nchar {
435     my ($hash, $key) = @_;
436     my $name = $$hash{$key}[NAME];
437     my $label = $$hash{$key}[LABEL];
438     my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen
439     my $hbox = Gtk2::HBox->new (FALSE, 5);
440     my $glabel = Gtk2::Label->new ($label);
441     my $gentry = Gtk2::Entry->new ();
442     $gentry->set_max_length($type[2]) if defined ($type[2]);
443     $gentry->set_width_chars(int ($type[2]) + 2) if defined ($type[2]);
444     $gentry->set_text ($HPVALUE{$name});
445     $$hash{$key}[GUI] = $gentry;
446     $gentry->signal_connect('key-release-event' => sub {
447             my ($w, $e) = @_;
448             &handle_nchar_value($w, $e, \$HPVALUE{$name}, $type[1]);
449         });
450     &set_widget_hint ($gentry, $$hash{$key}[DESC]);
451     &set_widget_sens ($gentry, $$hash{$key}[CMVER]);
452     $glabel->set_sensitive ($gentry->sensitive);
453     $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
454     $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
455     #
456     return $hbox;
457 }
458
459 sub new_color_button_for {
460     my ($hash, $key) = @_;
461     my $name = $$hash{$key}[NAME];
462     my $label = $$hash{$key}[LABEL];
463     #
464     my $col = &gdk_color_from_str ($HPVALUE{$name});
465     my $hbox = Gtk2::HBox->new (FALSE, 5);
466     my $glabel = Gtk2::Label->new ($label);
467     my $button = Gtk2::ColorButton->new_with_color ($col);
468     $$hash{$key}[GUI] = $button;
469     $button->set_title ($label);
470     $button->set_relief ('none');
471     $button->signal_connect ('color-set' => sub {
472             my ($w, $e) = @_;
473             &handle_color_value($w, $e, \$HPVALUE{$name}); 
474         });
475     &set_widget_hint ($button, $$hash{$key}[DESC]);
476     &set_widget_sens ($button, $$hash{$key}[CMVER]);
477     $glabel->set_sensitive ($button->sensitive);
478     $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
479     $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
480     #
481     return $hbox;
482 }
483
484 sub new_selection_box_for {
485     my ($hash, $key) = @_;
486     my $name = $$hash{$key}[NAME];
487     my $label = $$hash{$key}[LABEL];
488     #
489     my $hbox = Gtk2::HBox->new (FALSE, 5);
490     my $glabel = Gtk2::Label->new ($label);
491     my $combo = Gtk2::ComboBox->new_text;
492     $$hash{$key}[GUI] = $combo;
493     my @options = split (';', $$hash{$key}[TYPE]);
494     foreach my $opt (@options) {
495         my ($index, $textkey) = split ('=', $opt);
496         $combo->insert_text ($index, $xl::s{$textkey});
497     }
498     $combo->signal_connect ('changed' => sub {
499             my ($w, $e) = @_;
500             &handle_selection_value($w, $e, \$HPVALUE{$name});
501         });
502     $combo->set_active ($HPVALUE{$name});
503     &set_widget_hint ($combo, $$hash{$key}[DESC]);
504     &set_widget_sens ($combo, $$hash{$key}[CMVER]);
505     $glabel->set_sensitive ($combo->sensitive);
506     $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
507     $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
508     #
509     return $hbox;
510 }
511
512 # more graphic helpers
513
514 sub new_hbox_pack() {
515     my $hbox = Gtk2::HBox->new (FALSE, 5);
516     $hbox->set_border_width (PAGE_SPC);
517     foreach my $item (@_) {
518         $hbox->pack_start ($item, FALSE, FALSE, 0);
519     }
520     return $hbox;
521 }    
522
523 sub new_vbox_pack() {
524     my $vbox = Gtk2::VBox->new (FALSE, 5);
525     $vbox->set_border_width (PAGE_SPC);
526     foreach my $item (@_) {
527         $vbox->pack_start ($item, FALSE, FALSE, 0);
528     }
529     return $vbox;
530 }    
531
532 sub new_vbox_pack_compact() {
533     my $vbox = Gtk2::VBox->new (FALSE, 0);
534     $vbox->set_border_width (0);
535     foreach my $item (@_) {
536         $vbox->pack_start ($item, FALSE, FALSE, 0);
537     }
538     return $vbox;
539 }    
540
541 sub new_subpage_frame () {
542     my ($box, $title, $notpacked) = @_;
543     my $frame = Gtk2::Frame->new ($title);
544     $frame->add ($box);    
545     return &new_vbox_pack ($frame) unless defined ($notpacked);
546     return $frame;
547 }
548
549 # preference maps and corresponding page creation subs
550
551 %pr::oth = ( # other preferences
552     use_dlg => [ 
553         'addressbook_use_editaddress_dialog',
554         $xl::s{l_oth_use_dlg},
555         $xl::s{h_oth_use_dlg},
556         'bool',
557         '2.7.0',
558         '0',
559         undef,
560     ],
561     max_use => [
562         'cache_max_mem_usage',
563         $xl::s{l_oth_max_use},
564         $xl::s{h_oth_max_use},
565         'int,0,262144', # 0 Kb - 256 Mb
566         '0.0.0',
567         '4096',
568         undef,
569     ],
570     min_time => [
571         'cache_min_keep_time',
572         $xl::s{l_oth_min_time},
573         $xl::s{h_oth_min_time},
574         'int,0,120', # 0 minutes - 2 hours
575         '0.0.0',
576         '15',
577         undef,
578     ],
579     use_netm => [
580         'use_networkmanager',
581         $xl::s{l_oth_use_netm},
582         $xl::s{h_oth_use_netm},
583         'bool',
584         '3.3.1',
585         '1',
586         undef,
587     ],
588 );
589
590 sub new_other_page() {
591     return &new_vbox_pack (
592                &new_subpage_frame (
593                    &new_vbox_pack (
594                        &new_check_button_for(\%pr::oth, 'use_dlg')),
595                    $xl::s{ab_frame}, 'not-packed'),
596                &new_subpage_frame (
597                    &new_vbox_pack (
598                        &new_text_box_for_int(\%pr::oth, 'max_use'),
599                        &new_text_box_for_int(\%pr::oth, 'min_time')),
600                    $xl::s{mem_frame}, 'not-packed'),
601                &new_subpage_frame (
602                    &new_vbox_pack (
603                        &new_check_button_for(\%pr::oth, 'use_netm')),
604                    $xl::s{netm_frame}, 'not-packed')
605            );
606 }
607
608 %pr::gui = ( # gui bells and whistles
609     b_unread => [ 
610         'bold_unread',
611         $xl::s{l_gui_b_unread},
612         $xl::s{h_gui_b_unread},
613         'bool',
614         '0.0.0',
615         '1',
616         undef,
617     ],
618     no_markup => [
619         'compose_no_markup',
620         $xl::s{l_gui_no_markup},
621         $xl::s{h_gui_no_markup},
622         'bool',
623         '0.0.0',
624         '0',
625         undef,
626     ],
627     dot_lines => [
628         'enable_dotted_lines',
629         $xl::s{l_gui_dot_lines},
630         $xl::s{h_gui_dot_lines},
631         'bool',
632         '0.0.0',
633         '0',
634         undef,
635     ],
636     h_scroll => [
637         'enable_hscrollbar',
638         $xl::s{l_gui_h_scroll},
639         $xl::s{h_gui_h_scroll},
640         'bool',
641         '0.0.0',
642         '1',
643         undef,
644     ],
645     swp_from => [
646         'enable_swap_from',
647         $xl::s{l_gui_swp_from},
648         $xl::s{h_gui_swp_from},
649         'bool',
650         '0.0.0',
651         '0',
652         undef,
653     ],
654     v_scroll => [
655         'folderview_vscrollbar_policy',
656         $xl::s{l_gui_v_scroll},
657         $xl::s{h_gui_v_scroll},
658         '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
659         '0.0.0',
660         '0',
661         undef,
662     ],
663     from_show => [
664         'summary_from_show',
665         $xl::s{l_gui_from_show},
666         $xl::s{h_gui_from_show},
667         '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
668         '3.7.10',
669         '0',
670         undef,
671     ],
672     strip_off => [
673         'stripes_color_offset',
674         $xl::s{l_gui_strip_off},
675         $xl::s{h_gui_strip_off},
676         'int,0,40000', # no idea what this number means
677         '0.0.0',
678         '4000',
679         undef,
680     ],
681     cursor_v => [
682         'textview_cursor_visible',
683         $xl::s{l_gui_cursor_v},
684         $xl::s{h_gui_cursor_v},
685         'bool',
686         '0.0.0',
687         '0',
688         undef,
689     ],
690     toolbar_d => [
691         'toolbar_detachable',
692         $xl::s{l_gui_toolbar_d},
693         $xl::s{h_gui_toolbar_d},
694         'bool',
695         '0.0.0',
696         '0',
697         undef,
698     ],
699     strip_all => [
700         'use_stripes_everywhere',
701         $xl::s{l_gui_strip_all},
702         $xl::s{h_gui_strip_all},
703         'bool',
704         '0.0.0',
705         '1',
706         undef,
707     ],
708     strip_sum => [
709         'use_stripes_in_summaries',
710         $xl::s{l_gui_strip_sum},
711         $xl::s{h_gui_strip_sum},
712         'bool',
713         '0.0.0',
714         '1',
715         undef,
716     ],
717     two_linev => [
718         'two_line_vertical',
719         $xl::s{l_gui_two_line_v},
720         $xl::s{h_gui_two_line_v},
721         'bool',
722         '3.4.0.7',
723         '0',
724         undef,
725     ],
726     margin_co => [
727         'show_compose_margin',
728         $xl::s{l_gui_margin_co},
729         $xl::s{h_gui_margin_co},
730         'bool',
731         '3.7.6.7',
732         '0',
733         undef,
734     ],
735     mview_date => [
736         'msgview_date_format',
737         $xl::s{l_gui_mview_date},
738         $xl::s{h_gui_mview_date},
739         'bool',
740         '3.7.8.42',
741         '0',
742         undef,
743     ],
744     zero_char => [
745         'zero_replacement_char',
746         $xl::s{l_gui_zero_char},
747         $xl::s{h_gui_zero_char},
748         'char,1,1',
749         '2.8.1.77',
750         '0',
751         undef,
752     ],
753 );
754
755 sub new_gui_page() {
756     my $gf = Gtk2::VBox->new (FALSE, 5);
757     $gf->set_border_width (PAGE_SPC);
758
759     my $cb_dot_lines = &new_check_button_for (\%pr::gui, 'dot_lines'); 
760     my $cb_toolbar_d = &new_check_button_for (\%pr::gui, 'toolbar_d');
761     my $tb_zero_char = &new_text_box_for_nchar (\%pr::gui, 'zero_char');
762
763     $gf->pack_start (&new_subpage_frame (
764                          &new_vbox_pack (
765                              &new_check_button_for (\%pr::gui, 'strip_all'),
766                              &new_check_button_for (\%pr::gui, 'strip_sum'),
767                              &new_text_box_for_int (\%pr::gui, 'strip_off')),
768                          $xl::s{stripes_frame}, 'not-packed'),
769                      FALSE, FALSE, FRAME_SPC);
770     $gf->pack_start (&new_subpage_frame (
771                          &new_vbox_pack (
772                              &new_check_button_for (\%pr::gui, 'b_unread'),
773                              &new_check_button_for (\%pr::gui, 'swp_from'),
774                              &new_check_button_for (\%pr::gui, 'two_linev'),
775                              &new_selection_box_for (\%pr::gui, 'from_show')),
776                          $xl::s{mlist_frame}, 'not-packed'), 
777                      FALSE, FALSE, FRAME_SPC);
778     $gf->pack_start (&new_subpage_frame (
779                          &new_hbox_pack (
780                              &new_check_button_for (\%pr::gui, 'cursor_v'),
781                              &new_check_button_for (\%pr::gui, 'mview_date')),
782                          $xl::s{mview_frame}, 'not-packed'), 
783                      FALSE, FALSE, FRAME_SPC);
784     $gf->pack_start (&new_subpage_frame (
785                          &new_hbox_pack (
786                              &new_check_button_for (\%pr::gui, 'no_markup'),
787                              &new_check_button_for (\%pr::gui, 'margin_co')),
788                          $xl::s{compo_frame}, 'not-packed'), 
789                      FALSE, FALSE, FRAME_SPC);
790     $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
791     $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
792     $gf->pack_start (&new_subpage_frame (
793                          &new_vbox_pack (
794                              &new_check_button_for (\%pr::gui, 'h_scroll'),
795                              &new_selection_box_for (\%pr::gui, 'v_scroll')),
796                          $xl::s{sbar_frame}, 'not-packed'),
797                      FALSE, FALSE, FRAME_SPC);
798     $gf->pack_start ($tb_zero_char, FALSE, FALSE, 0);
799
800     return $gf;
801 }
802
803 %pr::beh = ( # tweak some behaviour
804     hover_t => [
805         'hover_timeout',
806         $xl::s{l_beh_hover_t},
807         $xl::s{h_beh_hover_t},
808         'int,100,3000', # 0.1 seconds - 3 seconds
809         '0.0.0',
810         '500',
811         undef,
812     ],
813     dangerous => [
814         'live_dangerously',
815         $xl::s{l_beh_dangerous},
816         $xl::s{h_beh_dangerous},
817         'bool',
818         '0.0.0',
819         '0',
820         undef,
821     ],
822     flowed => [
823         'respect_flowed_format',
824         $xl::s{l_beh_flowed},
825         $xl::s{h_beh_flowed},
826         'bool',
827         '0.0.0',
828         '0',
829         undef,
830     ],
831     parts_rw => [
832         'save_parts_readwrite',
833         $xl::s{l_beh_parts_rw},
834         $xl::s{h_beh_parts_rw},
835         'bool',
836         '0.0.0',
837         '0',
838         undef,
839     ],
840     skip_ssl => [
841         'skip_ssl_cert_check',
842         $xl::s{l_beh_skip_ssl},
843         $xl::s{h_beh_skip_ssl},
844         'bool',
845         '0.0.0',
846         '0',
847         undef,
848     ],
849     up_step => [
850         'statusbar_update_step',
851         $xl::s{l_beh_up_step},
852         $xl::s{h_beh_up_step},
853         'int,1,200', # 1 item - 200 items
854         '0.0.0',
855         '10',
856         undef,
857     ],
858     thread_a => [
859         'thread_by_subject_max_age',
860         $xl::s{l_beh_thread_a},
861         $xl::s{h_beh_thread_a},
862         'int,1,30', # 1 day - 30 days
863         '0.0.0',
864         '10',
865         undef,
866     ],
867     unsafe_ssl => [
868         'unsafe_ssl_certs',
869         $xl::s{l_beh_unsafe_ssl},
870         $xl::s{h_beh_unsafe_ssl},
871         'bool',
872         '0.0.0',
873         '0',
874         undef,
875     ],
876     use_utf8 => [
877         'utf8_instead_of_locale_for_broken_mail',
878         $xl::s{l_beh_use_utf8},
879         $xl::s{h_beh_use_utf8},
880         'bool',
881         '0.0.0',
882         '0',
883         undef,
884     ],
885     warn_dnd => [
886         'warn_dnd',
887         $xl::s{l_beh_warn_dnd},
888         $xl::s{h_beh_warn_dnd},
889         'bool',
890         '0.0.0',
891         '1',
892         undef,
893     ],
894     out_ascii => [
895         'outgoing_fallback_to_ascii',
896         $xl::s{l_beh_out_ascii},
897         $xl::s{h_beh_out_ascii},
898         'bool',
899         '3.4.0.37',
900         '1',
901         undef,
902     ],
903     pp_unsel => [
904         'primary_paste_unselects',
905         $xl::s{l_beh_pp_unsel},
906         $xl::s{h_beh_pp_unsel},
907         'bool',
908         '3.6.1.35',
909         '0',
910         undef,
911     ],
912     inline_at => [
913         'show_inline_attachments',
914         $xl::s{l_beh_inline_at},
915         $xl::s{h_beh_inline_at},
916         'bool',
917         '3.7.8.48',
918         '1',
919         undef,
920     ],
921 );
922
923 sub new_behaviour_page() {
924     my $bf = Gtk2::VBox->new (FALSE, 5);
925     $bf->set_border_width (PAGE_SPC);
926
927     my $tb_up_step = &new_text_box_for_int (\%pr::beh, 'up_step');
928     my $tb_thread_a = &new_text_box_for_int (\%pr::beh, 'thread_a');
929
930     $bf->pack_start (&new_subpage_frame (
931                          &new_vbox_pack (
932                              &new_text_box_for_int (\%pr::beh, 'hover_t'),
933                              &new_check_button_for (\%pr::beh, 'warn_dnd')),
934                          $xl::s{dnd_frame}, 'not-packed'), 
935                      FALSE, FALSE, FRAME_SPC);
936     $bf->pack_start (&new_subpage_frame (
937                          &new_hbox_pack (
938                              &new_check_button_for (\%pr::beh, 'skip_ssl'),
939                              &new_check_button_for (\%pr::beh, 'unsafe_ssl')),
940                          $xl::s{ssl_frame}, 'not-packed'),
941                      FALSE, FALSE, FRAME_SPC);
942     $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
943     $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
944     $bf->pack_start (&new_subpage_frame (
945                          &new_vbox_pack (
946                              &new_check_button_for (\%pr::beh, 'flowed'),
947                              &new_check_button_for (\%pr::beh, 'parts_rw'),
948                              &new_check_button_for (\%pr::beh, 'use_utf8'),
949                              &new_check_button_for (\%pr::beh, 'dangerous'),
950                              &new_check_button_for (\%pr::beh, 'out_ascii'),
951                              &new_check_button_for (\%pr::beh, 'pp_unsel'),
952                              &new_check_button_for (\%pr::beh, 'inline_at')),
953                          $xl::s{msgs_frame}, 'not-packed'),
954                      FALSE, FALSE, FRAME_SPC);
955
956     return $bf;
957 }
958
959 %pr::col = ( # a variety of colours
960     emphasis => [
961         'emphasis_color',
962         $xl::s{l_col_emphasis},
963         $xl::s{h_col_emphasis},
964         'color',
965         '0.0.0',
966         '#0000cf',
967         undef,
968     ],
969     log_err => [
970         'log_error_color',
971         $xl::s{l_col_log_err},
972         $xl::s{h_col_log_err},
973         'color',
974         '0.0.0',
975         '#af0000',
976         undef,
977     ],
978     log_in => [
979         'log_in_color',
980         $xl::s{l_col_log_in},
981         $xl::s{h_col_log_in},
982         'color',
983         '0.0.0',
984         '#000000',
985         undef,
986     ],
987     log_msg => [
988         'log_msg_color',
989         $xl::s{l_col_log_msg},
990         $xl::s{h_col_log_msg},
991         'color',
992         '0.0.0',
993         '#00af00',
994         undef,
995     ],
996     log_out => [
997         'log_out_color',
998         $xl::s{l_col_log_out},
999         $xl::s{h_col_log_out},
1000         'color',
1001         '0.0.0',
1002         '#0000ef',
1003         undef,
1004     ],
1005     log_warn => [
1006         'log_warn_color',
1007         $xl::s{l_col_log_warn},
1008         $xl::s{h_col_log_warn},
1009         'color',
1010         '0.0.0',
1011         '#af0000',
1012         undef,
1013     ],
1014 );
1015
1016 sub new_colours_page() {
1017     return &new_vbox_pack (
1018                &new_subpage_frame (
1019                    &new_vbox_pack (
1020                        &new_color_button_for (\%pr::col, 'emphasis')),
1021                    $xl::s{msgview_frame}, 'not-packed'),
1022                &new_subpage_frame (
1023                    &new_vbox_pack (
1024                        &new_color_button_for (\%pr::col, 'log_err'),
1025                        &new_color_button_for (\%pr::col, 'log_in'),
1026                        &new_color_button_for (\%pr::col, 'log_msg'),
1027                        &new_color_button_for (\%pr::col, 'log_out'),
1028                        &new_color_button_for (\%pr::col, 'log_warn')),
1029                    $xl::s{log_frame}, 'not-packed')
1030            );
1031 }
1032
1033 %pr::win = ( # tweak window positions and/or sizes
1034     main_x => [
1035         'mainwin_x',
1036         $xl::s{l_win_x},
1037         $xl::s{h_win_x},
1038         'int,0,3000', # 0 pixels - 3000 pixels
1039         '0.0.0',
1040         '16',
1041         undef,
1042     ],
1043     main_y => [
1044         'mainwin_y',
1045         $xl::s{l_win_y},
1046         $xl::s{h_win_y},
1047         'int,0,3000', # 0 pixels - 3000 pixels
1048         '0.0.0',
1049         '16',
1050         undef,
1051     ],
1052     main_w => [
1053         'mainwin_width',
1054         $xl::s{l_win_w},
1055         $xl::s{h_win_w},
1056         'int,0,3000', # 0 pixels - 3000 pixels
1057         '0.0.0',
1058         '779',
1059         undef,
1060     ],
1061     main_h => [
1062         'mainwin_height',
1063         $xl::s{l_win_h},
1064         $xl::s{h_win_h},
1065         'int,0,3000', # 0 pixels - 3000 pixels
1066         '0.0.0',
1067         '568',
1068         undef,
1069     ],
1070     main_mx => [
1071         'mainwin_maximised',
1072         $xl::s{l_win_main_mx},
1073         $xl::s{h_win_main_mx},
1074         'bool',
1075         '0.0.0',
1076         '0',
1077         undef,
1078     ],
1079     main_fs => [
1080         'mainwin_fullscreen',
1081         $xl::s{l_win_main_fs},
1082         $xl::s{h_win_main_fs},
1083         'bool',
1084         '0.0.0',
1085         '0',
1086         undef,
1087     ],
1088     msgs_x => [
1089         'main_messagewin_x',
1090         $xl::s{l_win_x},
1091         $xl::s{h_win_x},
1092         'int,0,3000', # 0 pixels - 3000 pixels
1093         '0.0.0',
1094         '256',
1095         undef,
1096     ],
1097     msgs_y => [
1098         'main_messagewin_y',
1099         $xl::s{l_win_y},
1100         $xl::s{h_win_y},
1101         'int,0,3000', # 0 pixels - 3000 pixels
1102         '0.0.0',
1103         '210',
1104         undef,
1105     ],
1106     msgs_w => [
1107         'messagewin_width',
1108         $xl::s{l_win_w},
1109         $xl::s{h_win_w},
1110         'int,0,3000', # 0 pixels - 3000 pixels
1111         '0.0.0',
1112         '600',
1113         undef,
1114     ],
1115     msgs_h => [
1116         'messagewin_height',
1117         $xl::s{l_win_h},
1118         $xl::s{h_win_h},
1119         'int,0,3000', # 0 pixels - 3000 pixels
1120         '0.0.0',
1121         '540',
1122         undef,
1123     ],
1124     send_w => [
1125         'sendwin_width',
1126         $xl::s{l_win_w},
1127         $xl::s{h_win_w},
1128         'int,0,3000', # 0 pixels - 3000 pixels
1129         '0.0.0',
1130         '460',
1131         undef,
1132     ],
1133     send_h => [
1134         'sendwin_height',
1135         $xl::s{l_win_h},
1136         $xl::s{h_win_h},
1137         'int,0,3000', # 0 pixels - 3000 pixels
1138         '0.0.0',
1139         '-1',
1140         undef,
1141     ],
1142     recv_w => [
1143         'receivewin_width',
1144         $xl::s{l_win_w},
1145         $xl::s{h_win_w},
1146         'int,0,3000', # 0 pixels - 3000 pixels
1147         '0.0.0',
1148         '460',
1149         undef,
1150     ],
1151     recv_h => [
1152         'receivewin_height',
1153         $xl::s{l_win_h},
1154         $xl::s{h_win_h},
1155         'int,0,3000', # 0 pixels - 3000 pixels
1156         '0.0.0',
1157         '-1',
1158         undef,
1159     ],
1160     fold_x => [
1161         'folderwin_x',
1162         $xl::s{l_win_x},
1163         $xl::s{h_win_x},
1164         'int,0,3000', # 0 pixels - 3000 pixels
1165         '0.0.0',
1166         '16',
1167         undef,
1168     ],
1169     fold_y => [
1170         'folderwin_y',
1171         $xl::s{l_win_y},
1172         $xl::s{h_win_y},
1173         'int,0,3000', # 0 pixels - 3000 pixels
1174         '0.0.0',
1175         '16',
1176         undef,
1177     ],
1178     fold_w => [
1179         'folderitemwin_width',
1180         $xl::s{l_win_w},
1181         $xl::s{h_win_w},
1182         'int,0,3000', # 0 pixels - 3000 pixels
1183         '0.0.0',
1184         '500',
1185         undef,
1186     ],
1187     fold_h => [
1188         'folderitemwin_height',
1189         $xl::s{l_win_h},
1190         $xl::s{h_win_h},
1191         'int,0,3000', # 0 pixels - 3000 pixels
1192         '0.0.0',
1193         '-1',
1194         undef,
1195     ],
1196     fsel_w => [
1197         'folderselwin_width',
1198         $xl::s{l_win_w},
1199         $xl::s{h_win_w},
1200         'int,0,3000', # 0 pixels - 3000 pixels
1201         '0.0.0',
1202         '300',
1203         undef,
1204     ],
1205     fsel_h => [
1206         'folderselwin_height',
1207         $xl::s{l_win_h},
1208         $xl::s{h_win_h},
1209         'int,0,3000', # 0 pixels - 3000 pixels
1210         '0.0.0',
1211         '-1',
1212         undef,
1213     ],
1214     sour_w => [
1215         'sourcewin_width',
1216         $xl::s{l_win_w},
1217         $xl::s{h_win_w},
1218         'int,0,3000', # 0 pixels - 3000 pixels
1219         '0.0.0',
1220         '600',
1221         undef,
1222     ],
1223     sour_h => [
1224         'sourcewin_height',
1225         $xl::s{l_win_h},
1226         $xl::s{h_win_h},
1227         'int,0,3000', # 0 pixels - 3000 pixels
1228         '0.0.0',
1229         '500',
1230         undef,
1231     ],
1232     addr_w => [
1233         'addressbookwin_width',
1234         $xl::s{l_win_w},
1235         $xl::s{h_win_w},
1236         'int,0,3000', # 0 pixels - 3000 pixels
1237         '0.0.0',
1238         '520',
1239         undef,
1240     ],
1241     addr_h => [
1242         'addressbookwin_height',
1243         $xl::s{l_win_h},
1244         $xl::s{h_win_h},
1245         'int,0,3000', # 0 pixels - 3000 pixels
1246         '0.0.0',
1247         '-1',
1248         undef,
1249     ],
1250     adep_w => [
1251         'addressbookeditpersonwin_width',
1252         $xl::s{l_win_w},
1253         $xl::s{h_win_w},
1254         'int,0,3000', # 0 pixels - 3000 pixels
1255         '0.0.0',
1256         '640',
1257         undef,
1258     ],
1259     adep_h => [
1260         'addressbookeditpersonwin_height',
1261         $xl::s{l_win_h},
1262         $xl::s{h_win_h},
1263         'int,0,3000', # 0 pixels - 3000 pixels
1264         '0.0.0',
1265         '320',
1266         undef,
1267     ],
1268     adeg_w => [
1269         'addressbookeditgroupwin_width',
1270         $xl::s{l_win_w},
1271         $xl::s{h_win_w},
1272         'int,0,3000', # 0 pixels - 3000 pixels
1273         '0.0.0',
1274         '580',
1275         undef,
1276     ],
1277     adeg_h => [
1278         'addressbookeditgroupwin_height',
1279         $xl::s{l_win_h},
1280         $xl::s{h_win_h},
1281         'int,0,3000', # 0 pixels - 3000 pixels
1282         '0.0.0',
1283         '340',
1284         undef,
1285     ],
1286     adda_w => [
1287         'addressaddwin_width',
1288         $xl::s{l_win_w},
1289         $xl::s{h_win_w},
1290         'int,0,3000', # 0 pixels - 3000 pixels
1291         '0.0.0',
1292         '300',
1293         undef,
1294     ],
1295     adda_h => [
1296         'addressaddwin_height',
1297         $xl::s{l_win_h},
1298         $xl::s{h_win_h},
1299         'int,0,3000', # 0 pixels - 3000 pixels
1300         '0.0.0',
1301         '-1',
1302         undef,
1303     ],
1304     addf_w => [
1305         'addressbook_folderselwin_width',
1306         $xl::s{l_win_w},
1307         $xl::s{h_win_w},
1308         'int,0,3000', # 0 pixels - 3000 pixels
1309         '0.0.0',
1310         '300',
1311         undef,
1312     ],
1313     addf_h => [
1314         'addressbook_folderselwin_height',
1315         $xl::s{l_win_h},
1316         $xl::s{h_win_h},
1317         'int,0,3000', # 0 pixels - 3000 pixels
1318         '0.0.0',
1319         '-1',
1320         undef,
1321     ],
1322     acce_w => [
1323         'editaccountwin_width',
1324         $xl::s{l_win_w},
1325         $xl::s{h_win_w},
1326         'int,0,3000', # 0 pixels - 3000 pixels
1327         '0.0.0',
1328         '500',
1329         undef,
1330     ],
1331     acce_h => [
1332         'editaccountwin_height',
1333         $xl::s{l_win_h},
1334         $xl::s{h_win_h},
1335         'int,0,3000', # 0 pixels - 3000 pixels
1336         '0.0.0',
1337         '-1',
1338         undef,
1339     ],
1340     acco_w => [
1341         'accountswin_width',
1342         $xl::s{l_win_w},
1343         $xl::s{h_win_w},
1344         'int,0,3000', # 0 pixels - 3000 pixels
1345         '0.0.0',
1346         '500',
1347         undef,
1348     ],
1349     acco_h => [
1350         'accountswin_height',
1351         $xl::s{l_win_h},
1352         $xl::s{h_win_h},
1353         'int,0,3000', # 0 pixels - 3000 pixels
1354         '0.0.0',
1355         '-1',
1356         undef,
1357     ],
1358     filt_w => [
1359         'filteringwin_width',
1360         $xl::s{l_win_w},
1361         $xl::s{h_win_w},
1362         'int,0,3000', # 0 pixels - 3000 pixels
1363         '0.0.0',
1364         '500',
1365         undef,
1366     ],
1367     filt_h => [
1368         'filteringwin_height',
1369         $xl::s{l_win_h},
1370         $xl::s{h_win_h},
1371         'int,0,3000', # 0 pixels - 3000 pixels
1372         '0.0.0',
1373         '-1',
1374         undef,
1375     ],
1376     fila_w => [
1377         'filteringactionwin_width',
1378         $xl::s{l_win_w},
1379         $xl::s{h_win_w},
1380         'int,0,3000', # 0 pixels - 3000 pixels
1381         '0.0.0',
1382         '490',
1383         undef,
1384     ],
1385     fila_h => [
1386         'filteringactionwin_height',
1387         $xl::s{l_win_h},
1388         $xl::s{h_win_h},
1389         'int,0,3000', # 0 pixels - 3000 pixels
1390         '0.0.0',
1391         '-1',
1392         undef,
1393     ],
1394     fild_w => [
1395         'filtering_debugwin_width',
1396         $xl::s{l_win_w},
1397         $xl::s{h_win_w},
1398         'int,0,3000', # 0 pixels - 3000 pixels
1399         '0.0.0',
1400         '600',
1401         undef,
1402     ],
1403     fild_h => [
1404         'filtering_debugwin_height',
1405         $xl::s{l_win_h},
1406         $xl::s{h_win_h},
1407         'int,0,3000', # 0 pixels - 3000 pixels
1408         '0.0.0',
1409         '-1',
1410         undef,
1411     ],
1412     matc_w => [
1413         'matcherwin_width',
1414         $xl::s{l_win_w},
1415         $xl::s{h_win_w},
1416         'int,0,3000', # 0 pixels - 3000 pixels
1417         '0.0.0',
1418         '520',
1419         undef,
1420     ],
1421     matc_h => [
1422         'matcherwin_height',
1423         $xl::s{l_win_h},
1424         $xl::s{h_win_h},
1425         'int,0,3000', # 0 pixels - 3000 pixels
1426         '0.0.0',
1427         '-1',
1428         undef,
1429     ],
1430     pref_w => [
1431         'prefswin_width',
1432         $xl::s{l_win_w},
1433         $xl::s{h_win_w},
1434         'int,0,3000', # 0 pixels - 3000 pixels
1435         '0.0.0',
1436         '600',
1437         undef,
1438     ],
1439     pref_h => [
1440         'prefswin_height',
1441         $xl::s{l_win_h},
1442         $xl::s{h_win_h},
1443         'int,0,3000', # 0 pixels - 3000 pixels
1444         '0.0.0',
1445         '-1',
1446         undef,
1447     ],
1448     temp_w => [
1449         'templateswin_width',
1450         $xl::s{l_win_w},
1451         $xl::s{h_win_w},
1452         'int,0,3000', # 0 pixels - 3000 pixels
1453         '0.0.0',
1454         '480',
1455         undef,
1456     ],
1457     temp_h => [
1458         'templateswin_height',
1459         $xl::s{l_win_h},
1460         $xl::s{h_win_h},
1461         'int,0,3000', # 0 pixels - 3000 pixels
1462         '0.0.0',
1463         '-1',
1464         undef,
1465     ],
1466     acti_w => [
1467         'actionswin_width',
1468         $xl::s{l_win_w},
1469         $xl::s{h_win_w},
1470         'int,0,3000', # 0 pixels - 3000 pixels
1471         '0.0.0',
1472         '486',
1473         undef,
1474     ],
1475     acti_h => [
1476         'actionswin_height',
1477         $xl::s{l_win_h},
1478         $xl::s{h_win_h},
1479         'int,0,3000', # 0 pixels - 3000 pixels
1480         '0.0.0',
1481         '-1',
1482         undef,
1483     ],
1484     tags_w => [
1485         'tagswin_width',
1486         $xl::s{l_win_w},
1487         $xl::s{h_win_w},
1488         'int,0,3000', # 0 pixels - 3000 pixels
1489         '0.0.0',
1490         '486',
1491         undef,
1492     ],
1493     tags_h => [
1494         'tagswin_height',
1495         $xl::s{l_win_h},
1496         $xl::s{h_win_h},
1497         'int,0,3000', # 0 pixels - 3000 pixels
1498         '0.0.0',
1499         '-1',
1500         undef,
1501     ],
1502     plug_w => [
1503         'pluginswin_width',
1504         $xl::s{l_win_w},
1505         $xl::s{h_win_w},
1506         'int,0,3000', # 0 pixels - 3000 pixels
1507         '0.0.0',
1508         '-1',
1509         undef,
1510     ],
1511     plug_h => [
1512         'pluginswin_height',
1513         $xl::s{l_win_h},
1514         $xl::s{h_win_h},
1515         'int,0,3000', # 0 pixels - 3000 pixels
1516         '0.0.0',
1517         '-1',
1518         undef,
1519     ],
1520     logw_w => [
1521         'logwin_width',
1522         $xl::s{l_win_w},
1523         $xl::s{h_win_w},
1524         'int,0,3000', # 0 pixels - 3000 pixels
1525         '0.0.0',
1526         '520',
1527         undef,
1528     ],
1529     logw_h => [
1530         'logwin_height',
1531         $xl::s{l_win_h},
1532         $xl::s{h_win_h},
1533         'int,0,3000', # 0 pixels - 3000 pixels
1534         '0.0.0',
1535         '-1',
1536         undef,
1537     ],
1538     prin_w => [
1539         'print_previewwin_width',
1540         $xl::s{l_win_w},
1541         $xl::s{h_win_w},
1542         'int,0,3000', # 0 pixels - 3000 pixels
1543         '0.0.0',
1544         '600',
1545         undef,
1546     ],
1547     prin_h => [
1548         'print_previewwin_height',
1549         $xl::s{l_win_h},
1550         $xl::s{h_win_h},
1551         'int,0,3000', # 0 pixels - 3000 pixels
1552         '0.0.0',
1553         '-1',
1554         undef,
1555     ],
1556 );
1557
1558 sub new_winpos_subpage_main() {
1559     return &new_subpage_frame (
1560                &new_vbox_pack_compact (
1561                    &new_vbox_pack (
1562                        &new_text_box_for_int (\%pr::win, 'main_x'), 
1563                        &new_text_box_for_int (\%pr::win, 'main_y')), 
1564                    &new_hbox_pack (
1565                        &new_text_box_for_int (\%pr::win, 'main_w'), 
1566                        &new_text_box_for_int (\%pr::win, 'main_h')), 
1567                    &new_vbox_pack (
1568                        &new_check_button_for (\%pr::win, 'main_fs'), 
1569                        &new_check_button_for (\%pr::win, 'main_mx'))),
1570                _('Main window')
1571            );
1572 }
1573
1574 sub new_winpos_subpage_msgs() {
1575     return &new_subpage_frame (
1576                &new_vbox_pack_compact (
1577                    &new_vbox_pack (
1578                        &new_text_box_for_int (\%pr::win, 'msgs_x'),
1579                        &new_text_box_for_int (\%pr::win, 'msgs_y')),
1580                    &new_hbox_pack (
1581                        &new_text_box_for_int (\%pr::win, 'msgs_w'),
1582                        &new_text_box_for_int (\%pr::win, 'msgs_h'))),
1583                _('Message window')
1584            );
1585 }
1586
1587 sub new_winpos_subpage_sendrecv() {
1588     return &new_vbox_pack (
1589                &new_subpage_frame (
1590                    &new_hbox_pack (
1591                        &new_text_box_for_int (\%pr::win, 'send_w'),
1592                        &new_text_box_for_int (\%pr::win, 'send_h')),
1593                    _('Send window'), 'not-packed'),
1594                &new_subpage_frame (
1595                    &new_hbox_pack (
1596                        &new_text_box_for_int (\%pr::win, 'recv_w'),
1597                        &new_text_box_for_int (\%pr::win, 'recv_h')),
1598                    _('Receive window'), 'not-packed')
1599            );
1600 }
1601
1602 sub new_winpos_subpage_fold() {
1603     return &new_vbox_pack (
1604                &new_subpage_frame (
1605                    &new_vbox_pack_compact (
1606                        &new_vbox_pack (
1607                             &new_text_box_for_int (\%pr::win, 'fold_x'), 
1608                             &new_text_box_for_int (\%pr::win, 'fold_y')), 
1609                        &new_hbox_pack (
1610                            &new_text_box_for_int (\%pr::win, 'fold_w'), 
1611                            &new_text_box_for_int (\%pr::win, 'fold_h'))),
1612                    _('Folder window'), 'not-packed'),
1613                &new_subpage_frame (
1614                    &new_hbox_pack (
1615                        &new_text_box_for_int (\%pr::win, 'fsel_w'),
1616                        &new_text_box_for_int (\%pr::win, 'fsel_h')),
1617                    _('Folder selection window'), 'not-packed')
1618            );
1619 }
1620
1621 sub new_winpos_subpage_addrbook() {
1622     return &new_vbox_pack (
1623                 &new_subpage_frame (
1624                      &new_hbox_pack (
1625                           &new_text_box_for_int (\%pr::win, 'addr_w'),
1626                           &new_text_box_for_int (\%pr::win, 'addr_h')),
1627                      _('Addressbook main window'), 'not-packed'),
1628                 &new_subpage_frame (
1629                      &new_hbox_pack (
1630                           &new_text_box_for_int (\%pr::win, 'adep_w'),
1631                           &new_text_box_for_int (\%pr::win, 'adep_h')),
1632                      _('Edit person window'), 'not-packed'),
1633                 &new_subpage_frame (
1634                      &new_hbox_pack (
1635                           &new_text_box_for_int (\%pr::win, 'adeg_w'),
1636                           &new_text_box_for_int (\%pr::win, 'adeg_h')),
1637                      _('Edit group window'), 'not-packed'),
1638                 &new_subpage_frame (
1639                      &new_hbox_pack (
1640                           &new_text_box_for_int (\%pr::win, 'adda_w'),
1641                           &new_text_box_for_int (\%pr::win, 'adda_h')),
1642                      _('Add address window'), 'not-packed'),
1643                 &new_subpage_frame (
1644                      &new_hbox_pack (
1645                           &new_text_box_for_int (\%pr::win, 'addf_w'),
1646                           &new_text_box_for_int (\%pr::win, 'addf_h')),
1647                      _('Folder select window'), 'not-packed')
1648            );
1649 }
1650
1651 sub new_winpos_subpage_accounts() {
1652     return &new_vbox_pack (
1653                 &new_subpage_frame (
1654                      &new_hbox_pack (
1655                           &new_text_box_for_int (\%pr::win, 'acco_w'),
1656                           &new_text_box_for_int (\%pr::win, 'acco_h')),
1657                      _('Accounts window'), 'not-packed'),
1658                 &new_subpage_frame (
1659                      &new_hbox_pack (
1660                           &new_text_box_for_int (\%pr::win, 'acce_w'),
1661                           &new_text_box_for_int (\%pr::win, 'acce_h')),
1662                      _('Edit account window'), 'not-packed')
1663            );
1664 }
1665
1666 sub new_winpos_subpage_filtering() {
1667     return &new_vbox_pack (
1668                 &new_subpage_frame (
1669                      &new_hbox_pack (
1670                           &new_text_box_for_int (\%pr::win, 'filt_w'),
1671                           &new_text_box_for_int (\%pr::win, 'filt_h')),
1672                      _('Filtering window'), 'not-packed'),
1673                 &new_subpage_frame (
1674                      &new_hbox_pack (
1675                           &new_text_box_for_int (\%pr::win, 'fila_w'),
1676                           &new_text_box_for_int (\%pr::win, 'fila_h')),
1677                      _('Filtering actions window'), 'not-packed'),
1678                 &new_subpage_frame (
1679                      &new_hbox_pack (
1680                           &new_text_box_for_int (\%pr::win, 'fild_w'),
1681                           &new_text_box_for_int (\%pr::win, 'fild_h')),
1682                      _('Filtering debug window'), 'not-packed'),
1683                 &new_subpage_frame (
1684                      &new_hbox_pack (
1685                           &new_text_box_for_int (\%pr::win, 'matc_w'),
1686                           &new_text_box_for_int (\%pr::win, 'matc_h')),
1687                      _('Matcher window'), 'not-packed')
1688            );
1689 }
1690
1691 sub new_winpos_subpage_prefs() {
1692     return &new_vbox_pack (
1693                 &new_subpage_frame (
1694                      &new_hbox_pack (
1695                           &new_text_box_for_int (\%pr::win, 'pref_w'),
1696                           &new_text_box_for_int (\%pr::win, 'pref_h')),
1697                      _('Preferences window'), 'not-packed'),
1698                 &new_subpage_frame (
1699                      &new_hbox_pack (
1700                           &new_text_box_for_int (\%pr::win, 'temp_w'),
1701                           &new_text_box_for_int (\%pr::win, 'temp_h')),
1702                      _('Templates window'), 'not-packed'),
1703                 &new_subpage_frame (
1704                      &new_hbox_pack (
1705                           &new_text_box_for_int (\%pr::win, 'acti_w'),
1706                           &new_text_box_for_int (\%pr::win, 'acti_h')),
1707                      _('Actions window'), 'not-packed'),
1708                 &new_subpage_frame (
1709                      &new_hbox_pack (
1710                           &new_text_box_for_int (\%pr::win, 'tags_w'),
1711                           &new_text_box_for_int (\%pr::win, 'tags_h')),
1712                      _('Tags window'), 'not-packed'),
1713                 &new_subpage_frame (
1714                      &new_hbox_pack (
1715                           &new_text_box_for_int (\%pr::win, 'plug_w'),
1716                           &new_text_box_for_int (\%pr::win, 'plug_h')),
1717                      _('Plugins window'), 'not-packed')
1718            );
1719 }
1720
1721 sub new_winpos_subpage_misc() {
1722     return &new_vbox_pack (
1723                 &new_subpage_frame (
1724                      &new_hbox_pack (
1725                           &new_text_box_for_int (\%pr::win, 'logw_w'),
1726                           &new_text_box_for_int (\%pr::win, 'logw_h')),
1727                      _('Log window'), 'not-packed'),
1728                 &new_subpage_frame (
1729                      &new_hbox_pack (
1730                           &new_text_box_for_int (\%pr::win, 'prin_w'),
1731                           &new_text_box_for_int (\%pr::win, 'prin_h')),
1732                      _('Print preview window'), 'not-packed'),
1733                 &new_subpage_frame (
1734                      &new_hbox_pack (
1735                           &new_text_box_for_int (\%pr::win, 'sour_w'),
1736                           &new_text_box_for_int (\%pr::win, 'sour_h')),
1737                      _('View source window'), 'not-packed')
1738            );
1739 }
1740
1741 sub new_winpos_page() {
1742     my $winbook = Gtk2::Notebook->new;
1743     $winbook->set_tab_pos ('right');
1744     $winbook->append_page (&new_winpos_subpage_main, _('Main'));
1745     $winbook->append_page (&new_winpos_subpage_msgs, _('Message'));
1746     $winbook->append_page (&new_winpos_subpage_sendrecv, _('Send/Receive'));
1747     $winbook->append_page (&new_winpos_subpage_fold, _('Folder'));
1748     $winbook->append_page (&new_winpos_subpage_addrbook, _('Addressbook'));
1749     $winbook->append_page (&new_winpos_subpage_accounts, _('Accounts'));
1750     $winbook->append_page (&new_winpos_subpage_filtering, _('Filtering'));
1751     $winbook->append_page (&new_winpos_subpage_prefs, _('Preferences'));
1752     $winbook->append_page (&new_winpos_subpage_misc, _('Other'));
1753     return $winbook;
1754 }
1755
1756 # version info
1757 sub print_version() {
1758     print $xl::s{about_title} . "\n";
1759     print $xl::s{about_version} . " $VERSION\n";
1760     print "Perl-GLib " . $Glib::VERSION;
1761     # version info stuff appeared in 1.040
1762     if ($Glib::VERSION >= 1.040) {
1763         print _(", built for ") . join(".", Glib->GET_VERSION_INFO) 
1764               . _(", running with ") . join(".", &Glib::major_version, 
1765               &Glib::minor_version, &Glib::micro_version);
1766     }
1767     print "\n";
1768     print "Perl-GTK2 " . $Gtk2::VERSION;
1769     if ($Gtk2::VERSION >= 1.040) {
1770         print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1771               . _(", running with ") . join(".", &Gtk2::major_version, 
1772               &Gtk2::minor_version, &Gtk2::micro_version);
1773     }
1774     print "\n";
1775     my $clawsver = ($CLAWSV eq "") ? 
1776                 _("was not found!") : 
1777                 (_("returned version ") . $CLAWSV);
1778     print "Claws Mail " . $clawsver . "\n";
1779 }
1780
1781 # the command line help
1782 sub print_help() {
1783     my $line = '-' x length ($xl::s{about_title}) . "\n";
1784     print $line;
1785     print $xl::s{about_title} . "\n";
1786     print $line;
1787     print _("Syntax:\n");
1788     print _("    clawsker [options]\n");
1789     print _("Options:\n");
1790     print _("    --help                         Prints this help screen.\n");
1791     print _("    --version                      Prints version infos.\n");
1792     print _("    --verbose                      More messages on standard output.\n");
1793     print _("    --alternate-config-dir <dir>   Uses <dir> as Claws Mail config dir.\n");
1794     print _("    --clawsrc <file>               Uses <file> as full resource name.\n");
1795 }
1796
1797 # handle errors which don't allow to run
1798 sub command_line_fatal() {
1799     my $reason = shift;
1800     my $emsg = $xl::s{e_error} . $reason;
1801     error_dialog ($emsg);
1802     log_message ("$emsg", 'die');
1803 }
1804
1805 # parse the command line
1806 sub parse_command_line() {
1807     $CLAWSV = &get_claws_version;
1808     my $arg = 0;
1809     while (defined($ARGV[$arg])) {
1810         for ($ARGV[$arg]) {
1811             /--help/ && do { 
1812                 &print_help; 
1813                 return FALSE;
1814             };
1815             /--version/ && do { 
1816                 &print_version; 
1817                 return FALSE;
1818             };
1819             /--verbose/ && do {
1820                 $VERBOSE = TRUE;
1821                 last;
1822             };
1823             /--use-claws-version/ && do {
1824                 ++$arg;
1825                 &command_line_fatal ("required version")
1826                     unless defined($ARGV[$arg]);
1827                 &command_line_fatal ("required a dotted numeric value")
1828                     unless ($ARGV[$arg] =~ /[\d\.]+/);
1829                 $CLAWSV = $ARGV[$arg];
1830                 last;
1831             };
1832             /--alternate-config-dir/ && do {
1833                 ++$arg;
1834                 &command_line_fatal ($xl::s{e_requireddir})
1835                     unless defined($ARGV[$arg]);
1836                 &command_line_fatal ($xl::s{e_notadir})
1837                     unless -d $ARGV[$arg];
1838                 $CONFIGDIR = $ARGV[$arg];
1839                 $CONFIGDIR .= "/" 
1840                     unless ($CONFIGDIR =~ /.*\/$/);
1841                 $ALTCONFIGDIR = TRUE;
1842                 last;
1843             };
1844             /--clawsrc/ && do {
1845                 ++$arg;
1846                 &command_line_fatal($xl::s{e_requiredfile}) 
1847                     unless defined($ARGV[$arg]);
1848                 &command_line_fatal($xl::s{e_notafile}) 
1849                     unless -f $ARGV[$arg];
1850                 &set_rc_filename ($ARGV[$arg]);
1851                 last;
1852             };
1853             /.*/ && &command_line_fatal (
1854                 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1855         }
1856         ++$arg;
1857     }
1858     # eveything continues...
1859     return TRUE;
1860 }
1861
1862 # update the hidden preferences status from loaded values
1863 sub init_hidden_preferences() {
1864     foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1865         foreach my $key (keys %$hash) { 
1866             $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1867         }
1868     }
1869     return TRUE;
1870 }
1871
1872 # load current status from disc
1873 sub load_preferences() {
1874     my $rc = &get_rc_filename;
1875     &log_message ("Loading preferences from $rc\n");
1876     return FALSE unless &check_rc_file ($rc);
1877     return FALSE unless &check_claws_not_running;
1878     open (RCF, "<$rc");
1879     while (<RCF>) {
1880         chomp;
1881         if (/^([8a-z_]+)=(.*)$/) {
1882             $PREFS{$1} = "$2";
1883         }
1884     }
1885     close (RCF);
1886     return TRUE;
1887 }
1888
1889 # save current preferences to disc
1890 sub save_preferences() {
1891     my $rc = &get_rc_filename;
1892     &log_message ("Saving preferences to $rc\n");
1893     return FALSE unless &check_rc_file ($rc);
1894     return FALSE unless &check_claws_not_running;
1895     my $rcbak = "$rc.backup";
1896     rename ($rc, $rcbak);
1897     open (RCF, ">$rc");
1898     open (RCB, "<$rcbak");
1899     while (<RCB>) {
1900         chomp;
1901         if (/^([8a-z_]+)=(.*)$/) {
1902             if (defined($HPVALUE{$1})) {
1903                 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1904             }
1905             else {
1906                 print RCF $_ . "\n";
1907             }
1908         }
1909         else {
1910             print RCF $_ . "\n";
1911         }
1912     }
1913     close (RCB);
1914     close (RCF);
1915     return TRUE;
1916 }
1917
1918 # create notebook
1919 sub new_notebook() {
1920     my $nb = Gtk2::Notebook->new;
1921     # 
1922     $nb->append_page (&new_behaviour_page, $xl::s{tab_behaviour});
1923     $nb->append_page (&new_colours_page, $xl::s{tab_colours});
1924     $nb->append_page (&new_gui_page, $xl::s{tab_gui});
1925     $nb->append_page (&new_other_page, $xl::s{tab_other});
1926     $nb->append_page (&new_winpos_page, $xl::s{tab_winpos});
1927
1928     return $nb;
1929 }
1930
1931 # create an about dialog
1932 sub new_about_dialog() {
1933     my ($parent) = @_;
1934     my $title = $xl::s{about_title};
1935     my $lic = $xl::s{about_license};
1936     my $vers = $xl::s{about_version} . " $VERSION";
1937     my $license = 
1938 "This program is free software: you can redistribute it and/or modify
1939 it under the terms of the GNU General Public License as published by
1940 the Free Software Foundation, either version 3 of the License, or
1941 (at your option) any later version.
1942
1943 This program is distributed in the hope that it will be useful,
1944 but WITHOUT ANY WARRANTY; without even the implied warranty of
1945 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1946 GNU General Public License for more details.
1947
1948 You should have received a copy of the GNU General Public License
1949 along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.";
1950     my $year = "2007-2012";
1951     my $holder = "Ricardo Mones &lt;ricardo\@mones.org&gt;";
1952     my $url = "http://www.claws-mail.org/clawsker.php";
1953
1954     my $dialog = Gtk2::MessageDialog->new_with_markup ($parent, 
1955                     [qw/modal destroy-with-parent/], 
1956                     'info', 'close', 
1957                     "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
1958                     . "<span size=\"large\">$vers</span>\n\n"
1959                     . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
1960                     . "<span>Copyright $year by $holder</span>\n\n"
1961                     . "<span size=\"large\">$lic</span>\n\n"
1962                     . "<span size=\"small\">$license</span>");
1963     $dialog->set_title ($xl::s{about});
1964     #
1965     return $dialog;
1966 }
1967
1968 # create buttons box
1969 sub new_button_box() {
1970     my ($parent, $adlg) = @_;
1971     my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
1972     my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
1973     my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
1974     # disable button until is really implemented
1975     # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
1976     my $hbox = Gtk2::HBox->new (FALSE, 5);
1977     # signal handlers 
1978     $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
1979     $b_apply->signal_connect (clicked => sub { &save_preferences ($parent) });
1980     # $b_undo->signal_connect (clicked => sub { &undo_current_changes });
1981     $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
1982     # package them
1983     $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
1984     $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
1985     # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
1986     $hbox->pack_start ($b_about, FALSE, FALSE, 0);
1987     #
1988     return $hbox;
1989 }
1990
1991 # initialise
1992 $main_window = Gtk2::Window->new ('toplevel');
1993 exit unless &parse_command_line;
1994 exit unless &load_preferences;
1995 exit unless &init_hidden_preferences;
1996 # create main GUI
1997 my $box = Gtk2::VBox->new (FALSE, 5);
1998 $box->set_border_width(3);
1999 my $about = &new_about_dialog;
2000 $box->pack_start (&new_notebook, FALSE, FALSE, 0);
2001 $box->pack_end (&new_button_box ($main_window, $about), FALSE, FALSE, 0);
2002 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
2003 $main_window->set_title ($xl::s{win_title});
2004 $main_window->add ($box);
2005 $main_window->show_all;
2006 Gtk2->main;
2007