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