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