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.
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 in compose window'),
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 compose 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'),
134 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
135 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.'),
136 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
137 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
138 l_beh_flowed => _('Respect format=flowed in messages'),
139 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.'),
140 l_beh_parts_rw => _('Allow writable temporary files'),
141 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
142 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
143 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
144 l_beh_up_step => _('Progress bar update step (items)'),
145 h_beh_up_step => _('Update stepping in progress bars.'),
146 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
147 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
148 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
149 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
150 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
151 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
152 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
153 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
154 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
155 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
156 l_beh_pp_unsel => _('Primary paste unselects selection'),
157 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
158 l_beh_inline_at => _('Show inline attachments'),
159 h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
160 l_beh_addr_swc => _('Address search in compose window matches any'),
161 h_beh_addr_swc => _('On Tab-key completion, address text will match any part of the string or only the from the start'),
162 l_beh_fold_swc => _('Folder search in folder selector matches any'),
163 h_beh_fold_swc => _('On folder name completion text will match any part of the string or only from the start'),
165 l_col_emphasis => _('X-Mailer header'),
166 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
167 l_col_log_err => _('Error messages'),
168 h_col_log_err => _('Colour for error messages in log window.'),
169 l_col_log_in => _('Server messages'),
170 h_col_log_in => _('Colour for messages received from servers in log window.'),
171 l_col_log_msg => _('Standard messages'),
172 h_col_log_msg => _('Colour for messages in log window.'),
173 l_col_log_out => _('Client messages'),
174 h_col_log_out => _('Colour for messages sent to servers in log window.'),
175 l_col_log_warn => _('Warnings'),
176 h_col_log_warn => _('Colour for warning messages in log window.'),
178 l_col_diff_add => _('Added lines'),
179 h_col_diff_add => _('Colour for added lines in patches.'),
180 l_col_diff_del => _('Deleted lines'),
181 h_col_diff_del => _('Colour for deleted lines in patches.'),
182 l_col_diff_hunk => _('Hunk lines'),
183 h_col_diff_hunk => _('Color for hunk headers in patches.'),
185 l_win_x => _('X position'),
186 h_win_x => _('X coordinate for window\'s top-left corner.'),
187 l_win_y => _('Y position'),
188 h_win_y => _('Y coordinate for window\'s top-left corner.'),
189 l_win_w => _('Width'),
190 h_win_w => _('Window\'s width in pixels.'),
191 l_win_h => _('Height'),
192 h_win_h => _('Window\'s height in pixels.'),
194 l_win_main_mx => _('Maximized'),
195 h_win_main_mx => _('Changes window maximized status.'),
196 l_win_main_fs => _('Full-screen'),
197 h_win_main_fs => _('Changes full screen status.'),
199 e_error => _('Error: '),
200 e_noclawsrc => _('resource file for Claws Mail was not found.'),
201 e_running => _('seems Claws Mail is currently running, close it first.'),
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 (_('Clawsker error'));
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 _(" -h|--help Prints this help screen.\n");
1888 print _(" -v|--version Prints version infos.\n");
1889 print _(" -b|--verbose More messages on standard output.\n");
1890 print _(" -a|--alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1891 print _(" -c|--clawsrc <file> Uses <file> as full resource name.\n");
1894 sub parse_command_line {
1896 $CLAWSV = get_claws_version ();
1898 GetOptions('h|help' => sub { print_help (); $cont = FALSE },
1899 'v|version' => sub { print_version (); $cont = FALSE },
1900 'b|verbose' => sub { $VERBOSE = TRUE },
1901 'u|use-claws-version=s' => \&opt_use_claws_version,
1902 'a|alternate-config-dir=s' => \&opt_alternate_config_dir,
1903 'r|clawsrc=s' => \&opt_clawsrc)
1904 or die _("try -h or --help for syntax.\n");
1907 my $msg = _("Error in options: {msg}\n", msg => $@);
1908 if (defined $ENV{'DISPLAY'} and $ENV{'DISPLAY'} ne '') {
1909 eval { Gtk2->init };
1910 error_dialog ($msg) unless $@;
1917 sub opt_use_claws_version {
1918 my ($name, $value) = @_;
1919 die _("Error: {opt} requires a dotted numeric value argument\n", opt => $name)
1920 unless ($value =~ /^[\d\.]+$/);
1924 sub opt_alternate_config_dir {
1925 my ($name, $value) = @_;
1926 die _("Error: '{dir}' is not a directory or does not exist\n", dir => $value)
1928 $CONFIGDIR = $value;
1929 $CONFIGDIR .= "/" unless ($CONFIGDIR =~ /.*\/$/);
1930 $ALTCONFIGDIR = TRUE;
1934 my ($name, $value) = @_;
1935 die _("Error: '{value}' is not a file or does not exist", value => $value)
1937 set_rc_filename ($value);
1940 # update the hidden preferences status from loaded values
1941 sub init_hidden_preferences {
1942 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1943 foreach my $key (keys %$hash) {
1944 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1950 # load current status from disc
1951 sub load_preferences {
1952 my $rc = get_rc_filename ();
1953 log_message ("Loading preferences from $rc\n");
1954 return FALSE unless check_rc_file ($rc);
1955 return FALSE unless check_claws_not_running ();
1959 if (/^([8a-z_]+)=(.*)$/) {
1960 $PREFS{$1} = decode('UTF-8', $2);
1967 # save current preferences to disc
1968 sub save_preferences {
1969 my $rc = get_rc_filename ();
1970 log_message ("Saving preferences to $rc\n");
1971 return FALSE unless check_rc_file ($rc);
1972 return FALSE unless check_claws_not_running ();
1973 my $rcbak = "$rc.backup";
1974 rename ($rc, $rcbak);
1976 open (RCB, "<$rcbak");
1979 if (/^([8a-z_]+)=(.*)$/) {
1980 if (defined($HPVALUE{$1})) {
1981 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1984 print RCF $_ . "\n";
1988 print RCF $_ . "\n";
1998 my $nb = Gtk2::Notebook->new;
2000 $nb->append_page (new_behaviour_page (), $xl::s{tab_behaviour});
2001 $nb->append_page (new_colours_page (), $xl::s{tab_colours});
2002 $nb->append_page (new_gui_page (), $xl::s{tab_gui});
2003 $nb->append_page (new_other_page (), $xl::s{tab_other});
2004 $nb->append_page (new_winpos_page (), $xl::s{tab_winpos});
2009 # create an about dialog
2010 sub new_about_dialog {
2012 my $title = $xl::s{about_title};
2013 my $lic = $xl::s{about_license};
2014 my $vers = $xl::s{about_version} . " $VERSION";
2016 "This program is free software: you can redistribute it and/or modify
2017 it under the terms of the GNU General Public License as published by
2018 the Free Software Foundation, either version 3 of the License, or
2019 (at your option) any later version.
2021 This program is distributed in the hope that it will be useful,
2022 but WITHOUT ANY WARRANTY; without even the implied warranty of
2023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2024 GNU General Public License for more details.
2026 You should have received a copy of the GNU General Public License
2027 along with this program. If not, see <http://www.gnu.org/licenses/>.";
2028 my $year = "2007-2014";
2029 my $holder = "Ricardo Mones <ricardo\@mones.org>";
2030 my $url = "http://www.claws-mail.org/clawsker.php";
2032 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
2033 [qw/modal destroy-with-parent/],
2035 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
2036 . "<span size=\"large\">$vers</span>\n\n"
2037 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
2038 . "<span>Copyright $year by $holder</span>\n\n"
2039 . "<span size=\"large\">$lic</span>\n\n"
2040 . "<span size=\"small\">$license</span>");
2041 $dialog->set_title ($xl::s{about});
2046 # create buttons box
2047 sub new_button_box {
2048 my ($parent, $adlg) = @_;
2049 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
2050 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
2051 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
2052 # disable button until is really implemented
2053 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
2054 my $hbox = Gtk2::HBox->new (FALSE, 5);
2056 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
2057 $b_apply->signal_connect (clicked => sub { save_preferences ($parent) });
2058 # $b_undo->signal_connect (clicked => sub { undo_current_changes });
2059 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
2061 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
2062 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
2063 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
2064 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
2070 exit unless parse_command_line ();
2072 $main_window = Gtk2::Window->new ('toplevel');
2073 exit unless load_preferences ();
2074 exit unless init_hidden_preferences ();
2076 my $box = Gtk2::VBox->new (FALSE, 5);
2077 $box->set_border_width(3);
2078 my $about = new_about_dialog ();
2079 $box->pack_start (new_notebook (), FALSE, FALSE, 0);
2080 $box->pack_end (new_button_box ($main_window, $about), FALSE, FALSE, 0);
2081 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
2082 $main_window->set_title ($xl::s{win_title});
2083 $main_window->add ($box);
2084 $main_window->show_all;