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