3 # Clawsker :: A Claws Mail Tweaker
4 # Copyright 2007-2014 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.
16 use Glib qw(TRUE FALSE);
18 use POSIX qw(setlocale);
21 use Digest::MD5 qw(md5_hex);
23 my $NAME = 'clawsker';
24 my $PREFIX = '@PREFIX@';
25 my $LIBDIR = '@LIBDIR@';
26 my $VERSION = '@VERSION@';
29 my $main_window = undef;
31 my $locale = (defined($ENV{LC_MESSAGES}) ? $ENV{LC_MESSAGES} : $ENV{LANG});
32 $locale = "C" unless defined($locale);
33 setlocale (LC_ALL, $locale);
34 bindtextdomain ($NAME, sprintf ('%s/share/locale', $PREFIX));
37 my $SHOWHINTS = FALSE;
38 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
43 my $xla = gettext ($str);
44 if (scalar(keys(%par)) > 0) {
45 foreach my $key (keys %par) {
46 $xla =~ s/\{$key\}/$par{$key}/g;
49 return decode_utf8($xla);
54 win_title => _('Claws Mail Hidden Preferences'),
55 about => _('About...'),
56 about_title => _('Clawsker :: A Claws Mail Tweaker'),
57 about_license => _('License:'),
58 about_version => _('Version:'),
60 tab_colours => _('Colours'),
61 tab_behaviour => _('Behaviour'),
63 tab_other => _('Other'),
64 tab_winpos => _('Windows'),
66 ab_frame => _('Addressbook'),
67 mem_frame => _('Memory'),
68 msgview_frame => _('Message View'),
69 log_frame => _('Log window'),
70 dnd_frame => _('Drag \'n\' drop'),
71 ssl_frame => _('Secure Sockets Layer'),
72 msgs_frame => _('Messages'),
73 swc_frame => _('Completion'),
74 stripes_frame => _('Coloured stripes'),
75 sbar_frame => _('Scroll bars'),
76 mlist_frame => _('Message List'),
77 mview_frame => _('Message View'),
78 compo_frame => _('Compose window'),
79 netm_frame => _('NetworkManager'),
80 diff_frame => _('Viewing patches'),
82 l_oth_use_dlg => _('Use detached address book edit dialogue'),
83 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.'),
84 l_oth_max_use => _('Maximum memory for message cache (kB)'),
85 h_oth_max_use => _('The maximum amount of memory to use to cache messages, in kilobytes.'),
86 l_oth_min_time => _('Minimun time for cache elements (minutes)'),
87 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.'),
88 l_oth_use_netm => _('Use NetworkManager'),
89 h_oth_use_netm => _('Use NetworkManager to switch offline automatically.'),
91 l_gui_b_unread => _('Show unread messages with bold font'),
92 h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
93 l_gui_no_markup => _('Don\'t use markup in compose window'),
94 h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
95 l_gui_dot_lines => _('Use dotted lines in tree view components'),
96 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.'),
97 l_gui_h_scroll => _('Enable horizontal scrollbar'),
98 h_gui_h_scroll => _('Enable the horizontal scrollbar in the Message List.'),
99 l_gui_swp_from => _('Display To column instead From column in Sent folder'),
100 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.'),
101 l_gui_v_scroll => _('Folder List scrollbar behaviour'),
102 h_gui_v_scroll => _('Specify the policy of vertical scrollbar of Folder List: show always, automatic or hide always.'),
103 l_gui_v_scroll_show => _('Show always'),
104 l_gui_v_scroll_auto => _('Automatic'),
105 l_gui_v_scroll_hide => _('Hide always'),
106 l_gui_from_show => _('From column displays'),
107 h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both'),
108 l_gui_from_show_name => _('Name only'),
109 l_gui_from_show_addr => _('Address only'),
110 l_gui_from_show_both => _('Both name and address'),
111 l_gui_strip_off => _('Coloured lines contrast'),
112 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.'),
113 l_gui_cursor_v => _('Show cursor'),
114 h_gui_cursor_v => _('Display the cursor in the Message View.'),
115 l_gui_toolbar_d => _('Detachable toolbars'),
116 h_gui_toolbar_d => _('Show handles in the toolbars.'),
117 l_gui_strip_all => _('Use stripes in all tree view components'),
118 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
119 l_gui_strip_sum => _('Use stripes in Folder List and Message List'),
120 h_gui_strip_sum => _('Enable alternately coloured lines in Message List and Folder List.'),
121 l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
122 h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
123 l_gui_margin_co => _('Show compose margin'),
124 h_gui_margin_co => _('Shows a small margin in the Compose View.'),
125 l_gui_mview_date => _('Don\'t display localized date'),
126 h_gui_mview_date => _('Toggles localization of date format in Message View'),
127 l_gui_zero_char => _('Zero replacement character'),
128 h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List'),
130 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
131 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.'),
132 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
133 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
134 l_beh_flowed => _('Respect format=flowed in messages'),
135 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.'),
136 l_beh_parts_rw => _('Allow writable temporary files'),
137 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
138 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
139 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
140 l_beh_up_step => _('Progress bar update step (items)'),
141 h_beh_up_step => _('Update stepping in progress bars.'),
142 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
143 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
144 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
145 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
146 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
147 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
148 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
149 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
150 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
151 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
152 l_beh_pp_unsel => _('Primary paste unselects selection'),
153 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
154 l_beh_inline_at => _('Show inline attachments'),
155 h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
156 l_beh_addr_swc => _('Address search in compose window matches any'),
157 h_beh_addr_swc => _('On Tab-key completion, address text will match any part of the string or only the from the start'),
158 l_beh_fold_swc => _('Folder search in folder selector matches any'),
159 h_beh_fold_swc => _('On folder name completion text will match any part of the string or only from the start'),
161 l_col_emphasis => _('X-Mailer header'),
162 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
163 l_col_log_err => _('Error messages'),
164 h_col_log_err => _('Colour for error messages in log window.'),
165 l_col_log_in => _('Server messages'),
166 h_col_log_in => _('Colour for messages received from servers in log window.'),
167 l_col_log_msg => _('Standard messages'),
168 h_col_log_msg => _('Colour for messages in log window.'),
169 l_col_log_out => _('Client messages'),
170 h_col_log_out => _('Colour for messages sent to servers in log window.'),
171 l_col_log_warn => _('Warnings'),
172 h_col_log_warn => _('Colour for warning messages in log window.'),
174 l_col_diff_add => _('Added lines'),
175 h_col_diff_add => _('Colour for added lines in patches.'),
176 l_col_diff_del => _('Deleted lines'),
177 h_col_diff_del => _('Colour for deleted lines in patches.'),
178 l_col_diff_hunk => _('Hunk lines'),
179 h_col_diff_hunk => _('Color for hunk headers in patches.'),
181 l_win_x => _('X position'),
182 h_win_x => _('X coordinate for window\'s top-left corner.'),
183 l_win_y => _('Y position'),
184 h_win_y => _('Y coordinate for window\'s top-left corner.'),
185 l_win_w => _('Width'),
186 h_win_w => _('Window\'s width in pixels.'),
187 l_win_h => _('Height'),
188 h_win_h => _('Window\'s height in pixels.'),
190 l_win_main_mx => _('Maximized'),
191 h_win_main_mx => _('Changes window maximized status.'),
192 l_win_main_fs => _('Full-screen'),
193 h_win_main_fs => _('Changes full screen status.'),
195 e_error => _('Error: '),
196 e_noclawsrc => _('resource file for Claws Mail was not found.'),
197 e_running => _('seems Claws Mail is currently running, close it first.'),
198 e_requireddir => _('option requires a directory name.'),
199 e_requiredfile => _('option requires a file name.'),
200 e_notadir => _('specified name is not a directory or does not exist.'),
201 e_notafile => _('specified name is not a file or does not exist.'),
204 # all preferences read by load_preferences
206 # values of all preferences handled by clawsker
208 # default config dir and file name
209 my $ALTCONFIGDIR = FALSE;
210 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
211 my $CONFIGRC = 'clawsrc';
213 # index constants for preference arrays
214 use constant NAME => 0; # the name on the rc file
215 use constant LABEL => 1; # the label on the GUI
216 use constant DESC => 2; # the description for the hint/help
217 use constant TYPE => 3; # data type: bool, int, float, string, color
218 use constant CMVER => 4; # lowest[,highest] Claws Mail version(s) the feature exists
219 use constant CMDEF => 5; # default value for the preference in Claws Mail
220 use constant GUI => 6; # GUI element
222 # constants for GUI spacing
223 use constant HBOX_SPC => 5;
224 use constant FRAME_SPC => 2;
225 use constant PAGE_SPC => 5;
229 sub version_greater_or_equal {
230 my ($version, $refvers) = @_;
231 my @version = split (/\./, $version);
232 my @refvers = split (/\./, $refvers);
233 while ($#version < $#refvers) {
234 push (@version, '0');
237 while (($idx <= $#refvers)
238 and (int ($version[$idx]) == int ($refvers[$idx]))) {
241 return TRUE if (($idx > $#refvers)
242 or (int ($version[$idx]) >= int ($refvers[$idx])));
246 sub get_claws_version {
251 foreach my $bin (@cmbin) {
256 return "" unless ($_); # not installed
259 my @fver = split (/ /);
260 die "Invalid version string" unless ($fver[2] eq "version");
261 my @ver = split (/\./, $fver[3]);
264 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
273 # data handlers and auxiliar functions
275 sub handle_bool_value {
276 my ($widget, $event, $dataref) = @_;
277 $$dataref = ($widget->get_active ())? '1': '0';
280 sub handle_int_value {
281 my ($widget, $event, $dataref) = @_;
282 $_ = $widget->get_text ();
287 $widget->set_text ($_);
290 $widget->set_text ($$dataref);
294 sub handle_string_value {
295 my ($widget, $event, $dataref) = @_;
296 $$dataref = $widget->get_text ();
299 sub handle_nchar_value {
300 my ($widget, $event, $dataref, $minlen) = @_;
301 $_ = substr ($widget->get_text (), 0, $minlen);
302 $widget->set_text ($_);
306 sub gdk_color_from_str {
308 my ($rr, $gg, $bb) = (0, 0 ,0);
310 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
315 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
319 sub str_from_gdk_color {
321 my $rr = $color->red / 256;
322 my $gg = $color->green / 256;
323 my $bb = $color->blue / 256;
324 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
328 sub handle_color_value {
329 my ($widget, $event, $dataref) = @_;
330 my $newcol = $widget->get_color;
331 $$dataref = str_from_gdk_color ($newcol);
334 sub handle_selection_value {
335 my ($widget, $event, $dataref) = @_;
336 $$dataref = $widget->get_active;
339 sub get_rc_filename {
340 return $CONFIGDIR . $CONFIGRC;
343 sub set_rc_filename {
345 my @parts = split ('/', $fullname);
346 $CONFIGRC = $parts[$#parts];
347 $parts[$#parts] = '';
348 $CONFIGDIR = join ('/', @parts);
352 my ($mesg, $fatal) = @_;
353 if (defined($fatal) && $fatal eq 'die') {
354 die "$NAME: $mesg\n";
357 print "$NAME: $mesg\n";
363 my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
364 my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
365 $errordlg->set_title (_('Error message'));
370 sub claws_is_running {
371 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
373 error_dialog ($emsg);
377 sub check_claws_not_running {
378 my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
379 $socket .= "claws-mail-$<";
380 -S $socket and return claws_is_running ();
382 my $lockdir = "/tmp/claws-mail-$<";
386 $socket = "$lockdir/" . md5_hex ($_);
387 -S $socket and return claws_is_running ();
394 (defined($rcfile) && -f $rcfile) or do {
395 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
397 error_dialog ($emsg);
403 sub set_widget_hint {
405 my ($wdgt, $hint) = @_;
406 $wdgt->set_tooltip_text ($hint);
407 $wdgt->set_has_tooltip (TRUE);
411 sub set_widget_sens {
412 my ($wdgt, $versions) = @_;
413 my @ver = split(/,/, $versions);
415 $wdgt->set_sensitive (
416 version_greater_or_equal ($CLAWSV, $ver[0])
417 and version_greater_or_equal ($ver[1], $CLAWSV)
420 $wdgt->set_sensitive (version_greater_or_equal ($CLAWSV, $ver[0]));
424 # graphic element creation
426 sub new_check_button_for {
427 my ($hash, $key) = @_;
428 my $name = $$hash{$key}[NAME];
429 my $label = $$hash{$key}[LABEL];
431 my $hbox = Gtk2::HBox->new (FALSE, 5);
432 my $cb = Gtk2::CheckButton->new ($label);
433 $$hash{$key}[GUI] = $cb;
434 if (defined ($HPVALUE{$name})) {
435 $cb->set_active ($HPVALUE{$name} eq '1');
437 $cb->signal_connect (clicked => sub {
439 handle_bool_value ($w, $e, \$HPVALUE{$name});
441 set_widget_hint ($cb, $$hash{$key}[DESC]);
442 set_widget_sens ($cb, $$hash{$key}[CMVER]);
443 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
448 sub new_text_box_for_int {
449 my ($hash, $key) = @_;
450 my $name = $$hash{$key}[NAME];
451 my $label = $$hash{$key}[LABEL];
452 my @type = split (/,/, $$hash{$key}[TYPE]);
453 push (@type, 0), push (@type, 10000) unless ($#type > 0);
455 my $hbox = Gtk2::HBox->new (FALSE, 5);
456 my $glabel = Gtk2::Label->new ($label);
457 my $pagei = int (($type[2] - $type[1]) / 10);
458 my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
459 $gentry->set_numeric (TRUE);
460 $gentry->set_value ($HPVALUE{$name});
461 $$hash{$key}[GUI] = $gentry;
462 $gentry->signal_connect('value-changed' => sub {
464 handle_int_value ($w, $e, \$HPVALUE{$name});
466 set_widget_hint ($gentry, $$hash{$key}[DESC]);
467 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
468 $glabel->set_sensitive ($gentry->sensitive);
469 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
470 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
475 sub new_text_box_for_nchar {
476 my ($hash, $key) = @_;
477 my $name = $$hash{$key}[NAME];
478 my $label = $$hash{$key}[LABEL];
479 my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen
480 my $hbox = Gtk2::HBox->new (FALSE, 5);
481 my $glabel = Gtk2::Label->new ($label);
482 my $gentry = Gtk2::Entry->new ();
483 $gentry->set_max_length($type[2]) if defined ($type[2]);
484 $gentry->set_width_chars(int ($type[2]) + 2) if defined ($type[2]);
485 $gentry->set_text ($HPVALUE{$name});
486 $$hash{$key}[GUI] = $gentry;
487 $gentry->signal_connect('key-release-event' => sub {
489 handle_nchar_value ($w, $e, \$HPVALUE{$name}, $type[1]);
491 set_widget_hint ($gentry, $$hash{$key}[DESC]);
492 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
493 $glabel->set_sensitive ($gentry->sensitive);
494 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
495 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
500 sub new_color_button_for {
501 my ($hash, $key) = @_;
502 my $name = $$hash{$key}[NAME];
503 my $label = $$hash{$key}[LABEL];
505 my $col = gdk_color_from_str ($HPVALUE{$name});
506 my $hbox = Gtk2::HBox->new (FALSE, 5);
507 my $glabel = Gtk2::Label->new ($label);
508 my $button = Gtk2::ColorButton->new_with_color ($col);
509 $$hash{$key}[GUI] = $button;
510 $button->set_title ($label);
511 $button->set_relief ('none');
512 $button->signal_connect ('color-set' => sub {
514 handle_color_value ($w, $e, \$HPVALUE{$name});
516 set_widget_hint ($button, $$hash{$key}[DESC]);
517 set_widget_sens ($button, $$hash{$key}[CMVER]);
518 $glabel->set_sensitive ($button->sensitive);
519 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
520 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
525 sub new_selection_box_for {
526 my ($hash, $key) = @_;
527 my $name = $$hash{$key}[NAME];
528 my $label = $$hash{$key}[LABEL];
530 my $hbox = Gtk2::HBox->new (FALSE, 5);
531 my $glabel = Gtk2::Label->new ($label);
532 my $combo = Gtk2::ComboBox->new_text;
533 $$hash{$key}[GUI] = $combo;
534 my @options = split (';', $$hash{$key}[TYPE]);
535 foreach my $opt (@options) {
536 my ($index, $textkey) = split ('=', $opt);
537 $combo->insert_text ($index, $xl::s{$textkey});
539 $combo->signal_connect ('changed' => sub {
541 handle_selection_value ($w, $e, \$HPVALUE{$name});
543 $combo->set_active ($HPVALUE{$name});
544 set_widget_hint ($combo, $$hash{$key}[DESC]);
545 set_widget_sens ($combo, $$hash{$key}[CMVER]);
546 $glabel->set_sensitive ($combo->sensitive);
547 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
548 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
553 # more graphic helpers
556 my $hbox = Gtk2::HBox->new (FALSE, 5);
557 $hbox->set_border_width (PAGE_SPC);
558 foreach my $item (@_) {
559 $hbox->pack_start ($item, FALSE, FALSE, 0);
565 my $vbox = Gtk2::VBox->new (FALSE, 5);
566 $vbox->set_border_width (PAGE_SPC);
567 foreach my $item (@_) {
568 $vbox->pack_start ($item, FALSE, FALSE, 0);
573 sub new_vbox_pack_compact {
574 my $vbox = Gtk2::VBox->new (FALSE, 0);
575 $vbox->set_border_width (0);
576 foreach my $item (@_) {
577 $vbox->pack_start ($item, FALSE, FALSE, 0);
582 sub new_subpage_frame {
583 my ($box, $title, $notpacked) = @_;
584 my $frame = Gtk2::Frame->new ($title);
586 return new_vbox_pack ($frame) unless defined ($notpacked);
590 # preference maps and corresponding page creation subs
592 %pr::oth = ( # other preferences
594 'addressbook_use_editaddress_dialog',
595 $xl::s{l_oth_use_dlg},
596 $xl::s{h_oth_use_dlg},
603 'cache_max_mem_usage',
604 $xl::s{l_oth_max_use},
605 $xl::s{h_oth_max_use},
606 'int,0,262144', # 0 Kb - 256 Mb
612 'cache_min_keep_time',
613 $xl::s{l_oth_min_time},
614 $xl::s{h_oth_min_time},
615 'int,0,120', # 0 minutes - 2 hours
621 'use_networkmanager',
622 $xl::s{l_oth_use_netm},
623 $xl::s{h_oth_use_netm},
631 sub new_other_page() {
632 return new_vbox_pack (
635 new_check_button_for(\%pr::oth, 'use_dlg')),
636 $xl::s{ab_frame}, 'not-packed'),
639 new_text_box_for_int(\%pr::oth, 'max_use'),
640 new_text_box_for_int(\%pr::oth, 'min_time')),
641 $xl::s{mem_frame}, 'not-packed'),
644 new_check_button_for(\%pr::oth, 'use_netm')),
645 $xl::s{netm_frame}, 'not-packed')
649 %pr::gui = ( # gui bells and whistles
652 $xl::s{l_gui_b_unread},
653 $xl::s{h_gui_b_unread},
661 $xl::s{l_gui_no_markup},
662 $xl::s{h_gui_no_markup},
669 'enable_dotted_lines',
670 $xl::s{l_gui_dot_lines},
671 $xl::s{h_gui_dot_lines},
679 $xl::s{l_gui_h_scroll},
680 $xl::s{h_gui_h_scroll},
688 $xl::s{l_gui_swp_from},
689 $xl::s{h_gui_swp_from},
696 'folderview_vscrollbar_policy',
697 $xl::s{l_gui_v_scroll},
698 $xl::s{h_gui_v_scroll},
699 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
706 $xl::s{l_gui_from_show},
707 $xl::s{h_gui_from_show},
708 '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
714 'stripes_color_offset',
715 $xl::s{l_gui_strip_off},
716 $xl::s{h_gui_strip_off},
717 'int,0,40000', # no idea what this number means
723 'textview_cursor_visible',
724 $xl::s{l_gui_cursor_v},
725 $xl::s{h_gui_cursor_v},
732 'toolbar_detachable',
733 $xl::s{l_gui_toolbar_d},
734 $xl::s{h_gui_toolbar_d},
741 'use_stripes_everywhere',
742 $xl::s{l_gui_strip_all},
743 $xl::s{h_gui_strip_all},
750 'use_stripes_in_summaries',
751 $xl::s{l_gui_strip_sum},
752 $xl::s{h_gui_strip_sum},
760 $xl::s{l_gui_two_line_v},
761 $xl::s{h_gui_two_line_v},
768 'show_compose_margin',
769 $xl::s{l_gui_margin_co},
770 $xl::s{h_gui_margin_co},
777 'msgview_date_format',
778 $xl::s{l_gui_mview_date},
779 $xl::s{h_gui_mview_date},
786 'zero_replacement_char',
787 $xl::s{l_gui_zero_char},
788 $xl::s{h_gui_zero_char},
797 my $gf = Gtk2::VBox->new (FALSE, 5);
798 $gf->set_border_width (PAGE_SPC);
800 my $cb_dot_lines = new_check_button_for (\%pr::gui, 'dot_lines');
801 my $cb_toolbar_d = new_check_button_for (\%pr::gui, 'toolbar_d');
802 my $tb_zero_char = new_text_box_for_nchar (\%pr::gui, 'zero_char');
804 $gf->pack_start (new_subpage_frame (
806 new_check_button_for (\%pr::gui, 'strip_all'),
807 new_check_button_for (\%pr::gui, 'strip_sum'),
808 new_text_box_for_int (\%pr::gui, 'strip_off')),
809 $xl::s{stripes_frame}, 'not-packed'),
810 FALSE, FALSE, FRAME_SPC);
811 $gf->pack_start (new_subpage_frame (
813 new_check_button_for (\%pr::gui, 'b_unread'),
814 new_check_button_for (\%pr::gui, 'swp_from'),
815 new_check_button_for (\%pr::gui, 'two_linev'),
816 new_selection_box_for (\%pr::gui, 'from_show')),
817 $xl::s{mlist_frame}, 'not-packed'),
818 FALSE, FALSE, FRAME_SPC);
819 $gf->pack_start (new_subpage_frame (
821 new_check_button_for (\%pr::gui, 'cursor_v'),
822 new_check_button_for (\%pr::gui, 'mview_date')),
823 $xl::s{mview_frame}, 'not-packed'),
824 FALSE, FALSE, FRAME_SPC);
825 $gf->pack_start (new_subpage_frame (
827 new_check_button_for (\%pr::gui, 'no_markup'),
828 new_check_button_for (\%pr::gui, 'margin_co')),
829 $xl::s{compo_frame}, 'not-packed'),
830 FALSE, FALSE, FRAME_SPC);
831 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
832 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
833 $gf->pack_start (new_subpage_frame (
835 new_check_button_for (\%pr::gui, 'h_scroll'),
836 new_selection_box_for (\%pr::gui, 'v_scroll')),
837 $xl::s{sbar_frame}, 'not-packed'),
838 FALSE, FALSE, FRAME_SPC);
839 $gf->pack_start ($tb_zero_char, FALSE, FALSE, 0);
844 %pr::beh = ( # tweak some behaviour
847 $xl::s{l_beh_hover_t},
848 $xl::s{h_beh_hover_t},
849 'int,100,3000', # 0.1 seconds - 3 seconds
856 $xl::s{l_beh_dangerous},
857 $xl::s{h_beh_dangerous},
864 'respect_flowed_format',
865 $xl::s{l_beh_flowed},
866 $xl::s{h_beh_flowed},
873 'save_parts_readwrite',
874 $xl::s{l_beh_parts_rw},
875 $xl::s{h_beh_parts_rw},
882 'skip_ssl_cert_check',
883 $xl::s{l_beh_skip_ssl},
884 $xl::s{h_beh_skip_ssl},
891 'statusbar_update_step',
892 $xl::s{l_beh_up_step},
893 $xl::s{h_beh_up_step},
894 'int,1,200', # 1 item - 200 items
900 'thread_by_subject_max_age',
901 $xl::s{l_beh_thread_a},
902 $xl::s{h_beh_thread_a},
903 'int,1,30', # 1 day - 30 days
910 $xl::s{l_beh_unsafe_ssl},
911 $xl::s{h_beh_unsafe_ssl},
918 'utf8_instead_of_locale_for_broken_mail',
919 $xl::s{l_beh_use_utf8},
920 $xl::s{h_beh_use_utf8},
928 $xl::s{l_beh_warn_dnd},
929 $xl::s{h_beh_warn_dnd},
936 'outgoing_fallback_to_ascii',
937 $xl::s{l_beh_out_ascii},
938 $xl::s{h_beh_out_ascii},
945 'primary_paste_unselects',
946 $xl::s{l_beh_pp_unsel},
947 $xl::s{h_beh_pp_unsel},
954 'show_inline_attachments',
955 $xl::s{l_beh_inline_at},
956 $xl::s{h_beh_inline_at},
963 'address_search_wildcard',
964 $xl::s{l_beh_addr_swc},
965 $xl::s{h_beh_addr_sw1},
972 'folder_search_wildcard',
973 $xl::s{l_beh_fold_swc},
974 $xl::s{h_beh_fold_sw1},
982 sub new_behaviour_page() {
983 my $bf = Gtk2::VBox->new (FALSE, 5);
984 $bf->set_border_width (PAGE_SPC);
986 my $tb_up_step = new_text_box_for_int (\%pr::beh, 'up_step');
987 my $tb_thread_a = new_text_box_for_int (\%pr::beh, 'thread_a');
989 $bf->pack_start (new_subpage_frame (
991 new_text_box_for_int (\%pr::beh, 'hover_t'),
992 new_check_button_for (\%pr::beh, 'warn_dnd')),
993 $xl::s{dnd_frame}, 'not-packed'),
994 FALSE, FALSE, FRAME_SPC);
995 $bf->pack_start (new_subpage_frame (
997 new_check_button_for (\%pr::beh, 'skip_ssl'),
998 new_check_button_for (\%pr::beh, 'unsafe_ssl')),
999 $xl::s{ssl_frame}, 'not-packed'),
1000 FALSE, FALSE, FRAME_SPC);
1001 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
1002 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
1003 $bf->pack_start (new_subpage_frame (
1005 new_check_button_for (\%pr::beh, 'flowed'),
1006 new_check_button_for (\%pr::beh, 'parts_rw'),
1007 new_check_button_for (\%pr::beh, 'use_utf8'),
1008 new_check_button_for (\%pr::beh, 'dangerous'),
1009 new_check_button_for (\%pr::beh, 'out_ascii'),
1010 new_check_button_for (\%pr::beh, 'pp_unsel'),
1011 new_check_button_for (\%pr::beh, 'inline_at')),
1012 $xl::s{msgs_frame}, 'not-packed'),
1013 FALSE, FALSE, FRAME_SPC);
1014 $bf->pack_start (new_subpage_frame (
1016 new_check_button_for (\%pr::beh, 'addr_swc'),
1017 new_check_button_for (\%pr::beh, 'fold_swc')),
1018 $xl::s{swc_frame}, 'not-packed'),
1019 FALSE, FALSE, FRAME_SPC);
1023 %pr::col = ( # a variety of colours
1026 $xl::s{l_col_emphasis},
1027 $xl::s{h_col_emphasis},
1035 $xl::s{l_col_log_err},
1036 $xl::s{h_col_log_err},
1044 $xl::s{l_col_log_in},
1045 $xl::s{h_col_log_in},
1053 $xl::s{l_col_log_msg},
1054 $xl::s{h_col_log_msg},
1062 $xl::s{l_col_log_out},
1063 $xl::s{h_col_log_out},
1071 $xl::s{l_col_log_warn},
1072 $xl::s{h_col_log_warn},
1080 $xl::s{l_col_diff_add},
1081 $xl::s{h_col_diff_add},
1088 'diff_deleted_color',
1089 $xl::s{l_col_diff_del},
1090 $xl::s{h_col_diff_del},
1098 $xl::s{l_col_diff_hunk},
1099 $xl::s{h_col_diff_hunk},
1107 sub new_colours_page() {
1108 return new_vbox_pack (
1111 new_color_button_for (\%pr::col, 'emphasis')),
1112 $xl::s{msgview_frame}, 'not-packed'),
1115 new_color_button_for (\%pr::col, 'log_err'),
1116 new_color_button_for (\%pr::col, 'log_in'),
1117 new_color_button_for (\%pr::col, 'log_msg'),
1118 new_color_button_for (\%pr::col, 'log_out'),
1119 new_color_button_for (\%pr::col, 'log_warn')),
1120 $xl::s{log_frame}, 'not-packed'),
1123 new_color_button_for (\%pr::col, 'diff_add'),
1124 new_color_button_for (\%pr::col, 'diff_del'),
1125 new_color_button_for (\%pr::col, 'diff_hunk')),
1126 $xl::s{diff_frame}, 'not-packed')
1130 %pr::win = ( # tweak window positions and/or sizes
1135 'int,0,3000', # 0 pixels - 3000 pixels
1144 'int,0,3000', # 0 pixels - 3000 pixels
1153 'int,0,3000', # 0 pixels - 3000 pixels
1162 'int,0,3000', # 0 pixels - 3000 pixels
1168 'mainwin_maximised',
1169 $xl::s{l_win_main_mx},
1170 $xl::s{h_win_main_mx},
1177 'mainwin_fullscreen',
1178 $xl::s{l_win_main_fs},
1179 $xl::s{h_win_main_fs},
1186 'main_messagewin_x',
1189 'int,0,3000', # 0 pixels - 3000 pixels
1195 'main_messagewin_y',
1198 'int,0,3000', # 0 pixels - 3000 pixels
1207 'int,0,3000', # 0 pixels - 3000 pixels
1213 'messagewin_height',
1216 'int,0,3000', # 0 pixels - 3000 pixels
1225 'int,0,3000', # 0 pixels - 3000 pixels
1234 'int,0,3000', # 0 pixels - 3000 pixels
1243 'int,0,3000', # 0 pixels - 3000 pixels
1249 'receivewin_height',
1252 'int,0,3000', # 0 pixels - 3000 pixels
1261 'int,0,3000', # 0 pixels - 3000 pixels
1270 'int,0,3000', # 0 pixels - 3000 pixels
1276 'folderitemwin_width',
1279 'int,0,3000', # 0 pixels - 3000 pixels
1285 'folderitemwin_height',
1288 'int,0,3000', # 0 pixels - 3000 pixels
1294 'folderselwin_width',
1297 'int,0,3000', # 0 pixels - 3000 pixels
1303 'folderselwin_height',
1306 'int,0,3000', # 0 pixels - 3000 pixels
1315 'int,0,3000', # 0 pixels - 3000 pixels
1324 'int,0,3000', # 0 pixels - 3000 pixels
1330 'addressbookwin_width',
1333 'int,0,3000', # 0 pixels - 3000 pixels
1339 'addressbookwin_height',
1342 'int,0,3000', # 0 pixels - 3000 pixels
1348 'addressbookeditpersonwin_width',
1351 'int,0,3000', # 0 pixels - 3000 pixels
1357 'addressbookeditpersonwin_height',
1360 'int,0,3000', # 0 pixels - 3000 pixels
1366 'addressbookeditgroupwin_width',
1369 'int,0,3000', # 0 pixels - 3000 pixels
1375 'addressbookeditgroupwin_height',
1378 'int,0,3000', # 0 pixels - 3000 pixels
1384 'addressaddwin_width',
1387 'int,0,3000', # 0 pixels - 3000 pixels
1393 'addressaddwin_height',
1396 'int,0,3000', # 0 pixels - 3000 pixels
1402 'addressbook_folderselwin_width',
1405 'int,0,3000', # 0 pixels - 3000 pixels
1411 'addressbook_folderselwin_height',
1414 'int,0,3000', # 0 pixels - 3000 pixels
1420 'editaccountwin_width',
1423 'int,0,3000', # 0 pixels - 3000 pixels
1429 'editaccountwin_height',
1432 'int,0,3000', # 0 pixels - 3000 pixels
1438 'accountswin_width',
1441 'int,0,3000', # 0 pixels - 3000 pixels
1447 'accountswin_height',
1450 'int,0,3000', # 0 pixels - 3000 pixels
1456 'filteringwin_width',
1459 'int,0,3000', # 0 pixels - 3000 pixels
1465 'filteringwin_height',
1468 'int,0,3000', # 0 pixels - 3000 pixels
1474 'filteringactionwin_width',
1477 'int,0,3000', # 0 pixels - 3000 pixels
1483 'filteringactionwin_height',
1486 'int,0,3000', # 0 pixels - 3000 pixels
1492 'filtering_debugwin_width',
1495 'int,0,3000', # 0 pixels - 3000 pixels
1501 'filtering_debugwin_height',
1504 'int,0,3000', # 0 pixels - 3000 pixels
1513 'int,0,3000', # 0 pixels - 3000 pixels
1519 'matcherwin_height',
1522 'int,0,3000', # 0 pixels - 3000 pixels
1531 'int,0,3000', # 0 pixels - 3000 pixels
1540 'int,0,3000', # 0 pixels - 3000 pixels
1546 'templateswin_width',
1549 'int,0,3000', # 0 pixels - 3000 pixels
1555 'templateswin_height',
1558 'int,0,3000', # 0 pixels - 3000 pixels
1567 'int,0,3000', # 0 pixels - 3000 pixels
1573 'actionswin_height',
1576 'int,0,3000', # 0 pixels - 3000 pixels
1585 'int,0,3000', # 0 pixels - 3000 pixels
1594 'int,0,3000', # 0 pixels - 3000 pixels
1603 'int,0,3000', # 0 pixels - 3000 pixels
1609 'pluginswin_height',
1612 'int,0,3000', # 0 pixels - 3000 pixels
1621 'int,0,3000', # 0 pixels - 3000 pixels
1630 'int,0,3000', # 0 pixels - 3000 pixels
1636 'print_previewwin_width',
1639 'int,0,3000', # 0 pixels - 3000 pixels
1645 'print_previewwin_height',
1648 'int,0,3000', # 0 pixels - 3000 pixels
1655 sub new_winpos_subpage_main() {
1656 return new_subpage_frame (
1657 new_vbox_pack_compact (
1659 new_text_box_for_int (\%pr::win, 'main_x'),
1660 new_text_box_for_int (\%pr::win, 'main_y')),
1662 new_text_box_for_int (\%pr::win, 'main_w'),
1663 new_text_box_for_int (\%pr::win, 'main_h')),
1665 new_check_button_for (\%pr::win, 'main_fs'),
1666 new_check_button_for (\%pr::win, 'main_mx'))),
1671 sub new_winpos_subpage_msgs() {
1672 return new_subpage_frame (
1673 new_vbox_pack_compact (
1675 new_text_box_for_int (\%pr::win, 'msgs_x'),
1676 new_text_box_for_int (\%pr::win, 'msgs_y')),
1678 new_text_box_for_int (\%pr::win, 'msgs_w'),
1679 new_text_box_for_int (\%pr::win, 'msgs_h'))),
1684 sub new_winpos_subpage_sendrecv() {
1685 return new_vbox_pack (
1688 new_text_box_for_int (\%pr::win, 'send_w'),
1689 new_text_box_for_int (\%pr::win, 'send_h')),
1690 _('Send window'), 'not-packed'),
1693 new_text_box_for_int (\%pr::win, 'recv_w'),
1694 new_text_box_for_int (\%pr::win, 'recv_h')),
1695 _('Receive window'), 'not-packed')
1699 sub new_winpos_subpage_fold() {
1700 return new_vbox_pack (
1702 new_vbox_pack_compact (
1704 new_text_box_for_int (\%pr::win, 'fold_x'),
1705 new_text_box_for_int (\%pr::win, 'fold_y')),
1707 new_text_box_for_int (\%pr::win, 'fold_w'),
1708 new_text_box_for_int (\%pr::win, 'fold_h'))),
1709 _('Folder window'), 'not-packed'),
1712 new_text_box_for_int (\%pr::win, 'fsel_w'),
1713 new_text_box_for_int (\%pr::win, 'fsel_h')),
1714 _('Folder selection window'), 'not-packed')
1718 sub new_winpos_subpage_addrbook() {
1719 return new_vbox_pack (
1722 new_text_box_for_int (\%pr::win, 'addr_w'),
1723 new_text_box_for_int (\%pr::win, 'addr_h')),
1724 _('Addressbook main window'), 'not-packed'),
1727 new_text_box_for_int (\%pr::win, 'adep_w'),
1728 new_text_box_for_int (\%pr::win, 'adep_h')),
1729 _('Edit person window'), 'not-packed'),
1732 new_text_box_for_int (\%pr::win, 'adeg_w'),
1733 new_text_box_for_int (\%pr::win, 'adeg_h')),
1734 _('Edit group window'), 'not-packed'),
1737 new_text_box_for_int (\%pr::win, 'adda_w'),
1738 new_text_box_for_int (\%pr::win, 'adda_h')),
1739 _('Add address window'), 'not-packed'),
1742 new_text_box_for_int (\%pr::win, 'addf_w'),
1743 new_text_box_for_int (\%pr::win, 'addf_h')),
1744 _('Folder select window'), 'not-packed')
1748 sub new_winpos_subpage_accounts() {
1749 return new_vbox_pack (
1752 new_text_box_for_int (\%pr::win, 'acco_w'),
1753 new_text_box_for_int (\%pr::win, 'acco_h')),
1754 _('Accounts window'), 'not-packed'),
1757 new_text_box_for_int (\%pr::win, 'acce_w'),
1758 new_text_box_for_int (\%pr::win, 'acce_h')),
1759 _('Edit account window'), 'not-packed')
1763 sub new_winpos_subpage_filtering() {
1764 return new_vbox_pack (
1767 new_text_box_for_int (\%pr::win, 'filt_w'),
1768 new_text_box_for_int (\%pr::win, 'filt_h')),
1769 _('Filtering window'), 'not-packed'),
1772 new_text_box_for_int (\%pr::win, 'fila_w'),
1773 new_text_box_for_int (\%pr::win, 'fila_h')),
1774 _('Filtering actions window'), 'not-packed'),
1777 new_text_box_for_int (\%pr::win, 'fild_w'),
1778 new_text_box_for_int (\%pr::win, 'fild_h')),
1779 _('Filtering debug window'), 'not-packed'),
1782 new_text_box_for_int (\%pr::win, 'matc_w'),
1783 new_text_box_for_int (\%pr::win, 'matc_h')),
1784 _('Matcher window'), 'not-packed')
1788 sub new_winpos_subpage_prefs() {
1789 return new_vbox_pack (
1792 new_text_box_for_int (\%pr::win, 'pref_w'),
1793 new_text_box_for_int (\%pr::win, 'pref_h')),
1794 _('Preferences window'), 'not-packed'),
1797 new_text_box_for_int (\%pr::win, 'temp_w'),
1798 new_text_box_for_int (\%pr::win, 'temp_h')),
1799 _('Templates window'), 'not-packed'),
1802 new_text_box_for_int (\%pr::win, 'acti_w'),
1803 new_text_box_for_int (\%pr::win, 'acti_h')),
1804 _('Actions window'), 'not-packed'),
1807 new_text_box_for_int (\%pr::win, 'tags_w'),
1808 new_text_box_for_int (\%pr::win, 'tags_h')),
1809 _('Tags window'), 'not-packed'),
1812 new_text_box_for_int (\%pr::win, 'plug_w'),
1813 new_text_box_for_int (\%pr::win, 'plug_h')),
1814 _('Plugins window'), 'not-packed')
1818 sub new_winpos_subpage_misc() {
1819 return new_vbox_pack (
1822 new_text_box_for_int (\%pr::win, 'logw_w'),
1823 new_text_box_for_int (\%pr::win, 'logw_h')),
1824 _('Log window'), 'not-packed'),
1827 new_text_box_for_int (\%pr::win, 'prin_w'),
1828 new_text_box_for_int (\%pr::win, 'prin_h')),
1829 _('Print preview window'), 'not-packed'),
1832 new_text_box_for_int (\%pr::win, 'sour_w'),
1833 new_text_box_for_int (\%pr::win, 'sour_h')),
1834 _('View source window'), 'not-packed')
1838 sub new_winpos_page() {
1839 my $winbook = Gtk2::Notebook->new;
1840 $winbook->set_tab_pos ('right');
1841 $winbook->append_page (new_winpos_subpage_main, _('Main'));
1842 $winbook->append_page (new_winpos_subpage_msgs, _('Message'));
1843 $winbook->append_page (new_winpos_subpage_sendrecv, _('Send/Receive'));
1844 $winbook->append_page (new_winpos_subpage_fold, _('Folder'));
1845 $winbook->append_page (new_winpos_subpage_addrbook, _('Addressbook'));
1846 $winbook->append_page (new_winpos_subpage_accounts, _('Accounts'));
1847 $winbook->append_page (new_winpos_subpage_filtering, _('Filtering'));
1848 $winbook->append_page (new_winpos_subpage_prefs, _('Preferences'));
1849 $winbook->append_page (new_winpos_subpage_misc, _('Other'));
1854 sub print_version() {
1855 print $xl::s{about_title} . "\n";
1856 print $xl::s{about_version} . " $VERSION\n";
1857 print "Perl-GLib " . $Glib::VERSION;
1858 # version info stuff appeared in 1.040
1859 if ($Glib::VERSION >= 1.040) {
1860 print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
1861 . _(", running with ") . join(".", &Glib::major_version,
1862 &Glib::minor_version, &Glib::micro_version);
1865 print "Perl-GTK2 " . $Gtk2::VERSION;
1866 if ($Gtk2::VERSION >= 1.040) {
1867 print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1868 . _(", running with ") . join(".", &Gtk2::major_version,
1869 &Gtk2::minor_version, &Gtk2::micro_version);
1872 my $clawsver = ($CLAWSV eq "") ?
1873 _("was not found!") :
1874 (_("returned version ") . $CLAWSV);
1875 print "Claws Mail " . $clawsver . "\n";
1878 # the command line help
1880 my $line = '-' x length ($xl::s{about_title}) . "\n";
1882 print $xl::s{about_title} . "\n";
1884 print _("Syntax:\n");
1885 print _(" clawsker [options]\n");
1886 print _("Options:\n");
1887 print _(" --help Prints this help screen.\n");
1888 print _(" --version Prints version infos.\n");
1889 print _(" --verbose More messages on standard output.\n");
1890 print _(" --alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1891 print _(" --clawsrc <file> Uses <file> as full resource name.\n");
1894 # handle errors which don't allow to run
1895 sub command_line_fatal {
1897 my $emsg = $xl::s{e_error} . $reason;
1898 error_dialog ($emsg);
1899 log_message ("$emsg", 'die');
1902 # parse the command line
1903 sub parse_command_line {
1904 $CLAWSV = get_claws_version ();
1906 while (defined($ARGV[$arg])) {
1920 /--use-claws-version/ && do {
1922 command_line_fatal ("required version")
1923 unless defined($ARGV[$arg]);
1924 command_line_fatal ("required a dotted numeric value")
1925 unless ($ARGV[$arg] =~ /[\d\.]+/);
1926 $CLAWSV = $ARGV[$arg];
1929 /--alternate-config-dir/ && do {
1931 command_line_fatal ($xl::s{e_requireddir})
1932 unless defined($ARGV[$arg]);
1933 command_line_fatal ($xl::s{e_notadir})
1934 unless -d $ARGV[$arg];
1935 $CONFIGDIR = $ARGV[$arg];
1937 unless ($CONFIGDIR =~ /.*\/$/);
1938 $ALTCONFIGDIR = TRUE;
1943 command_line_fatal($xl::s{e_requiredfile})
1944 unless defined($ARGV[$arg]);
1945 command_line_fatal($xl::s{e_notafile})
1946 unless -f $ARGV[$arg];
1947 set_rc_filename ($ARGV[$arg]);
1950 /.*/ && command_line_fatal (
1951 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1955 # eveything continues...
1959 # update the hidden preferences status from loaded values
1960 sub init_hidden_preferences {
1961 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1962 foreach my $key (keys %$hash) {
1963 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1969 # load current status from disc
1970 sub load_preferences {
1971 my $rc = get_rc_filename ();
1972 log_message ("Loading preferences from $rc\n");
1973 return FALSE unless check_rc_file ($rc);
1974 return FALSE unless check_claws_not_running ();
1978 if (/^([8a-z_]+)=(.*)$/) {
1979 $PREFS{$1} = decode('UTF-8', $2);
1986 # save current preferences to disc
1987 sub save_preferences {
1988 my $rc = get_rc_filename ();
1989 log_message ("Saving preferences to $rc\n");
1990 return FALSE unless check_rc_file ($rc);
1991 return FALSE unless check_claws_not_running ();
1992 my $rcbak = "$rc.backup";
1993 rename ($rc, $rcbak);
1995 open (RCB, "<$rcbak");
1998 if (/^([8a-z_]+)=(.*)$/) {
1999 if (defined($HPVALUE{$1})) {
2000 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
2003 print RCF $_ . "\n";
2007 print RCF $_ . "\n";
2017 my $nb = Gtk2::Notebook->new;
2019 $nb->append_page (new_behaviour_page (), $xl::s{tab_behaviour});
2020 $nb->append_page (new_colours_page (), $xl::s{tab_colours});
2021 $nb->append_page (new_gui_page (), $xl::s{tab_gui});
2022 $nb->append_page (new_other_page (), $xl::s{tab_other});
2023 $nb->append_page (new_winpos_page (), $xl::s{tab_winpos});
2028 # create an about dialog
2029 sub new_about_dialog {
2031 my $title = $xl::s{about_title};
2032 my $lic = $xl::s{about_license};
2033 my $vers = $xl::s{about_version} . " $VERSION";
2035 "This program is free software: you can redistribute it and/or modify
2036 it under the terms of the GNU General Public License as published by
2037 the Free Software Foundation, either version 3 of the License, or
2038 (at your option) any later version.
2040 This program is distributed in the hope that it will be useful,
2041 but WITHOUT ANY WARRANTY; without even the implied warranty of
2042 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2043 GNU General Public License for more details.
2045 You should have received a copy of the GNU General Public License
2046 along with this program. If not, see <http://www.gnu.org/licenses/>.";
2047 my $year = "2007-2014";
2048 my $holder = "Ricardo Mones <ricardo\@mones.org>";
2049 my $url = "http://www.claws-mail.org/clawsker.php";
2051 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
2052 [qw/modal destroy-with-parent/],
2054 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
2055 . "<span size=\"large\">$vers</span>\n\n"
2056 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
2057 . "<span>Copyright $year by $holder</span>\n\n"
2058 . "<span size=\"large\">$lic</span>\n\n"
2059 . "<span size=\"small\">$license</span>");
2060 $dialog->set_title ($xl::s{about});
2065 # create buttons box
2066 sub new_button_box {
2067 my ($parent, $adlg) = @_;
2068 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
2069 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
2070 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
2071 # disable button until is really implemented
2072 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
2073 my $hbox = Gtk2::HBox->new (FALSE, 5);
2075 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
2076 $b_apply->signal_connect (clicked => sub { save_preferences ($parent) });
2077 # $b_undo->signal_connect (clicked => sub { undo_current_changes });
2078 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
2080 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
2081 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
2082 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
2083 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
2089 $main_window = Gtk2::Window->new ('toplevel');
2090 exit unless parse_command_line ();
2091 exit unless load_preferences ();
2092 exit unless init_hidden_preferences ();
2094 my $box = Gtk2::VBox->new (FALSE, 5);
2095 $box->set_border_width(3);
2096 my $about = new_about_dialog ();
2097 $box->pack_start (new_notebook (), FALSE, FALSE, 0);
2098 $box->pack_end (new_button_box ($main_window, $about), FALSE, FALSE, 0);
2099 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
2100 $main_window->set_title ($xl::s{win_title});
2101 $main_window->add ($box);
2102 $main_window->show_all;