10 Clawsker - A Claws Mail Tweaker
18 Clawsker is an applet to edit the so called Claws Mail hidden preferences.
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.
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
32 Shows a brief help screen.
35 Show information about program, Claws Mail and Perl-GTK versions.
38 Tells more on the standard output.
40 --alternate-config-dir <dir>
41 Uses <dir> as Claws Mail configuration dir.
44 Uses <file> as Claws Mail resource configuration file. This sets
45 the full file name overriding any previous setting.
47 Multiple options are allowed, although only the last one has effect. Weird
48 option specifications may produce weird results (but otherwise correct).
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.
58 Ricardo Mones E<lt>ricardo@mones.orgE<gt>
62 Copyright (c) 2007-2009 by Ricardo Mones Lastra
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.
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.
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>.
81 use Glib qw(TRUE FALSE);
83 use POSIX qw(setlocale);
86 my $NAME = 'clawsker';
87 my $PREFIX = '@PREFIX@';
88 my $LIBDIR = '@LIBDIR@';
89 my $VERSION = '@VERSION@';
92 my $main_window = undef;
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));
100 my $SHOWHINTS = FALSE;
101 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
106 my $xla = gettext ($str);
107 if (scalar(keys(%par)) > 0) {
108 foreach my $key (keys %par) {
109 $xla =~ s/\{$key\}/$par{$key}/g;
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:'),
123 tab_colours => _('Colours'),
124 tab_behaviour => _('Behaviour'),
126 tab_other => _('Other'),
127 tab_winpos => _('Windows'),
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'),
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.'),
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.'),
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.'),
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.'),
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.'),
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.'),
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.'),
239 # all preferences read by load_preferences
241 # values of all preferences handled by clawsker
243 # default config dir and file name
244 my $ALTCONFIGDIR = FALSE;
245 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
246 my $CONFIGRC = 'clawsrc';
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
257 # constants for GUI spacing
258 use constant HBOX_SPC => 5;
259 use constant FRAME_SPC => 2;
260 use constant PAGE_SPC => 5;
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');
272 while (($idx <= $#refvers)
273 and (int ($version[$idx]) == int ($refvers[$idx]))) {
276 return TRUE if (($idx > $#refvers)
277 or (int ($version[$idx]) >= int ($refvers[$idx])));
281 sub get_claws_version() {
286 foreach my $bin (@cmbin) {
291 return "" unless ($_); # not installed
294 my @fver = split (/ /);
295 die "Invalid version string" unless ($fver[2] eq "version");
296 my @ver = split (/\./, $fver[3]);
299 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
308 # data handlers and auxiliar functions
310 sub handle_bool_value {
311 my ($widget, $event, $dataref) = @_;
312 $$dataref = ($widget->get_active ())? '1': '0';
315 sub handle_int_value {
316 my ($widget, $event, $dataref) = @_;
317 $_ = $widget->get_text ();
322 $widget->set_text ($_);
325 $widget->set_text ($$dataref);
329 sub handle_string_value {
330 my ($widget, $event, $dataref) = @_;
331 $$dataref = $widget->get_text ();
334 sub gdk_color_from_str {
336 my ($rr, $gg, $bb) = (0, 0 ,0);
338 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
343 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
347 sub str_from_gdk_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);
356 sub handle_color_value {
357 my ($widget, $event, $dataref) = @_;
358 my $newcol = $widget->get_color;
359 $$dataref = &str_from_gdk_color ($newcol);
362 sub handle_selection_value {
363 my ($widget, $event, $dataref) = @_;
364 $$dataref = $widget->get_active;
367 sub get_rc_filename {
368 return $CONFIGDIR . $CONFIGRC;
371 sub set_rc_filename {
373 my @parts = split ('/', $fullname);
374 $CONFIGRC = $parts[$#parts];
375 $parts[$#parts] = '';
376 $CONFIGDIR = join ('/', @parts);
380 my ($mesg, $fatal) = @_;
381 if (defined($fatal) && $fatal eq 'die') {
382 die "$NAME: $mesg\n";
385 print "$NAME: $mesg\n";
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'));
398 sub check_claws_not_running() {
399 my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
400 $socket .= "claws-mail-$<";
402 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
404 error_dialog ($emsg);
411 sub check_rc_file() {
413 (defined($rcfile) && -f $rcfile) or do {
414 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
416 error_dialog ($emsg);
423 sub set_widget_hint() {
425 my ($wdgt, $hint) = @_;
426 $wdgt->set_tooltip_text ($hint);
427 $wdgt->set_has_tooltip (TRUE);
431 sub set_widget_sens() {
432 my ($wdgt, $minver) = @_;
433 $wdgt->set_sensitive (&version_greater_or_equal ($CLAWSV, $minver));
436 # graphic element creation
438 sub new_check_button_for {
439 my ($hash, $key) = @_;
440 my $name = $$hash{$key}[NAME];
441 my $label = $$hash{$key}[LABEL];
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');
449 $cb->signal_connect (clicked => sub {
451 &handle_bool_value($w, $e, \$HPVALUE{$name});
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);
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);
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
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 {
478 &handle_int_value($w, $e, \$HPVALUE{$name});
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);
489 sub new_color_button_for {
490 my ($hash, $key) = @_;
491 my $name = $$hash{$key}[NAME];
492 my $label = $$hash{$key}[LABEL];
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 {
503 &handle_color_value($w, $e, \$HPVALUE{$name});
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);
514 sub new_selection_box_for {
515 my ($hash, $key) = @_;
516 my $name = $$hash{$key}[NAME];
517 my $label = $$hash{$key}[LABEL];
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});
528 $combo->signal_connect ('changed' => sub {
530 &handle_selection_value($w, $e, \$HPVALUE{$name});
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);
542 # more graphic helpers
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);
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);
562 sub new_subpage_frame () {
563 my ($box, $title, $notpacked) = @_;
564 my $frame = Gtk2::Frame->new ($title);
566 return &new_vbox_pack ($frame) unless defined ($notpacked);
570 # preference maps and corresponding page creation subs
572 %pr::oth = ( # other preferences
574 'addressbook_use_editaddress_dialog',
575 $xl::s{l_oth_use_dlg},
576 $xl::s{h_oth_use_dlg},
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
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
601 'use_networkmanager',
602 $xl::s{l_oth_use_netm},
603 $xl::s{h_oth_use_netm},
611 sub new_other_page() {
612 my $of = Gtk2::VBox->new (FALSE, 5);
613 $of->set_border_width (PAGE_SPC);
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);
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);
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);
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);
645 %pr::gui = ( # gui bells and whistles
648 $xl::s{l_gui_b_unread},
649 $xl::s{h_gui_b_unread},
657 $xl::s{l_gui_no_markup},
658 $xl::s{h_gui_no_markup},
665 'enable_dotted_lines',
666 $xl::s{l_gui_dot_lines},
667 $xl::s{h_gui_dot_lines},
675 $xl::s{l_gui_h_scroll},
676 $xl::s{h_gui_h_scroll},
684 $xl::s{l_gui_swp_from},
685 $xl::s{h_gui_swp_from},
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',
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
710 'textview_cursor_visible',
711 $xl::s{l_gui_cursor_v},
712 $xl::s{h_gui_cursor_v},
719 'toolbar_detachable',
720 $xl::s{l_gui_toolbar_d},
721 $xl::s{h_gui_toolbar_d},
728 'use_stripes_everywhere',
729 $xl::s{l_gui_strip_all},
730 $xl::s{h_gui_strip_all},
737 'use_stripes_in_summaries',
738 $xl::s{l_gui_strip_sum},
739 $xl::s{h_gui_strip_sum},
747 $xl::s{l_gui_two_line_v},
748 $xl::s{h_gui_two_line_v},
757 my $gf = Gtk2::VBox->new (FALSE, 5);
758 $gf->set_border_width (PAGE_SPC);
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);
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);
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);
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');
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);
807 %pr::beh = ( # tweak some behaviour
810 $xl::s{l_beh_hover_t},
811 $xl::s{h_beh_hover_t},
812 'int,100,3000', # 0.1 seconds - 3 seconds
819 $xl::s{l_beh_dangerous},
820 $xl::s{h_beh_dangerous},
827 'respect_flowed_format',
828 $xl::s{l_beh_flowed},
829 $xl::s{h_beh_flowed},
836 'save_parts_readwrite',
837 $xl::s{l_beh_parts_rw},
838 $xl::s{h_beh_parts_rw},
845 'skip_ssl_cert_check',
846 $xl::s{l_beh_skip_ssl},
847 $xl::s{h_beh_skip_ssl},
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
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
873 $xl::s{l_beh_unsafe_ssl},
874 $xl::s{h_beh_unsafe_ssl},
881 'utf8_instead_of_locale_for_broken_mail',
882 $xl::s{l_beh_use_utf8},
883 $xl::s{h_beh_use_utf8},
891 $xl::s{l_beh_warn_dnd},
892 $xl::s{h_beh_warn_dnd},
899 'outgoing_fallback_to_ascii',
900 $xl::s{l_beh_out_ascii},
901 $xl::s{h_beh_out_ascii},
908 'primary_paste_unselects',
909 $xl::s{l_beh_pp_unsel},
910 $xl::s{h_beh_pp_unsel},
918 sub new_behaviour_page() {
919 my $bf = Gtk2::VBox->new (FALSE, 5);
920 $bf->set_border_width (PAGE_SPC);
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);
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);
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');
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);
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);
969 %pr::col = ( # a variety of colours
972 $xl::s{l_col_emphasis},
973 $xl::s{h_col_emphasis},
981 $xl::s{l_col_log_err},
982 $xl::s{h_col_log_err},
990 $xl::s{l_col_log_in},
991 $xl::s{h_col_log_in},
999 $xl::s{l_col_log_msg},
1000 $xl::s{h_col_log_msg},
1008 $xl::s{l_col_log_out},
1009 $xl::s{h_col_log_out},
1017 $xl::s{l_col_log_warn},
1018 $xl::s{h_col_log_warn},
1026 sub new_colours_page() {
1027 my $cf = Gtk2::VBox->new (FALSE, 5);
1028 $cf->set_border_width (PAGE_SPC);
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);
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);
1052 $cf->pack_start ($msgview_frame, FALSE, FALSE, 0);
1053 $cf->pack_start ($log_frame, FALSE, FALSE, 0);
1058 %pr::win = ( # tweak window positions and/or sizes
1063 'int,0,3000', # 0 pixels - 3000 pixels
1072 'int,0,3000', # 0 pixels - 3000 pixels
1081 'int,0,3000', # 0 pixels - 3000 pixels
1090 'int,0,3000', # 0 pixels - 3000 pixels
1096 'mainwin_maximised',
1097 $xl::s{l_win_main_mx},
1098 $xl::s{h_win_main_mx},
1105 'mainwin_fullscreen',
1106 $xl::s{l_win_main_fs},
1107 $xl::s{h_win_main_fs},
1114 'main_messagewin_x',
1117 'int,0,3000', # 0 pixels - 3000 pixels
1123 'main_messagewin_y',
1126 'int,0,3000', # 0 pixels - 3000 pixels
1135 'int,0,3000', # 0 pixels - 3000 pixels
1141 'messagewin_height',
1144 'int,0,3000', # 0 pixels - 3000 pixels
1153 'int,0,3000', # 0 pixels - 3000 pixels
1162 'int,0,3000', # 0 pixels - 3000 pixels
1171 'int,0,3000', # 0 pixels - 3000 pixels
1177 'receivewin_height',
1180 'int,0,3000', # 0 pixels - 3000 pixels
1189 'int,0,3000', # 0 pixels - 3000 pixels
1198 'int,0,3000', # 0 pixels - 3000 pixels
1204 'folderitemwin_width',
1207 'int,0,3000', # 0 pixels - 3000 pixels
1213 'folderitemwin_height',
1216 'int,0,3000', # 0 pixels - 3000 pixels
1222 'folderselwin_width',
1225 'int,0,3000', # 0 pixels - 3000 pixels
1231 'folderselwin_height',
1234 'int,0,3000', # 0 pixels - 3000 pixels
1243 'int,0,3000', # 0 pixels - 3000 pixels
1252 'int,0,3000', # 0 pixels - 3000 pixels
1258 'addressbookwin_width',
1261 'int,0,3000', # 0 pixels - 3000 pixels
1267 'addressbookwin_height',
1270 'int,0,3000', # 0 pixels - 3000 pixels
1276 'addressbookeditpersonwin_width',
1279 'int,0,3000', # 0 pixels - 3000 pixels
1285 'addressbookeditpersonwin_height',
1288 'int,0,3000', # 0 pixels - 3000 pixels
1294 'addressbookeditgroupwin_width',
1297 'int,0,3000', # 0 pixels - 3000 pixels
1303 'addressbookeditgroupwin_height',
1306 'int,0,3000', # 0 pixels - 3000 pixels
1312 'addressaddwin_width',
1315 'int,0,3000', # 0 pixels - 3000 pixels
1321 'addressaddwin_height',
1324 'int,0,3000', # 0 pixels - 3000 pixels
1330 'addressbook_folderselwin_width',
1333 'int,0,3000', # 0 pixels - 3000 pixels
1339 'addressbook_folderselwin_height',
1342 'int,0,3000', # 0 pixels - 3000 pixels
1348 'editaccountwin_width',
1351 'int,0,3000', # 0 pixels - 3000 pixels
1357 'editaccountwin_height',
1360 'int,0,3000', # 0 pixels - 3000 pixels
1366 'accountswin_width',
1369 'int,0,3000', # 0 pixels - 3000 pixels
1375 'accountswin_height',
1378 'int,0,3000', # 0 pixels - 3000 pixels
1384 'filteringwin_width',
1387 'int,0,3000', # 0 pixels - 3000 pixels
1393 'filteringwin_height',
1396 'int,0,3000', # 0 pixels - 3000 pixels
1402 'filteringactionwin_width',
1405 'int,0,3000', # 0 pixels - 3000 pixels
1411 'filteringactionwin_height',
1414 'int,0,3000', # 0 pixels - 3000 pixels
1420 'filtering_debugwin_width',
1423 'int,0,3000', # 0 pixels - 3000 pixels
1429 'filtering_debugwin_height',
1432 'int,0,3000', # 0 pixels - 3000 pixels
1441 'int,0,3000', # 0 pixels - 3000 pixels
1447 'matcherwin_height',
1450 'int,0,3000', # 0 pixels - 3000 pixels
1459 'int,0,3000', # 0 pixels - 3000 pixels
1468 'int,0,3000', # 0 pixels - 3000 pixels
1474 'templateswin_width',
1477 'int,0,3000', # 0 pixels - 3000 pixels
1483 'templateswin_height',
1486 'int,0,3000', # 0 pixels - 3000 pixels
1495 'int,0,3000', # 0 pixels - 3000 pixels
1501 'actionswin_height',
1504 'int,0,3000', # 0 pixels - 3000 pixels
1513 'int,0,3000', # 0 pixels - 3000 pixels
1522 'int,0,3000', # 0 pixels - 3000 pixels
1531 'int,0,3000', # 0 pixels - 3000 pixels
1537 'pluginswin_height',
1540 'int,0,3000', # 0 pixels - 3000 pixels
1549 'int,0,3000', # 0 pixels - 3000 pixels
1558 'int,0,3000', # 0 pixels - 3000 pixels
1564 'print_previewwin_width',
1567 'int,0,3000', # 0 pixels - 3000 pixels
1573 'print_previewwin_height',
1576 'int,0,3000', # 0 pixels - 3000 pixels
1583 sub new_winpos_subpage_main() {
1584 return &new_subpage_frame (
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'),
1591 &new_check_button_for (\%pr::win, 'main_fs'),
1592 &new_check_button_for (\%pr::win, 'main_mx'))),
1597 sub new_winpos_subpage_msgs() {
1598 return &new_subpage_frame (
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')),
1608 sub new_winpos_subpage_sendrecv() {
1609 return &new_vbox_pack (
1610 &new_subpage_frame (
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 (
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')
1625 sub new_winpos_subpage_fold() {
1626 return &new_vbox_pack (
1627 &new_subpage_frame (
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 (
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')
1642 sub new_winpos_subpage_sour() {
1643 return &new_subpage_frame (
1645 &new_text_box_for_int (\%pr::win, 'sour_w'),
1646 &new_text_box_for_int (\%pr::win, 'sour_h')),
1647 _('View source window')
1651 sub new_winpos_subpage_addrbook() {
1652 return &new_vbox_pack (
1653 &new_subpage_frame (
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 (
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 (
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 (
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 (
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')
1686 sub new_winpos_subpage_accounts() {
1687 return &new_vbox_pack (
1688 &new_subpage_frame (
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 (
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')
1703 sub new_winpos_subpage_filtering() {
1704 return &new_vbox_pack (
1705 &new_subpage_frame (
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 (
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 (
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 (
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')
1732 sub new_winpos_subpage_prefs() {
1733 return &new_vbox_pack (
1734 &new_subpage_frame (
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 (
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 (
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 (
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 (
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')
1767 sub new_winpos_subpage_misc() {
1768 return &new_vbox_pack (
1769 &new_subpage_frame (
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 (
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')
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'));
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);
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);
1819 my $clawsver = ($CLAWSV eq "") ?
1820 _("was not found!") :
1821 (_("returned version ") . $CLAWSV);
1822 print "Claws Mail " . $clawsver . "\n";
1825 # the command line help
1827 my $line = '-' x length ($xl::s{about_title}) . "\n";
1829 print $xl::s{about_title} . "\n";
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");
1841 # handle errors which don't allow to run
1842 sub command_line_fatal() {
1844 my $emsg = $xl::s{e_error} . $reason;
1845 error_dialog ($emsg);
1846 log_message ("$emsg", 'die');
1849 # parse the command line
1850 sub parse_command_line() {
1851 $CLAWSV = &get_claws_version;
1853 while (defined($ARGV[$arg])) {
1867 /--use-claws-version/ && do {
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];
1876 /--alternate-config-dir/ && do {
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];
1884 unless ($CONFIGDIR =~ /.*\/$/);
1885 $ALTCONFIGDIR = TRUE;
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]);
1897 /.*/ && &command_line_fatal (
1898 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1902 # eveything continues...
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]};
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;
1925 if (/^([8a-z_]+)=(.*)$/) {
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);
1942 open (RCB, "<$rcbak");
1945 if (/^([8a-z_]+)=(.*)$/) {
1946 if (defined($HPVALUE{$1})) {
1947 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1950 print RCF $_ . "\n";
1954 print RCF $_ . "\n";
1963 sub new_notebook() {
1964 my $nb = Gtk2::Notebook->new;
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});
1975 # create an about dialog
1976 sub new_about_dialog() {
1978 my $title = $xl::s{about_title};
1979 my $lic = $xl::s{about_license};
1980 my $vers = $xl::s{about_version} . " $VERSION";
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.
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.
1992 You should have received a copy of the GNU General Public License
1993 along with this program. If not, see <http://www.gnu.org/licenses/>.";
1994 my $year = "2007-2009";
1995 my $holder = "Ricardo Mones <ricardo\@mones.org>";
1997 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
1998 [qw/modal destroy-with-parent/],
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});
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);
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 });
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);
2034 $main_window = Gtk2::Window->new ('toplevel');
2035 exit unless &parse_command_line;
2036 exit unless &load_preferences;
2037 exit unless &init_hidden_preferences;
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;