3 # Clawsker :: A Claws Mail Tweaker
4 # Copyright 2007-2015 Ricardo Mones <ricardo@mones.org>
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # See COPYING file for license details.
12 # See AUTHORS file for a complete list of contributors.
15 binmode STDOUT, ":encoding(utf8)";
19 use Glib qw(TRUE FALSE);
21 use POSIX qw(setlocale);
24 use Digest::MD5 qw(md5_hex);
27 my $NAME = 'clawsker';
28 my $PREFIX = '@PREFIX@';
29 my $LIBDIR = '@LIBDIR@';
30 my $VERSION = '@VERSION@';
33 my $main_window = undef;
35 my $locale = (defined($ENV{LC_MESSAGES}) ? $ENV{LC_MESSAGES} : $ENV{LANG});
36 $locale = "C" unless defined($locale);
37 setlocale (LC_ALL, $locale);
38 bindtextdomain ($NAME, sprintf ('%s/share/locale', $PREFIX));
41 my $SHOWHINTS = FALSE;
42 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
47 my $xla = gettext ($str);
48 if (scalar(keys(%par)) > 0) {
49 foreach my $key (keys %par) {
50 $xla =~ s/\{$key\}/$par{$key}/g;
53 return decode_utf8($xla);
58 win_title => _('Claws Mail Hidden Preferences'),
59 about => _('About...'),
60 about_title => _('Clawsker :: A Claws Mail Tweaker'),
61 about_license => _('License:'),
62 about_version => _('Version:'),
64 tab_colours => _('Colours'),
65 tab_behaviour => _('Behaviour'),
67 tab_other => _('Other'),
68 tab_winpos => _('Windows'),
70 ab_frame => _('Addressbook'),
71 mem_frame => _('Memory'),
72 msgview_frame => _('Message View'),
73 log_frame => _('Log window'),
74 dnd_frame => _('Drag \'n\' drop'),
75 ssl_frame => _('Secure Sockets Layer'),
76 msgs_frame => _('Messages'),
77 swc_frame => _('Completion'),
78 stripes_frame => _('Coloured stripes'),
79 sbar_frame => _('Scroll bars'),
80 mlist_frame => _('Message List'),
81 mview_frame => _('Message View'),
82 compo_frame => _('Compose window'),
83 netm_frame => _('NetworkManager'),
84 diff_frame => _('Viewing patches'),
86 l_oth_use_dlg => _('Use detached address book edit dialogue'),
87 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.'),
88 l_oth_max_use => _('Maximum memory for message cache (kB)'),
89 h_oth_max_use => _('The maximum amount of memory to use to cache messages, in kilobytes.'),
90 l_oth_min_time => _('Minimun time for cache elements (minutes)'),
91 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.'),
92 l_oth_use_netm => _('Use NetworkManager'),
93 h_oth_use_netm => _('Use NetworkManager to switch offline automatically.'),
95 l_gui_b_unread => _('Show unread messages with bold font'),
96 h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
97 l_gui_no_markup => _('Don\'t use markup'),
98 h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
99 l_gui_dot_lines => _('Use dotted lines in tree view components'),
100 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.'),
101 l_gui_h_scroll => _('Enable horizontal scrollbar'),
102 h_gui_h_scroll => _('Enable the horizontal scrollbar in the Message List.'),
103 l_gui_swp_from => _('Display To column instead From column in Sent folder'),
104 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.'),
105 l_gui_v_scroll => _('Folder List scrollbar behaviour'),
106 h_gui_v_scroll => _('Specify the policy of vertical scrollbar of Folder List: show always, automatic or hide always.'),
107 l_gui_v_scroll_show => _('Show always'),
108 l_gui_v_scroll_auto => _('Automatic'),
109 l_gui_v_scroll_hide => _('Hide always'),
110 l_gui_from_show => _('From column displays'),
111 h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both'),
112 l_gui_from_show_name => _('Name only'),
113 l_gui_from_show_addr => _('Address only'),
114 l_gui_from_show_both => _('Both name and address'),
115 l_gui_strip_off => _('Coloured lines contrast'),
116 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.'),
117 l_gui_cursor_v => _('Show cursor'),
118 h_gui_cursor_v => _('Display the cursor in the Message View.'),
119 l_gui_toolbar_d => _('Detachable toolbars'),
120 h_gui_toolbar_d => _('Show handles in the toolbars.'),
121 l_gui_strip_all => _('Use stripes in all tree view components'),
122 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
123 l_gui_strip_sum => _('Use stripes in Folder List and Message List'),
124 h_gui_strip_sum => _('Enable alternately coloured lines in Message List and Folder List.'),
125 l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
126 h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
127 l_gui_margin_co => _('Show margin'),
128 h_gui_margin_co => _('Shows a small margin in the Compose View.'),
129 l_gui_mview_date => _('Don\'t display localized date'),
130 h_gui_mview_date => _('Toggles localization of date format in Message View'),
131 l_gui_zero_char => _('Zero replacement character'),
132 h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List'),
133 l_gui_type_any => _('Editable headers'),
134 h_gui_type_any => _('Allows to manually type any value in Compose Window header entries or just select from the available choices in the associated dropdown list'),
136 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
137 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.'),
138 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
139 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
140 l_beh_flowed => _('Respect format=flowed in messages'),
141 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.'),
142 l_beh_parts_rw => _('Allow writable temporary files'),
143 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
144 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
145 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
146 l_beh_up_step => _('Progress bar update step (items)'),
147 h_beh_up_step => _('Update stepping in progress bars.'),
148 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
149 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
150 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
151 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
152 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
153 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
154 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
155 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
156 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
157 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
158 l_beh_pp_unsel => _('Primary paste unselects selection'),
159 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
160 l_beh_inline_at => _('Show inline attachments'),
161 h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
162 l_beh_addr_swc => _('Address search in compose window matches any'),
163 h_beh_addr_swc => _('On Tab-key completion, address text will match any part of the string or only the from the start'),
164 l_beh_fold_swc => _('Folder search in folder selector matches any'),
165 h_beh_fold_swc => _('On folder name completion text will match any part of the string or only from the start'),
167 l_col_emphasis => _('X-Mailer header'),
168 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
169 l_col_log_err => _('Error messages'),
170 h_col_log_err => _('Colour for error messages in log window.'),
171 l_col_log_in => _('Server messages'),
172 h_col_log_in => _('Colour for messages received from servers in log window.'),
173 l_col_log_msg => _('Standard messages'),
174 h_col_log_msg => _('Colour for messages in log window.'),
175 l_col_log_out => _('Client messages'),
176 h_col_log_out => _('Colour for messages sent to servers in log window.'),
177 l_col_log_warn => _('Warnings'),
178 h_col_log_warn => _('Colour for warning messages in log window.'),
180 l_col_diff_add => _('Added lines'),
181 h_col_diff_add => _('Colour for added lines in patches.'),
182 l_col_diff_del => _('Deleted lines'),
183 h_col_diff_del => _('Colour for deleted lines in patches.'),
184 l_col_diff_hunk => _('Hunk lines'),
185 h_col_diff_hunk => _('Color for hunk headers in patches.'),
187 l_win_x => _('X position'),
188 h_win_x => _('X coordinate for window\'s top-left corner.'),
189 l_win_y => _('Y position'),
190 h_win_y => _('Y coordinate for window\'s top-left corner.'),
191 l_win_w => _('Width'),
192 h_win_w => _('Window\'s width in pixels.'),
193 l_win_h => _('Height'),
194 h_win_h => _('Window\'s height in pixels.'),
196 l_win_main_mx => _('Maximized'),
197 h_win_main_mx => _('Changes window maximized status.'),
198 l_win_main_fs => _('Full-screen'),
199 h_win_main_fs => _('Changes full screen status.'),
201 e_error => _('Error: '),
202 e_noclawsrc => _('resource file for Claws Mail was not found.'),
203 e_running => _('seems Claws Mail is currently running, close it first.'),
206 # all preferences read by load_preferences
208 # values of all preferences handled by clawsker
210 # default config dir and file name
211 my $ALTCONFIGDIR = FALSE;
212 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
213 my $CONFIGRC = 'clawsrc';
215 # index constants for preference arrays
216 use constant NAME => 0; # the name on the rc file
217 use constant LABEL => 1; # the label on the GUI
218 use constant DESC => 2; # the description for the hint/help
219 use constant TYPE => 3; # data type: bool, int, float, string, color
220 use constant CMVER => 4; # lowest[,highest] Claws Mail version(s) the feature exists
221 use constant CMDEF => 5; # default value for the preference in Claws Mail
222 use constant GUI => 6; # GUI element
224 # constants for GUI spacing
225 use constant HBOX_SPC => 5;
226 use constant FRAME_SPC => 2;
227 use constant PAGE_SPC => 5;
231 sub version_greater_or_equal {
232 my ($version, $refvers) = @_;
233 my @version = split (/\./, $version);
234 my @refvers = split (/\./, $refvers);
235 while ($#version < $#refvers) {
236 push (@version, '0');
239 while (($idx <= $#refvers)
240 and (int ($version[$idx]) == int ($refvers[$idx]))) {
243 return TRUE if (($idx > $#refvers)
244 or (int ($version[$idx]) >= int ($refvers[$idx])));
248 sub get_claws_version {
253 foreach my $bin (@cmbin) {
258 return "" unless ($_); # not installed
261 my @fver = split (/ /);
262 die "Invalid version string" unless ($fver[2] eq "version");
263 my @ver = split (/\./, $fver[3]);
266 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
275 # data handlers and auxiliar functions
277 sub handle_bool_value {
278 my ($widget, $event, $dataref) = @_;
279 $$dataref = ($widget->get_active ())? '1': '0';
282 sub handle_int_value {
283 my ($widget, $event, $dataref) = @_;
284 $_ = $widget->get_text ();
289 $widget->set_text ($_);
292 $widget->set_text ($$dataref);
296 sub handle_string_value {
297 my ($widget, $event, $dataref) = @_;
298 $$dataref = $widget->get_text ();
301 sub handle_nchar_value {
302 my ($widget, $event, $dataref, $minlen) = @_;
303 $_ = substr ($widget->get_text (), 0, $minlen);
304 $widget->set_text ($_);
308 sub gdk_color_from_str {
310 my ($rr, $gg, $bb) = (0, 0 ,0);
312 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
317 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
321 sub str_from_gdk_color {
323 my $rr = $color->red / 256;
324 my $gg = $color->green / 256;
325 my $bb = $color->blue / 256;
326 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
330 sub handle_color_value {
331 my ($widget, $event, $dataref) = @_;
332 my $newcol = $widget->get_color;
333 $$dataref = str_from_gdk_color ($newcol);
336 sub handle_selection_value {
337 my ($widget, $event, $dataref) = @_;
338 $$dataref = $widget->get_active;
341 sub get_rc_filename {
342 return $CONFIGDIR . $CONFIGRC;
345 sub set_rc_filename {
347 my @parts = split ('/', $fullname);
348 $CONFIGRC = $parts[$#parts];
349 $parts[$#parts] = '';
350 $CONFIGDIR = join ('/', @parts);
354 my ($mesg, $fatal) = @_;
355 if (defined($fatal) && $fatal eq 'die') {
356 die "$NAME: $mesg\n";
359 print "$NAME: $mesg\n";
365 my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
366 my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
367 $errordlg->set_title (_('Clawsker error'));
372 sub claws_is_running {
373 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
375 error_dialog ($emsg);
379 sub check_claws_not_running {
380 my $tmpdir = (defined $ENV{TMPDIR})? $ENV{TMPDIR}: '/tmp';
381 $tmpdir = '/tmp' if ($tmpdir eq '');
382 my $socket = (not $ALTCONFIGDIR)? $tmpdir: $CONFIGDIR;
383 $socket .= "/claws-mail-$<";
384 -S $socket and return claws_is_running ();
386 my $lockdir = "$tmpdir/claws-mail-$<";
390 $socket = "$lockdir/" . md5_hex ($_);
391 -S $socket and return claws_is_running ();
398 (defined($rcfile) && -f $rcfile) or do {
399 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
401 error_dialog ($emsg);
407 sub set_widget_hint {
409 my ($wdgt, $hint) = @_;
410 $wdgt->set_tooltip_text ($hint);
411 $wdgt->set_has_tooltip (TRUE);
415 sub set_widget_sens {
416 my ($wdgt, $versions) = @_;
417 my @ver = split(/,/, $versions);
419 $wdgt->set_sensitive (
420 version_greater_or_equal ($CLAWSV, $ver[0])
421 and version_greater_or_equal ($ver[1], $CLAWSV)
424 $wdgt->set_sensitive (version_greater_or_equal ($CLAWSV, $ver[0]));
428 # graphic element creation
430 sub new_check_button_for {
431 my ($hash, $key) = @_;
432 my $name = $$hash{$key}[NAME];
433 my $label = $$hash{$key}[LABEL];
435 my $hbox = Gtk2::HBox->new (FALSE, 5);
436 my $cb = Gtk2::CheckButton->new ($label);
437 $$hash{$key}[GUI] = $cb;
438 if (defined ($HPVALUE{$name})) {
439 $cb->set_active ($HPVALUE{$name} eq '1');
441 $cb->signal_connect (clicked => sub {
443 handle_bool_value ($w, $e, \$HPVALUE{$name});
445 set_widget_hint ($cb, $$hash{$key}[DESC]);
446 set_widget_sens ($cb, $$hash{$key}[CMVER]);
447 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
452 sub new_text_box_for_int {
453 my ($hash, $key) = @_;
454 my $name = $$hash{$key}[NAME];
455 my $label = $$hash{$key}[LABEL];
456 my @type = split (/,/, $$hash{$key}[TYPE]);
457 push (@type, 0), push (@type, 10000) unless ($#type > 0);
459 my $hbox = Gtk2::HBox->new (FALSE, 5);
460 my $glabel = Gtk2::Label->new ($label);
461 my $pagei = int (($type[2] - $type[1]) / 10);
462 my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
463 $gentry->set_numeric (TRUE);
464 $gentry->set_value ($HPVALUE{$name});
465 $$hash{$key}[GUI] = $gentry;
466 $gentry->signal_connect('value-changed' => sub {
468 handle_int_value ($w, $e, \$HPVALUE{$name});
470 set_widget_hint ($gentry, $$hash{$key}[DESC]);
471 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
472 $glabel->set_sensitive ($gentry->sensitive);
473 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
474 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
479 sub new_text_box_for_nchar {
480 my ($hash, $key) = @_;
481 my $name = $$hash{$key}[NAME];
482 my $label = $$hash{$key}[LABEL];
483 my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen
484 my $hbox = Gtk2::HBox->new (FALSE, 5);
485 my $glabel = Gtk2::Label->new ($label);
486 my $gentry = Gtk2::Entry->new ();
487 $gentry->set_max_length($type[2]) if defined ($type[2]);
488 $gentry->set_width_chars(int ($type[2]) + 2) if defined ($type[2]);
489 $gentry->set_text ($HPVALUE{$name});
490 $$hash{$key}[GUI] = $gentry;
491 $gentry->signal_connect('key-release-event' => sub {
493 handle_nchar_value ($w, $e, \$HPVALUE{$name}, $type[1]);
495 set_widget_hint ($gentry, $$hash{$key}[DESC]);
496 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
497 $glabel->set_sensitive ($gentry->sensitive);
498 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
499 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
504 sub new_color_button_for {
505 my ($hash, $key) = @_;
506 my $name = $$hash{$key}[NAME];
507 my $label = $$hash{$key}[LABEL];
509 my $col = gdk_color_from_str ($HPVALUE{$name});
510 my $hbox = Gtk2::HBox->new (FALSE, 5);
511 my $glabel = Gtk2::Label->new ($label);
512 my $button = Gtk2::ColorButton->new_with_color ($col);
513 $$hash{$key}[GUI] = $button;
514 $button->set_title ($label);
515 $button->set_relief ('none');
516 $button->signal_connect ('color-set' => sub {
518 handle_color_value ($w, $e, \$HPVALUE{$name});
520 set_widget_hint ($button, $$hash{$key}[DESC]);
521 set_widget_sens ($button, $$hash{$key}[CMVER]);
522 $glabel->set_sensitive ($button->sensitive);
523 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
524 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
529 sub new_selection_box_for {
530 my ($hash, $key) = @_;
531 my $name = $$hash{$key}[NAME];
532 my $label = $$hash{$key}[LABEL];
534 my $hbox = Gtk2::HBox->new (FALSE, 5);
535 my $glabel = Gtk2::Label->new ($label);
536 my $combo = Gtk2::ComboBox->new_text;
537 $$hash{$key}[GUI] = $combo;
538 my @options = split (';', $$hash{$key}[TYPE]);
539 foreach my $opt (@options) {
540 my ($index, $textkey) = split ('=', $opt);
541 $combo->insert_text ($index, $xl::s{$textkey});
543 $combo->signal_connect ('changed' => sub {
545 handle_selection_value ($w, $e, \$HPVALUE{$name});
547 $combo->set_active ($HPVALUE{$name});
548 set_widget_hint ($combo, $$hash{$key}[DESC]);
549 set_widget_sens ($combo, $$hash{$key}[CMVER]);
550 $glabel->set_sensitive ($combo->sensitive);
551 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
552 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
557 # more graphic helpers
560 my $hbox = Gtk2::HBox->new (FALSE, 5);
561 $hbox->set_border_width (PAGE_SPC);
562 foreach my $item (@_) {
563 $hbox->pack_start ($item, FALSE, FALSE, 0);
569 my $vbox = Gtk2::VBox->new (FALSE, 5);
570 $vbox->set_border_width (PAGE_SPC);
571 foreach my $item (@_) {
572 $vbox->pack_start ($item, FALSE, FALSE, 0);
577 sub new_vbox_pack_compact {
578 my $vbox = Gtk2::VBox->new (FALSE, 0);
579 $vbox->set_border_width (0);
580 foreach my $item (@_) {
581 $vbox->pack_start ($item, FALSE, FALSE, 0);
586 sub new_subpage_frame {
587 my ($box, $title, $notpacked) = @_;
588 my $frame = Gtk2::Frame->new ($title);
590 return new_vbox_pack ($frame) unless defined ($notpacked);
594 # preference maps and corresponding page creation subs
596 %pr::oth = ( # other preferences
598 'addressbook_use_editaddress_dialog',
599 $xl::s{l_oth_use_dlg},
600 $xl::s{h_oth_use_dlg},
607 'cache_max_mem_usage',
608 $xl::s{l_oth_max_use},
609 $xl::s{h_oth_max_use},
610 'int,0,262144', # 0 Kb - 256 Mb
616 'cache_min_keep_time',
617 $xl::s{l_oth_min_time},
618 $xl::s{h_oth_min_time},
619 'int,0,120', # 0 minutes - 2 hours
625 'use_networkmanager',
626 $xl::s{l_oth_use_netm},
627 $xl::s{h_oth_use_netm},
635 sub new_other_page() {
636 return new_vbox_pack (
639 new_check_button_for(\%pr::oth, 'use_dlg')),
640 $xl::s{ab_frame}, 'not-packed'),
643 new_text_box_for_int(\%pr::oth, 'max_use'),
644 new_text_box_for_int(\%pr::oth, 'min_time')),
645 $xl::s{mem_frame}, 'not-packed'),
648 new_check_button_for(\%pr::oth, 'use_netm')),
649 $xl::s{netm_frame}, 'not-packed')
653 %pr::gui = ( # gui bells and whistles
656 $xl::s{l_gui_b_unread},
657 $xl::s{h_gui_b_unread},
665 $xl::s{l_gui_no_markup},
666 $xl::s{h_gui_no_markup},
673 'enable_dotted_lines',
674 $xl::s{l_gui_dot_lines},
675 $xl::s{h_gui_dot_lines},
683 $xl::s{l_gui_h_scroll},
684 $xl::s{h_gui_h_scroll},
692 $xl::s{l_gui_swp_from},
693 $xl::s{h_gui_swp_from},
700 'folderview_vscrollbar_policy',
701 $xl::s{l_gui_v_scroll},
702 $xl::s{h_gui_v_scroll},
703 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
710 $xl::s{l_gui_from_show},
711 $xl::s{h_gui_from_show},
712 '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
718 'stripes_color_offset',
719 $xl::s{l_gui_strip_off},
720 $xl::s{h_gui_strip_off},
721 'int,0,40000', # no idea what this number means
727 'textview_cursor_visible',
728 $xl::s{l_gui_cursor_v},
729 $xl::s{h_gui_cursor_v},
736 'toolbar_detachable',
737 $xl::s{l_gui_toolbar_d},
738 $xl::s{h_gui_toolbar_d},
745 'use_stripes_everywhere',
746 $xl::s{l_gui_strip_all},
747 $xl::s{h_gui_strip_all},
754 'use_stripes_in_summaries',
755 $xl::s{l_gui_strip_sum},
756 $xl::s{h_gui_strip_sum},
764 $xl::s{l_gui_two_line_v},
765 $xl::s{h_gui_two_line_v},
772 'show_compose_margin',
773 $xl::s{l_gui_margin_co},
774 $xl::s{h_gui_margin_co},
781 'msgview_date_format',
782 $xl::s{l_gui_mview_date},
783 $xl::s{h_gui_mview_date},
790 'zero_replacement_char',
791 $xl::s{l_gui_zero_char},
792 $xl::s{h_gui_zero_char},
800 $xl::s{l_gui_type_any},
801 $xl::s{h_gui_type_any},
810 my $gf = Gtk2::VBox->new (FALSE, 5);
811 $gf->set_border_width (PAGE_SPC);
813 my $cb_dot_lines = new_check_button_for (\%pr::gui, 'dot_lines');
814 my $cb_toolbar_d = new_check_button_for (\%pr::gui, 'toolbar_d');
815 my $tb_zero_char = new_text_box_for_nchar (\%pr::gui, 'zero_char');
817 $gf->pack_start (new_subpage_frame (
819 new_check_button_for (\%pr::gui, 'strip_all'),
820 new_check_button_for (\%pr::gui, 'strip_sum'),
821 new_text_box_for_int (\%pr::gui, 'strip_off')),
822 $xl::s{stripes_frame}, 'not-packed'),
823 FALSE, FALSE, FRAME_SPC);
824 $gf->pack_start (new_subpage_frame (
826 new_check_button_for (\%pr::gui, 'b_unread'),
827 new_check_button_for (\%pr::gui, 'swp_from'),
828 new_check_button_for (\%pr::gui, 'two_linev'),
829 new_selection_box_for (\%pr::gui, 'from_show')),
830 $xl::s{mlist_frame}, 'not-packed'),
831 FALSE, FALSE, FRAME_SPC);
832 $gf->pack_start (new_subpage_frame (
834 new_check_button_for (\%pr::gui, 'cursor_v'),
835 new_check_button_for (\%pr::gui, 'mview_date')),
836 $xl::s{mview_frame}, 'not-packed'),
837 FALSE, FALSE, FRAME_SPC);
838 $gf->pack_start (new_subpage_frame (
840 new_check_button_for (\%pr::gui, 'no_markup'),
841 new_check_button_for (\%pr::gui, 'margin_co'),
842 new_check_button_for (\%pr::gui, 'type_any')),
843 $xl::s{compo_frame}, 'not-packed'),
844 FALSE, FALSE, FRAME_SPC);
845 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
846 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
847 $gf->pack_start (new_subpage_frame (
849 new_check_button_for (\%pr::gui, 'h_scroll'),
850 new_selection_box_for (\%pr::gui, 'v_scroll')),
851 $xl::s{sbar_frame}, 'not-packed'),
852 FALSE, FALSE, FRAME_SPC);
853 $gf->pack_start ($tb_zero_char, FALSE, FALSE, 0);
858 %pr::beh = ( # tweak some behaviour
861 $xl::s{l_beh_hover_t},
862 $xl::s{h_beh_hover_t},
863 'int,100,3000', # 0.1 seconds - 3 seconds
870 $xl::s{l_beh_dangerous},
871 $xl::s{h_beh_dangerous},
878 'respect_flowed_format',
879 $xl::s{l_beh_flowed},
880 $xl::s{h_beh_flowed},
887 'save_parts_readwrite',
888 $xl::s{l_beh_parts_rw},
889 $xl::s{h_beh_parts_rw},
896 'skip_ssl_cert_check',
897 $xl::s{l_beh_skip_ssl},
898 $xl::s{h_beh_skip_ssl},
905 'statusbar_update_step',
906 $xl::s{l_beh_up_step},
907 $xl::s{h_beh_up_step},
908 'int,1,200', # 1 item - 200 items
914 'thread_by_subject_max_age',
915 $xl::s{l_beh_thread_a},
916 $xl::s{h_beh_thread_a},
917 'int,1,30', # 1 day - 30 days
924 $xl::s{l_beh_unsafe_ssl},
925 $xl::s{h_beh_unsafe_ssl},
932 'utf8_instead_of_locale_for_broken_mail',
933 $xl::s{l_beh_use_utf8},
934 $xl::s{h_beh_use_utf8},
942 $xl::s{l_beh_warn_dnd},
943 $xl::s{h_beh_warn_dnd},
950 'outgoing_fallback_to_ascii',
951 $xl::s{l_beh_out_ascii},
952 $xl::s{h_beh_out_ascii},
959 'primary_paste_unselects',
960 $xl::s{l_beh_pp_unsel},
961 $xl::s{h_beh_pp_unsel},
968 'show_inline_attachments',
969 $xl::s{l_beh_inline_at},
970 $xl::s{h_beh_inline_at},
977 'address_search_wildcard',
978 $xl::s{l_beh_addr_swc},
979 $xl::s{h_beh_addr_sw1},
986 'folder_search_wildcard',
987 $xl::s{l_beh_fold_swc},
988 $xl::s{h_beh_fold_sw1},
996 sub new_behaviour_page() {
997 my $bf = Gtk2::VBox->new (FALSE, 5);
998 $bf->set_border_width (PAGE_SPC);
1000 my $tb_up_step = new_text_box_for_int (\%pr::beh, 'up_step');
1001 my $tb_thread_a = new_text_box_for_int (\%pr::beh, 'thread_a');
1003 $bf->pack_start (new_subpage_frame (
1005 new_text_box_for_int (\%pr::beh, 'hover_t'),
1006 new_check_button_for (\%pr::beh, 'warn_dnd')),
1007 $xl::s{dnd_frame}, 'not-packed'),
1008 FALSE, FALSE, FRAME_SPC);
1009 $bf->pack_start (new_subpage_frame (
1011 new_check_button_for (\%pr::beh, 'skip_ssl'),
1012 new_check_button_for (\%pr::beh, 'unsafe_ssl')),
1013 $xl::s{ssl_frame}, 'not-packed'),
1014 FALSE, FALSE, FRAME_SPC);
1015 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
1016 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
1017 $bf->pack_start (new_subpage_frame (
1019 new_check_button_for (\%pr::beh, 'flowed'),
1020 new_check_button_for (\%pr::beh, 'parts_rw'),
1021 new_check_button_for (\%pr::beh, 'use_utf8'),
1022 new_check_button_for (\%pr::beh, 'dangerous'),
1023 new_check_button_for (\%pr::beh, 'out_ascii'),
1024 new_check_button_for (\%pr::beh, 'pp_unsel'),
1025 new_check_button_for (\%pr::beh, 'inline_at')),
1026 $xl::s{msgs_frame}, 'not-packed'),
1027 FALSE, FALSE, FRAME_SPC);
1028 $bf->pack_start (new_subpage_frame (
1030 new_check_button_for (\%pr::beh, 'addr_swc'),
1031 new_check_button_for (\%pr::beh, 'fold_swc')),
1032 $xl::s{swc_frame}, 'not-packed'),
1033 FALSE, FALSE, FRAME_SPC);
1037 %pr::col = ( # a variety of colours
1040 $xl::s{l_col_emphasis},
1041 $xl::s{h_col_emphasis},
1049 $xl::s{l_col_log_err},
1050 $xl::s{h_col_log_err},
1058 $xl::s{l_col_log_in},
1059 $xl::s{h_col_log_in},
1067 $xl::s{l_col_log_msg},
1068 $xl::s{h_col_log_msg},
1076 $xl::s{l_col_log_out},
1077 $xl::s{h_col_log_out},
1085 $xl::s{l_col_log_warn},
1086 $xl::s{h_col_log_warn},
1094 $xl::s{l_col_diff_add},
1095 $xl::s{h_col_diff_add},
1102 'diff_deleted_color',
1103 $xl::s{l_col_diff_del},
1104 $xl::s{h_col_diff_del},
1112 $xl::s{l_col_diff_hunk},
1113 $xl::s{h_col_diff_hunk},
1121 sub new_colours_page() {
1122 return new_vbox_pack (
1125 new_color_button_for (\%pr::col, 'emphasis')),
1126 $xl::s{msgview_frame}, 'not-packed'),
1129 new_color_button_for (\%pr::col, 'log_err'),
1130 new_color_button_for (\%pr::col, 'log_in'),
1131 new_color_button_for (\%pr::col, 'log_msg'),
1132 new_color_button_for (\%pr::col, 'log_out'),
1133 new_color_button_for (\%pr::col, 'log_warn')),
1134 $xl::s{log_frame}, 'not-packed'),
1137 new_color_button_for (\%pr::col, 'diff_add'),
1138 new_color_button_for (\%pr::col, 'diff_del'),
1139 new_color_button_for (\%pr::col, 'diff_hunk')),
1140 $xl::s{diff_frame}, 'not-packed')
1144 %pr::win = ( # tweak window positions and/or sizes
1149 'int,0,3000', # 0 pixels - 3000 pixels
1158 'int,0,3000', # 0 pixels - 3000 pixels
1167 'int,0,3000', # 0 pixels - 3000 pixels
1176 'int,0,3000', # 0 pixels - 3000 pixels
1182 'mainwin_maximised',
1183 $xl::s{l_win_main_mx},
1184 $xl::s{h_win_main_mx},
1191 'mainwin_fullscreen',
1192 $xl::s{l_win_main_fs},
1193 $xl::s{h_win_main_fs},
1200 'main_messagewin_x',
1203 'int,0,3000', # 0 pixels - 3000 pixels
1209 'main_messagewin_y',
1212 'int,0,3000', # 0 pixels - 3000 pixels
1221 'int,0,3000', # 0 pixels - 3000 pixels
1227 'messagewin_height',
1230 'int,0,3000', # 0 pixels - 3000 pixels
1239 'int,0,3000', # 0 pixels - 3000 pixels
1248 'int,0,3000', # 0 pixels - 3000 pixels
1257 'int,0,3000', # 0 pixels - 3000 pixels
1263 'receivewin_height',
1266 'int,0,3000', # 0 pixels - 3000 pixels
1275 'int,0,3000', # 0 pixels - 3000 pixels
1284 'int,0,3000', # 0 pixels - 3000 pixels
1290 'folderitemwin_width',
1293 'int,0,3000', # 0 pixels - 3000 pixels
1299 'folderitemwin_height',
1302 'int,0,3000', # 0 pixels - 3000 pixels
1308 'folderselwin_width',
1311 'int,0,3000', # 0 pixels - 3000 pixels
1317 'folderselwin_height',
1320 'int,0,3000', # 0 pixels - 3000 pixels
1329 'int,0,3000', # 0 pixels - 3000 pixels
1338 'int,0,3000', # 0 pixels - 3000 pixels
1344 'addressbookwin_width',
1347 'int,0,3000', # 0 pixels - 3000 pixels
1353 'addressbookwin_height',
1356 'int,0,3000', # 0 pixels - 3000 pixels
1362 'addressbookeditpersonwin_width',
1365 'int,0,3000', # 0 pixels - 3000 pixels
1371 'addressbookeditpersonwin_height',
1374 'int,0,3000', # 0 pixels - 3000 pixels
1380 'addressbookeditgroupwin_width',
1383 'int,0,3000', # 0 pixels - 3000 pixels
1389 'addressbookeditgroupwin_height',
1392 'int,0,3000', # 0 pixels - 3000 pixels
1398 'addressaddwin_width',
1401 'int,0,3000', # 0 pixels - 3000 pixels
1407 'addressaddwin_height',
1410 'int,0,3000', # 0 pixels - 3000 pixels
1416 'addressbook_folderselwin_width',
1419 'int,0,3000', # 0 pixels - 3000 pixels
1425 'addressbook_folderselwin_height',
1428 'int,0,3000', # 0 pixels - 3000 pixels
1434 'editaccountwin_width',
1437 'int,0,3000', # 0 pixels - 3000 pixels
1443 'editaccountwin_height',
1446 'int,0,3000', # 0 pixels - 3000 pixels
1452 'accountswin_width',
1455 'int,0,3000', # 0 pixels - 3000 pixels
1461 'accountswin_height',
1464 'int,0,3000', # 0 pixels - 3000 pixels
1470 'filteringwin_width',
1473 'int,0,3000', # 0 pixels - 3000 pixels
1479 'filteringwin_height',
1482 'int,0,3000', # 0 pixels - 3000 pixels
1488 'filteringactionwin_width',
1491 'int,0,3000', # 0 pixels - 3000 pixels
1497 'filteringactionwin_height',
1500 'int,0,3000', # 0 pixels - 3000 pixels
1506 'filtering_debugwin_width',
1509 'int,0,3000', # 0 pixels - 3000 pixels
1515 'filtering_debugwin_height',
1518 'int,0,3000', # 0 pixels - 3000 pixels
1527 'int,0,3000', # 0 pixels - 3000 pixels
1533 'matcherwin_height',
1536 'int,0,3000', # 0 pixels - 3000 pixels
1545 'int,0,3000', # 0 pixels - 3000 pixels
1554 'int,0,3000', # 0 pixels - 3000 pixels
1560 'templateswin_width',
1563 'int,0,3000', # 0 pixels - 3000 pixels
1569 'templateswin_height',
1572 'int,0,3000', # 0 pixels - 3000 pixels
1581 'int,0,3000', # 0 pixels - 3000 pixels
1587 'actionswin_height',
1590 'int,0,3000', # 0 pixels - 3000 pixels
1599 'int,0,3000', # 0 pixels - 3000 pixels
1608 'int,0,3000', # 0 pixels - 3000 pixels
1617 'int,0,3000', # 0 pixels - 3000 pixels
1623 'pluginswin_height',
1626 'int,0,3000', # 0 pixels - 3000 pixels
1635 'int,0,3000', # 0 pixels - 3000 pixels
1644 'int,0,3000', # 0 pixels - 3000 pixels
1650 'print_previewwin_width',
1653 'int,0,3000', # 0 pixels - 3000 pixels
1659 'print_previewwin_height',
1662 'int,0,3000', # 0 pixels - 3000 pixels
1669 sub new_winpos_subpage_main() {
1670 return new_subpage_frame (
1671 new_vbox_pack_compact (
1673 new_text_box_for_int (\%pr::win, 'main_x'),
1674 new_text_box_for_int (\%pr::win, 'main_y')),
1676 new_text_box_for_int (\%pr::win, 'main_w'),
1677 new_text_box_for_int (\%pr::win, 'main_h')),
1679 new_check_button_for (\%pr::win, 'main_fs'),
1680 new_check_button_for (\%pr::win, 'main_mx'))),
1685 sub new_winpos_subpage_msgs() {
1686 return new_subpage_frame (
1687 new_vbox_pack_compact (
1689 new_text_box_for_int (\%pr::win, 'msgs_x'),
1690 new_text_box_for_int (\%pr::win, 'msgs_y')),
1692 new_text_box_for_int (\%pr::win, 'msgs_w'),
1693 new_text_box_for_int (\%pr::win, 'msgs_h'))),
1698 sub new_winpos_subpage_sendrecv() {
1699 return new_vbox_pack (
1702 new_text_box_for_int (\%pr::win, 'send_w'),
1703 new_text_box_for_int (\%pr::win, 'send_h')),
1704 _('Send window'), 'not-packed'),
1707 new_text_box_for_int (\%pr::win, 'recv_w'),
1708 new_text_box_for_int (\%pr::win, 'recv_h')),
1709 _('Receive window'), 'not-packed')
1713 sub new_winpos_subpage_fold() {
1714 return new_vbox_pack (
1716 new_vbox_pack_compact (
1718 new_text_box_for_int (\%pr::win, 'fold_x'),
1719 new_text_box_for_int (\%pr::win, 'fold_y')),
1721 new_text_box_for_int (\%pr::win, 'fold_w'),
1722 new_text_box_for_int (\%pr::win, 'fold_h'))),
1723 _('Folder window'), 'not-packed'),
1726 new_text_box_for_int (\%pr::win, 'fsel_w'),
1727 new_text_box_for_int (\%pr::win, 'fsel_h')),
1728 _('Folder selection window'), 'not-packed')
1732 sub new_winpos_subpage_addrbook() {
1733 return new_vbox_pack (
1736 new_text_box_for_int (\%pr::win, 'addr_w'),
1737 new_text_box_for_int (\%pr::win, 'addr_h')),
1738 _('Addressbook main window'), 'not-packed'),
1741 new_text_box_for_int (\%pr::win, 'adep_w'),
1742 new_text_box_for_int (\%pr::win, 'adep_h')),
1743 _('Edit person window'), 'not-packed'),
1746 new_text_box_for_int (\%pr::win, 'adeg_w'),
1747 new_text_box_for_int (\%pr::win, 'adeg_h')),
1748 _('Edit group window'), 'not-packed'),
1751 new_text_box_for_int (\%pr::win, 'adda_w'),
1752 new_text_box_for_int (\%pr::win, 'adda_h')),
1753 _('Add address window'), 'not-packed'),
1756 new_text_box_for_int (\%pr::win, 'addf_w'),
1757 new_text_box_for_int (\%pr::win, 'addf_h')),
1758 _('Folder select window'), 'not-packed')
1762 sub new_winpos_subpage_accounts() {
1763 return new_vbox_pack (
1766 new_text_box_for_int (\%pr::win, 'acco_w'),
1767 new_text_box_for_int (\%pr::win, 'acco_h')),
1768 _('Accounts window'), 'not-packed'),
1771 new_text_box_for_int (\%pr::win, 'acce_w'),
1772 new_text_box_for_int (\%pr::win, 'acce_h')),
1773 _('Edit account window'), 'not-packed')
1777 sub new_winpos_subpage_filtering() {
1778 return new_vbox_pack (
1781 new_text_box_for_int (\%pr::win, 'filt_w'),
1782 new_text_box_for_int (\%pr::win, 'filt_h')),
1783 _('Filtering window'), 'not-packed'),
1786 new_text_box_for_int (\%pr::win, 'fila_w'),
1787 new_text_box_for_int (\%pr::win, 'fila_h')),
1788 _('Filtering actions window'), 'not-packed'),
1791 new_text_box_for_int (\%pr::win, 'fild_w'),
1792 new_text_box_for_int (\%pr::win, 'fild_h')),
1793 _('Filtering debug window'), 'not-packed'),
1796 new_text_box_for_int (\%pr::win, 'matc_w'),
1797 new_text_box_for_int (\%pr::win, 'matc_h')),
1798 _('Matcher window'), 'not-packed')
1802 sub new_winpos_subpage_prefs() {
1803 return new_vbox_pack (
1806 new_text_box_for_int (\%pr::win, 'pref_w'),
1807 new_text_box_for_int (\%pr::win, 'pref_h')),
1808 _('Preferences window'), 'not-packed'),
1811 new_text_box_for_int (\%pr::win, 'temp_w'),
1812 new_text_box_for_int (\%pr::win, 'temp_h')),
1813 _('Templates window'), 'not-packed'),
1816 new_text_box_for_int (\%pr::win, 'acti_w'),
1817 new_text_box_for_int (\%pr::win, 'acti_h')),
1818 _('Actions window'), 'not-packed'),
1821 new_text_box_for_int (\%pr::win, 'tags_w'),
1822 new_text_box_for_int (\%pr::win, 'tags_h')),
1823 _('Tags window'), 'not-packed'),
1826 new_text_box_for_int (\%pr::win, 'plug_w'),
1827 new_text_box_for_int (\%pr::win, 'plug_h')),
1828 _('Plugins window'), 'not-packed')
1832 sub new_winpos_subpage_misc() {
1833 return new_vbox_pack (
1836 new_text_box_for_int (\%pr::win, 'logw_w'),
1837 new_text_box_for_int (\%pr::win, 'logw_h')),
1838 _('Log window'), 'not-packed'),
1841 new_text_box_for_int (\%pr::win, 'prin_w'),
1842 new_text_box_for_int (\%pr::win, 'prin_h')),
1843 _('Print preview window'), 'not-packed'),
1846 new_text_box_for_int (\%pr::win, 'sour_w'),
1847 new_text_box_for_int (\%pr::win, 'sour_h')),
1848 _('View source window'), 'not-packed')
1852 sub new_winpos_page() {
1853 my $winbook = Gtk2::Notebook->new;
1854 $winbook->set_tab_pos ('right');
1855 $winbook->append_page (new_winpos_subpage_main, _('Main'));
1856 $winbook->append_page (new_winpos_subpage_msgs, _('Message'));
1857 $winbook->append_page (new_winpos_subpage_sendrecv, _('Send/Receive'));
1858 $winbook->append_page (new_winpos_subpage_fold, _('Folder'));
1859 $winbook->append_page (new_winpos_subpage_addrbook, _('Addressbook'));
1860 $winbook->append_page (new_winpos_subpage_accounts, _('Accounts'));
1861 $winbook->append_page (new_winpos_subpage_filtering, _('Filtering'));
1862 $winbook->append_page (new_winpos_subpage_prefs, _('Preferences'));
1863 $winbook->append_page (new_winpos_subpage_misc, _('Other'));
1868 sub print_version() {
1869 print $xl::s{about_title} . "\n";
1870 print $xl::s{about_version} . " $VERSION\n";
1871 print "Perl-GLib " . $Glib::VERSION;
1872 # version info stuff appeared in 1.040
1873 if ($Glib::VERSION >= 1.040) {
1874 print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
1875 . _(", running with ") . join(".", &Glib::major_version,
1876 &Glib::minor_version, &Glib::micro_version);
1879 print "Perl-GTK2 " . $Gtk2::VERSION;
1880 if ($Gtk2::VERSION >= 1.040) {
1881 print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1882 . _(", running with ") . join(".", &Gtk2::major_version,
1883 &Gtk2::minor_version, &Gtk2::micro_version);
1886 my $clawsver = ($CLAWSV eq "") ?
1887 _("was not found!") :
1888 (_("returned version ") . $CLAWSV);
1889 print "Claws Mail " . $clawsver . "\n";
1892 # the command line help
1894 my $line = '-' x length ($xl::s{about_title}) . "\n";
1896 print $xl::s{about_title} . "\n";
1898 print _("Syntax:\n");
1899 print _(" clawsker [options]\n");
1900 print _("Options:\n");
1901 print _(" -h|--help Prints this help screen.\n");
1902 print _(" -v|--version Prints version infos.\n");
1903 print _(" -b|--verbose More messages on standard output.\n");
1904 print _(" -a|--alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1905 print _(" -c|--clawsrc <file> Uses <file> as full resource name.\n");
1908 sub parse_command_line {
1910 $CLAWSV = get_claws_version ();
1912 GetOptions('h|help' => sub { print_help (); $cont = FALSE },
1913 'v|version' => sub { print_version (); $cont = FALSE },
1914 'b|verbose' => sub { $VERBOSE = TRUE },
1915 'u|use-claws-version=s' => \&opt_use_claws_version,
1916 'a|alternate-config-dir=s' => \&opt_alternate_config_dir,
1917 'r|clawsrc=s' => \&opt_clawsrc)
1918 or die _("try -h or --help for syntax.\n");
1921 my $msg = _("Error in options: {msg}\n", msg => $@);
1922 if (defined $ENV{'DISPLAY'} and $ENV{'DISPLAY'} ne '') {
1923 eval { Gtk2->init };
1924 error_dialog ($msg) unless $@;
1931 sub opt_use_claws_version {
1932 my ($name, $value) = @_;
1933 die _("Error: {opt} requires a dotted numeric value argument\n", opt => $name)
1934 unless ($value =~ /^[\d\.]+$/);
1938 sub opt_alternate_config_dir {
1939 my ($name, $value) = @_;
1940 die _("Error: '{dir}' is not a directory or does not exist\n", dir => $value)
1942 $CONFIGDIR = $value;
1943 $CONFIGDIR .= "/" unless ($CONFIGDIR =~ /.*\/$/);
1944 $ALTCONFIGDIR = TRUE;
1948 my ($name, $value) = @_;
1949 die _("Error: '{value}' is not a file or does not exist\n", value => $value)
1951 set_rc_filename ($value);
1954 # update the hidden preferences status from loaded values
1955 sub init_hidden_preferences {
1956 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1957 foreach my $key (keys %$hash) {
1958 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1964 # load current status from disc
1965 sub load_preferences {
1966 my $rc = get_rc_filename ();
1967 log_message ("Loading preferences from $rc\n");
1968 return FALSE unless check_rc_file ($rc);
1969 return FALSE unless check_claws_not_running ();
1973 if (/^([8a-z_]+)=(.*)$/) {
1974 $PREFS{$1} = decode('UTF-8', $2);
1981 # save current preferences to disc
1982 sub save_preferences {
1983 my $rc = get_rc_filename ();
1984 log_message ("Saving preferences to $rc\n");
1985 return FALSE unless check_rc_file ($rc);
1986 return FALSE unless check_claws_not_running ();
1987 my $rcbak = "$rc.backup";
1988 rename ($rc, $rcbak);
1990 open (RCB, "<$rcbak");
1993 if (/^([8a-z_]+)=(.*)$/) {
1994 if (defined($HPVALUE{$1})) {
1995 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1998 print RCF $_ . "\n";
2002 print RCF $_ . "\n";
2012 my $nb = Gtk2::Notebook->new;
2014 $nb->append_page (new_behaviour_page (), $xl::s{tab_behaviour});
2015 $nb->append_page (new_colours_page (), $xl::s{tab_colours});
2016 $nb->append_page (new_gui_page (), $xl::s{tab_gui});
2017 $nb->append_page (new_other_page (), $xl::s{tab_other});
2018 $nb->append_page (new_winpos_page (), $xl::s{tab_winpos});
2023 # create an about dialog
2024 sub new_about_dialog {
2026 my $title = $xl::s{about_title};
2027 my $lic = $xl::s{about_license};
2028 my $vers = $xl::s{about_version} . " $VERSION";
2030 "This program is free software: you can redistribute it and/or modify
2031 it under the terms of the GNU General Public License as published by
2032 the Free Software Foundation, either version 3 of the License, or
2033 (at your option) any later version.
2035 This program is distributed in the hope that it will be useful,
2036 but WITHOUT ANY WARRANTY; without even the implied warranty of
2037 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2038 GNU General Public License for more details.
2040 You should have received a copy of the GNU General Public License
2041 along with this program. If not, see <http://www.gnu.org/licenses/>.";
2042 my $year = "2007-2015";
2043 my $holder = "Ricardo Mones <ricardo\@mones.org>";
2044 my $url = "http://www.claws-mail.org/clawsker.php";
2046 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
2047 [qw/modal destroy-with-parent/],
2049 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
2050 . "<span size=\"large\">$vers</span>\n\n"
2051 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
2052 . "<span>Copyright $year by $holder</span>\n\n"
2053 . "<span size=\"large\">$lic</span>\n\n"
2054 . "<span size=\"small\">$license</span>");
2055 $dialog->set_title ($xl::s{about});
2060 # create buttons box
2061 sub new_button_box {
2062 my ($parent, $adlg) = @_;
2063 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
2064 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
2065 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
2066 # disable button until is really implemented
2067 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
2068 my $hbox = Gtk2::HBox->new (FALSE, 5);
2070 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
2071 $b_apply->signal_connect (clicked => sub { save_preferences ($parent) });
2072 # $b_undo->signal_connect (clicked => sub { undo_current_changes });
2073 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
2075 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
2076 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
2077 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
2078 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
2084 exit unless parse_command_line ();
2086 $main_window = Gtk2::Window->new ('toplevel');
2087 exit unless load_preferences ();
2088 exit unless init_hidden_preferences ();
2090 my $box = Gtk2::VBox->new (FALSE, 5);
2091 $box->set_border_width(3);
2092 my $about = new_about_dialog ();
2093 $box->pack_start (new_notebook (), FALSE, FALSE, 0);
2094 $box->pack_end (new_button_box ($main_window, $about), FALSE, FALSE, 0);
2095 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
2096 $main_window->set_title ($xl::s{win_title});
2097 $main_window->add ($box);
2098 $main_window->show_all;