3 # Clawsker :: A Claws Mail Tweaker
7 use Glib qw(TRUE FALSE);
9 use POSIX qw(setlocale);
12 use Digest::MD5 qw(md5_hex);
14 my $NAME = 'clawsker';
15 my $PREFIX = '@PREFIX@';
16 my $LIBDIR = '@LIBDIR@';
17 my $VERSION = '@VERSION@';
20 my $main_window = undef;
22 my $locale = (defined($ENV{LC_MESSAGES}) ? $ENV{LC_MESSAGES} : $ENV{LANG});
23 $locale = "C" unless defined($locale);
24 setlocale (LC_ALL, $locale);
25 bindtextdomain ($NAME, sprintf ('%s/share/locale', $PREFIX));
28 my $SHOWHINTS = FALSE;
29 $SHOWHINTS = TRUE if ($Gtk2::VERSION >= 1.040 and Gtk2->CHECK_VERSION (2, 12, 0));
34 my $xla = gettext ($str);
35 if (scalar(keys(%par)) > 0) {
36 foreach my $key (keys %par) {
37 $xla =~ s/\{$key\}/$par{$key}/g;
40 return decode_utf8($xla);
45 win_title => _('Claws Mail Hidden Preferences'),
46 about => _('About...'),
47 about_title => _('Clawsker :: A Claws Mail Tweaker'),
48 about_license => _('License:'),
49 about_version => _('Version:'),
51 tab_colours => _('Colours'),
52 tab_behaviour => _('Behaviour'),
54 tab_other => _('Other'),
55 tab_winpos => _('Windows'),
57 ab_frame => _('Addressbook'),
58 mem_frame => _('Memory'),
59 msgview_frame => _('Message View'),
60 log_frame => _('Log window'),
61 dnd_frame => _('Drag \'n\' drop'),
62 ssl_frame => _('Secure Sockets Layer'),
63 msgs_frame => _('Messages'),
64 swc_frame => _('Completion'),
65 stripes_frame => _('Coloured stripes'),
66 sbar_frame => _('Scroll bars'),
67 mlist_frame => _('Message List'),
68 mview_frame => _('Message View'),
69 compo_frame => _('Compose window'),
70 netm_frame => _('NetworkManager'),
71 diff_frame => _('Viewing patches'),
73 l_oth_use_dlg => _('Use detached address book edit dialogue'),
74 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.'),
75 l_oth_max_use => _('Maximum memory for message cache (kB)'),
76 h_oth_max_use => _('The maximum amount of memory to use to cache messages, in kilobytes.'),
77 l_oth_min_time => _('Minimun time for cache elements (minutes)'),
78 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.'),
79 l_oth_use_netm => _('Use NetworkManager'),
80 h_oth_use_netm => _('Use NetworkManager to switch offline automatically.'),
82 l_gui_b_unread => _('Show unread messages with bold font'),
83 h_gui_b_unread => _('Show unread messages in the Message List using a bold font.'),
84 l_gui_no_markup => _('Don\'t use markup in compose window'),
85 h_gui_no_markup => _('Don\'t use bold and italic text in Compose dialogue\'s account selector.'),
86 l_gui_dot_lines => _('Use dotted lines in tree view components'),
87 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.'),
88 l_gui_h_scroll => _('Enable horizontal scrollbar'),
89 h_gui_h_scroll => _('Enable the horizontal scrollbar in the Message List.'),
90 l_gui_swp_from => _('Display To column instead From column in Sent folder'),
91 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.'),
92 l_gui_v_scroll => _('Folder List scrollbar behaviour'),
93 h_gui_v_scroll => _('Specify the policy of vertical scrollbar of Folder List: show always, automatic or hide always.'),
94 l_gui_v_scroll_show => _('Show always'),
95 l_gui_v_scroll_auto => _('Automatic'),
96 l_gui_v_scroll_hide => _('Hide always'),
97 l_gui_from_show => _('From column displays'),
98 h_gui_from_show => _('Selects the data displayed in the From column of the Message List: name, address or both'),
99 l_gui_from_show_name => _('Name only'),
100 l_gui_from_show_addr => _('Address only'),
101 l_gui_from_show_both => _('Both name and address'),
102 l_gui_strip_off => _('Coloured lines contrast'),
103 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.'),
104 l_gui_cursor_v => _('Show cursor'),
105 h_gui_cursor_v => _('Display the cursor in the Message View.'),
106 l_gui_toolbar_d => _('Detachable toolbars'),
107 h_gui_toolbar_d => _('Show handles in the toolbars.'),
108 l_gui_strip_all => _('Use stripes in all tree view components'),
109 h_gui_strip_all => _('Enable alternately coloured lines in all tree view components.'),
110 l_gui_strip_sum => _('Use stripes in Folder List and Message List'),
111 h_gui_strip_sum => _('Enable alternately coloured lines in Message List and Folder List.'),
112 l_gui_two_line_v => _('2 lines per Message List item in 3-column layout'),
113 h_gui_two_line_v => _('Spread Message List information over two lines when using the three column mode.'),
114 l_gui_margin_co => _('Show compose margin'),
115 h_gui_margin_co => _('Shows a small margin in the Compose View.'),
116 l_gui_mview_date => _('Don\'t display localized date'),
117 h_gui_mview_date => _('Toggles localization of date format in Message View'),
118 l_gui_zero_char => _('Zero replacement character'),
119 h_gui_zero_char => _('Replaces \'0\' with the given character in Folder List'),
121 l_beh_hover_t => _('Drag \'n\' drop hover timeout (ms)'),
122 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.'),
123 l_beh_dangerous => _('Don\'t confirm deletions (dangerous!)'),
124 h_beh_dangerous => _('Don\'t ask for confirmation before definitive deletion of emails.'),
125 l_beh_flowed => _('Respect format=flowed in messages'),
126 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.'),
127 l_beh_parts_rw => _('Allow writable temporary files'),
128 h_beh_parts_rw => _('Saves temporary files when opening attachment with write bit set.'),
129 l_beh_skip_ssl => _('Don\'t check SSL certificates'),
130 h_beh_skip_ssl => _('Disables the verification of SSL certificates.'),
131 l_beh_up_step => _('Progress bar update step (items)'),
132 h_beh_up_step => _('Update stepping in progress bars.'),
133 l_beh_thread_a => _('Maximum age when threading by subject (days)'),
134 h_beh_thread_a => _('Number of days to include a message in a thread when using "Thread using subject in addition to standard headers".'),
135 l_beh_unsafe_ssl => _('Allow unsafe SSL certificates'),
136 h_beh_unsafe_ssl => _('Allows Claws Mail to remember multiple SSL certificates for a given server/port.'),
137 l_beh_use_utf8 => _('Force UTF-8 for broken mails'),
138 h_beh_use_utf8 => _('Use UTF-8 encoding for broken mails instead of current locale.'),
139 l_beh_warn_dnd => _('Warn on drag \'n\' drop'),
140 h_beh_warn_dnd => _('Display a confirmation dialogue on drag \'n\' drop of folders.'),
141 l_beh_out_ascii => _('Outgoing messages fallback to ASCII'),
142 h_beh_out_ascii => _('If content allows, ASCII will be used to encode outgoing messages, otherwise the user-defined encoding is enforced always.'),
143 l_beh_pp_unsel => _('Primary paste unselects selection'),
144 h_beh_pp_unsel => _('Controls how pasting using middle-click changes the selected text and insertion point.'),
145 l_beh_inline_at => _('Show inline attachments'),
146 h_beh_inline_at => _('Allows hiding inline attachments already shown in mail structure view'),
147 l_beh_addr_swc => _('Address search in compose window matches any'),
148 h_beh_addr_swc => _('On Tab-key completion, address text will match any part of the string or only the from the start'),
149 l_beh_fold_swc => _('Folder search in folder selector matches any'),
150 h_beh_fold_swc => _('On folder name completion text will match any part of the string or only from the start'),
152 l_col_emphasis => _('X-Mailer header'),
153 h_col_emphasis => _('The colour used for the X-Mailer line when its value is Claws Mail.'),
154 l_col_log_err => _('Error messages'),
155 h_col_log_err => _('Colour for error messages in log window.'),
156 l_col_log_in => _('Server messages'),
157 h_col_log_in => _('Colour for messages received from servers in log window.'),
158 l_col_log_msg => _('Standard messages'),
159 h_col_log_msg => _('Colour for messages in log window.'),
160 l_col_log_out => _('Client messages'),
161 h_col_log_out => _('Colour for messages sent to servers in log window.'),
162 l_col_log_warn => _('Warnings'),
163 h_col_log_warn => _('Colour for warning messages in log window.'),
165 l_col_diff_add => _('Added lines'),
166 h_col_diff_add => _('Colour for added lines in patches.'),
167 l_col_diff_del => _('Deleted lines'),
168 h_col_diff_del => _('Colour for deleted lines in patches.'),
169 l_col_diff_hunk => _('Hunk lines'),
170 h_col_diff_hunk => _('Color for hunk headers in patches.'),
172 l_win_x => _('X position'),
173 h_win_x => _('X coordinate for window\'s top-left corner.'),
174 l_win_y => _('Y position'),
175 h_win_y => _('Y coordinate for window\'s top-left corner.'),
176 l_win_w => _('Width'),
177 h_win_w => _('Window\'s width in pixels.'),
178 l_win_h => _('Height'),
179 h_win_h => _('Window\'s height in pixels.'),
181 l_win_main_mx => _('Maximized'),
182 h_win_main_mx => _('Changes window maximized status.'),
183 l_win_main_fs => _('Full-screen'),
184 h_win_main_fs => _('Changes full screen status.'),
186 e_error => _('Error: '),
187 e_noclawsrc => _('resource file for Claws Mail was not found.'),
188 e_running => _('seems Claws Mail is currently running, close it first.'),
189 e_requireddir => _('option requires a directory name.'),
190 e_requiredfile => _('option requires a file name.'),
191 e_notadir => _('specified name is not a directory or does not exist.'),
192 e_notafile => _('specified name is not a file or does not exist.'),
195 # all preferences read by load_preferences
197 # values of all preferences handled by clawsker
199 # default config dir and file name
200 my $ALTCONFIGDIR = FALSE;
201 my $CONFIGDIR = $ENV{HOME} . '/.claws-mail/';
202 my $CONFIGRC = 'clawsrc';
204 # index constants for preference arrays
205 use constant NAME => 0; # the name on the rc file
206 use constant LABEL => 1; # the label on the GUI
207 use constant DESC => 2; # the description for the hint/help
208 use constant TYPE => 3; # data type: bool, int, float, string, color
209 use constant CMVER => 4; # lowest Claws Mail version the feature exists
210 use constant CMDEF => 5; # default value for the preference in Claws Mail
211 use constant GUI => 6; # GUI element
213 # constants for GUI spacing
214 use constant HBOX_SPC => 5;
215 use constant FRAME_SPC => 2;
216 use constant PAGE_SPC => 5;
220 sub version_greater_or_equal {
221 my ($version, $refvers) = @_;
222 my @version = split (/\./, $version);
223 my @refvers = split (/\./, $refvers);
224 while ($#version < $#refvers) {
225 push (@version, '0');
228 while (($idx <= $#refvers)
229 and (int ($version[$idx]) == int ($refvers[$idx]))) {
232 return TRUE if (($idx > $#refvers)
233 or (int ($version[$idx]) >= int ($refvers[$idx])));
237 sub get_claws_version {
242 foreach my $bin (@cmbin) {
247 return "" unless ($_); # not installed
250 my @fver = split (/ /);
251 die "Invalid version string" unless ($fver[2] eq "version");
252 my @ver = split (/\./, $fver[3]);
255 if ($ver[2] =~ /(\d+)cvs(\d+)/) {
264 # data handlers and auxiliar functions
266 sub handle_bool_value {
267 my ($widget, $event, $dataref) = @_;
268 $$dataref = ($widget->get_active ())? '1': '0';
271 sub handle_int_value {
272 my ($widget, $event, $dataref) = @_;
273 $_ = $widget->get_text ();
278 $widget->set_text ($_);
281 $widget->set_text ($$dataref);
285 sub handle_string_value {
286 my ($widget, $event, $dataref) = @_;
287 $$dataref = $widget->get_text ();
290 sub handle_nchar_value {
291 my ($widget, $event, $dataref, $minlen) = @_;
292 $_ = substr ($widget->get_text (), 0, $minlen);
293 $widget->set_text ($_);
297 sub gdk_color_from_str {
299 my ($rr, $gg, $bb) = (0, 0 ,0);
301 if (/\#([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])([A-F0-9][A-F0-9])/) {
306 my $color = Gtk2::Gdk::Color->new ($rr, $gg, $bb);
310 sub str_from_gdk_color {
312 my $rr = $color->red / 256;
313 my $gg = $color->green / 256;
314 my $bb = $color->blue / 256;
315 my $str = sprintf ("#%.2x%.2x%.2x", $rr, $gg, $bb);
319 sub handle_color_value {
320 my ($widget, $event, $dataref) = @_;
321 my $newcol = $widget->get_color;
322 $$dataref = str_from_gdk_color ($newcol);
325 sub handle_selection_value {
326 my ($widget, $event, $dataref) = @_;
327 $$dataref = $widget->get_active;
330 sub get_rc_filename {
331 return $CONFIGDIR . $CONFIGRC;
334 sub set_rc_filename {
336 my @parts = split ('/', $fullname);
337 $CONFIGRC = $parts[$#parts];
338 $parts[$#parts] = '';
339 $CONFIGDIR = join ('/', @parts);
343 my ($mesg, $fatal) = @_;
344 if (defined($fatal) && $fatal eq 'die') {
345 die "$NAME: $mesg\n";
348 print "$NAME: $mesg\n";
354 my $markup = "<span weight=\"bold\" size=\"large\">" . $emsg . "</span>";
355 my $errordlg = Gtk2::MessageDialog->new_with_markup ($main_window, 'modal', 'error', 'cancel', $markup);
356 $errordlg->set_title (_('Error message'));
361 sub claws_is_running {
362 my $emsg = "$xl::s{e_error}$xl::s{e_running}";
364 error_dialog ($emsg);
368 sub check_claws_not_running {
369 my $socket = (not $ALTCONFIGDIR)? "/tmp/": $CONFIGDIR;
370 $socket .= "claws-mail-$<";
371 -S $socket and return claws_is_running ();
373 my $lockdir = "/tmp/claws-mail-$<";
377 $socket = "$lockdir/" . md5_hex ($_);
378 -S $socket and return claws_is_running ();
385 (defined($rcfile) && -f $rcfile) or do {
386 my $emsg = "$xl::s{e_error}$xl::s{e_noclawsrc}\n";
388 error_dialog ($emsg);
394 sub set_widget_hint {
396 my ($wdgt, $hint) = @_;
397 $wdgt->set_tooltip_text ($hint);
398 $wdgt->set_has_tooltip (TRUE);
402 sub set_widget_sens {
403 my ($wdgt, $versions) = @_;
404 my @ver = split(/,/, $versions);
406 $wdgt->set_sensitive (
407 version_greater_or_equal ($CLAWSV, $ver[0])
408 and version_greater_or_equal ($ver[1], $CLAWSV)
411 $wdgt->set_sensitive (version_greater_or_equal ($CLAWSV, $ver[0]));
415 # graphic element creation
417 sub new_check_button_for {
418 my ($hash, $key) = @_;
419 my $name = $$hash{$key}[NAME];
420 my $label = $$hash{$key}[LABEL];
422 my $hbox = Gtk2::HBox->new (FALSE, 5);
423 my $cb = Gtk2::CheckButton->new ($label);
424 $$hash{$key}[GUI] = $cb;
425 if (defined ($HPVALUE{$name})) {
426 $cb->set_active ($HPVALUE{$name} eq '1');
428 $cb->signal_connect (clicked => sub {
430 handle_bool_value ($w, $e, \$HPVALUE{$name});
432 set_widget_hint ($cb, $$hash{$key}[DESC]);
433 set_widget_sens ($cb, $$hash{$key}[CMVER]);
434 $hbox->pack_start ($cb, FALSE, FALSE, HBOX_SPC);
439 sub new_text_box_for_int {
440 my ($hash, $key) = @_;
441 my $name = $$hash{$key}[NAME];
442 my $label = $$hash{$key}[LABEL];
443 my @type = split (/,/, $$hash{$key}[TYPE]);
444 push (@type, 0), push (@type, 10000) unless ($#type > 0);
446 my $hbox = Gtk2::HBox->new (FALSE, 5);
447 my $glabel = Gtk2::Label->new ($label);
448 my $pagei = int (($type[2] - $type[1]) / 10);
449 my $gentry = Gtk2::SpinButton->new_with_range ($type[1], $type[2], $pagei);
450 $gentry->set_numeric (TRUE);
451 $gentry->set_value ($HPVALUE{$name});
452 $$hash{$key}[GUI] = $gentry;
453 $gentry->signal_connect('value-changed' => sub {
455 handle_int_value ($w, $e, \$HPVALUE{$name});
457 set_widget_hint ($gentry, $$hash{$key}[DESC]);
458 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
459 $glabel->set_sensitive ($gentry->sensitive);
460 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
461 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
466 sub new_text_box_for_nchar {
467 my ($hash, $key) = @_;
468 my $name = $$hash{$key}[NAME];
469 my $label = $$hash{$key}[LABEL];
470 my @type = split (/,/, $$hash{$key}[TYPE]); # char,minlen,maxlen
471 my $hbox = Gtk2::HBox->new (FALSE, 5);
472 my $glabel = Gtk2::Label->new ($label);
473 my $gentry = Gtk2::Entry->new ();
474 $gentry->set_max_length($type[2]) if defined ($type[2]);
475 $gentry->set_width_chars(int ($type[2]) + 2) if defined ($type[2]);
476 $gentry->set_text ($HPVALUE{$name});
477 $$hash{$key}[GUI] = $gentry;
478 $gentry->signal_connect('key-release-event' => sub {
480 handle_nchar_value ($w, $e, \$HPVALUE{$name}, $type[1]);
482 set_widget_hint ($gentry, $$hash{$key}[DESC]);
483 set_widget_sens ($gentry, $$hash{$key}[CMVER]);
484 $glabel->set_sensitive ($gentry->sensitive);
485 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
486 $hbox->pack_start ($gentry, FALSE, FALSE, HBOX_SPC);
491 sub new_color_button_for {
492 my ($hash, $key) = @_;
493 my $name = $$hash{$key}[NAME];
494 my $label = $$hash{$key}[LABEL];
496 my $col = gdk_color_from_str ($HPVALUE{$name});
497 my $hbox = Gtk2::HBox->new (FALSE, 5);
498 my $glabel = Gtk2::Label->new ($label);
499 my $button = Gtk2::ColorButton->new_with_color ($col);
500 $$hash{$key}[GUI] = $button;
501 $button->set_title ($label);
502 $button->set_relief ('none');
503 $button->signal_connect ('color-set' => sub {
505 handle_color_value ($w, $e, \$HPVALUE{$name});
507 set_widget_hint ($button, $$hash{$key}[DESC]);
508 set_widget_sens ($button, $$hash{$key}[CMVER]);
509 $glabel->set_sensitive ($button->sensitive);
510 $hbox->pack_start ($button, FALSE, FALSE, HBOX_SPC);
511 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
516 sub new_selection_box_for {
517 my ($hash, $key) = @_;
518 my $name = $$hash{$key}[NAME];
519 my $label = $$hash{$key}[LABEL];
521 my $hbox = Gtk2::HBox->new (FALSE, 5);
522 my $glabel = Gtk2::Label->new ($label);
523 my $combo = Gtk2::ComboBox->new_text;
524 $$hash{$key}[GUI] = $combo;
525 my @options = split (';', $$hash{$key}[TYPE]);
526 foreach my $opt (@options) {
527 my ($index, $textkey) = split ('=', $opt);
528 $combo->insert_text ($index, $xl::s{$textkey});
530 $combo->signal_connect ('changed' => sub {
532 handle_selection_value ($w, $e, \$HPVALUE{$name});
534 $combo->set_active ($HPVALUE{$name});
535 set_widget_hint ($combo, $$hash{$key}[DESC]);
536 set_widget_sens ($combo, $$hash{$key}[CMVER]);
537 $glabel->set_sensitive ($combo->sensitive);
538 $hbox->pack_start ($glabel, FALSE, FALSE, HBOX_SPC);
539 $hbox->pack_start ($combo, FALSE, FALSE, HBOX_SPC);
544 # more graphic helpers
547 my $hbox = Gtk2::HBox->new (FALSE, 5);
548 $hbox->set_border_width (PAGE_SPC);
549 foreach my $item (@_) {
550 $hbox->pack_start ($item, FALSE, FALSE, 0);
556 my $vbox = Gtk2::VBox->new (FALSE, 5);
557 $vbox->set_border_width (PAGE_SPC);
558 foreach my $item (@_) {
559 $vbox->pack_start ($item, FALSE, FALSE, 0);
564 sub new_vbox_pack_compact {
565 my $vbox = Gtk2::VBox->new (FALSE, 0);
566 $vbox->set_border_width (0);
567 foreach my $item (@_) {
568 $vbox->pack_start ($item, FALSE, FALSE, 0);
573 sub new_subpage_frame {
574 my ($box, $title, $notpacked) = @_;
575 my $frame = Gtk2::Frame->new ($title);
577 return new_vbox_pack ($frame) unless defined ($notpacked);
581 # preference maps and corresponding page creation subs
583 %pr::oth = ( # other preferences
585 'addressbook_use_editaddress_dialog',
586 $xl::s{l_oth_use_dlg},
587 $xl::s{h_oth_use_dlg},
594 'cache_max_mem_usage',
595 $xl::s{l_oth_max_use},
596 $xl::s{h_oth_max_use},
597 'int,0,262144', # 0 Kb - 256 Mb
603 'cache_min_keep_time',
604 $xl::s{l_oth_min_time},
605 $xl::s{h_oth_min_time},
606 'int,0,120', # 0 minutes - 2 hours
612 'use_networkmanager',
613 $xl::s{l_oth_use_netm},
614 $xl::s{h_oth_use_netm},
622 sub new_other_page() {
623 return new_vbox_pack (
626 new_check_button_for(\%pr::oth, 'use_dlg')),
627 $xl::s{ab_frame}, 'not-packed'),
630 new_text_box_for_int(\%pr::oth, 'max_use'),
631 new_text_box_for_int(\%pr::oth, 'min_time')),
632 $xl::s{mem_frame}, 'not-packed'),
635 new_check_button_for(\%pr::oth, 'use_netm')),
636 $xl::s{netm_frame}, 'not-packed')
640 %pr::gui = ( # gui bells and whistles
643 $xl::s{l_gui_b_unread},
644 $xl::s{h_gui_b_unread},
652 $xl::s{l_gui_no_markup},
653 $xl::s{h_gui_no_markup},
660 'enable_dotted_lines',
661 $xl::s{l_gui_dot_lines},
662 $xl::s{h_gui_dot_lines},
670 $xl::s{l_gui_h_scroll},
671 $xl::s{h_gui_h_scroll},
679 $xl::s{l_gui_swp_from},
680 $xl::s{h_gui_swp_from},
687 'folderview_vscrollbar_policy',
688 $xl::s{l_gui_v_scroll},
689 $xl::s{h_gui_v_scroll},
690 '0=l_gui_v_scroll_show;1=l_gui_v_scroll_auto;2=l_gui_v_scroll_hide',
697 $xl::s{l_gui_from_show},
698 $xl::s{h_gui_from_show},
699 '0=l_gui_from_show_name;1=l_gui_from_show_addr;2=l_gui_from_show_both',
705 'stripes_color_offset',
706 $xl::s{l_gui_strip_off},
707 $xl::s{h_gui_strip_off},
708 'int,0,40000', # no idea what this number means
714 'textview_cursor_visible',
715 $xl::s{l_gui_cursor_v},
716 $xl::s{h_gui_cursor_v},
723 'toolbar_detachable',
724 $xl::s{l_gui_toolbar_d},
725 $xl::s{h_gui_toolbar_d},
732 'use_stripes_everywhere',
733 $xl::s{l_gui_strip_all},
734 $xl::s{h_gui_strip_all},
741 'use_stripes_in_summaries',
742 $xl::s{l_gui_strip_sum},
743 $xl::s{h_gui_strip_sum},
751 $xl::s{l_gui_two_line_v},
752 $xl::s{h_gui_two_line_v},
759 'show_compose_margin',
760 $xl::s{l_gui_margin_co},
761 $xl::s{h_gui_margin_co},
768 'msgview_date_format',
769 $xl::s{l_gui_mview_date},
770 $xl::s{h_gui_mview_date},
777 'zero_replacement_char',
778 $xl::s{l_gui_zero_char},
779 $xl::s{h_gui_zero_char},
788 my $gf = Gtk2::VBox->new (FALSE, 5);
789 $gf->set_border_width (PAGE_SPC);
791 my $cb_dot_lines = new_check_button_for (\%pr::gui, 'dot_lines');
792 my $cb_toolbar_d = new_check_button_for (\%pr::gui, 'toolbar_d');
793 my $tb_zero_char = new_text_box_for_nchar (\%pr::gui, 'zero_char');
795 $gf->pack_start (new_subpage_frame (
797 new_check_button_for (\%pr::gui, 'strip_all'),
798 new_check_button_for (\%pr::gui, 'strip_sum'),
799 new_text_box_for_int (\%pr::gui, 'strip_off')),
800 $xl::s{stripes_frame}, 'not-packed'),
801 FALSE, FALSE, FRAME_SPC);
802 $gf->pack_start (new_subpage_frame (
804 new_check_button_for (\%pr::gui, 'b_unread'),
805 new_check_button_for (\%pr::gui, 'swp_from'),
806 new_check_button_for (\%pr::gui, 'two_linev'),
807 new_selection_box_for (\%pr::gui, 'from_show')),
808 $xl::s{mlist_frame}, 'not-packed'),
809 FALSE, FALSE, FRAME_SPC);
810 $gf->pack_start (new_subpage_frame (
812 new_check_button_for (\%pr::gui, 'cursor_v'),
813 new_check_button_for (\%pr::gui, 'mview_date')),
814 $xl::s{mview_frame}, 'not-packed'),
815 FALSE, FALSE, FRAME_SPC);
816 $gf->pack_start (new_subpage_frame (
818 new_check_button_for (\%pr::gui, 'no_markup'),
819 new_check_button_for (\%pr::gui, 'margin_co')),
820 $xl::s{compo_frame}, 'not-packed'),
821 FALSE, FALSE, FRAME_SPC);
822 $gf->pack_start ($cb_dot_lines, FALSE, FALSE, 0);
823 $gf->pack_start ($cb_toolbar_d, FALSE, FALSE, 0);
824 $gf->pack_start (new_subpage_frame (
826 new_check_button_for (\%pr::gui, 'h_scroll'),
827 new_selection_box_for (\%pr::gui, 'v_scroll')),
828 $xl::s{sbar_frame}, 'not-packed'),
829 FALSE, FALSE, FRAME_SPC);
830 $gf->pack_start ($tb_zero_char, FALSE, FALSE, 0);
835 %pr::beh = ( # tweak some behaviour
838 $xl::s{l_beh_hover_t},
839 $xl::s{h_beh_hover_t},
840 'int,100,3000', # 0.1 seconds - 3 seconds
847 $xl::s{l_beh_dangerous},
848 $xl::s{h_beh_dangerous},
855 'respect_flowed_format',
856 $xl::s{l_beh_flowed},
857 $xl::s{h_beh_flowed},
864 'save_parts_readwrite',
865 $xl::s{l_beh_parts_rw},
866 $xl::s{h_beh_parts_rw},
873 'skip_ssl_cert_check',
874 $xl::s{l_beh_skip_ssl},
875 $xl::s{h_beh_skip_ssl},
882 'statusbar_update_step',
883 $xl::s{l_beh_up_step},
884 $xl::s{h_beh_up_step},
885 'int,1,200', # 1 item - 200 items
891 'thread_by_subject_max_age',
892 $xl::s{l_beh_thread_a},
893 $xl::s{h_beh_thread_a},
894 'int,1,30', # 1 day - 30 days
901 $xl::s{l_beh_unsafe_ssl},
902 $xl::s{h_beh_unsafe_ssl},
909 'utf8_instead_of_locale_for_broken_mail',
910 $xl::s{l_beh_use_utf8},
911 $xl::s{h_beh_use_utf8},
919 $xl::s{l_beh_warn_dnd},
920 $xl::s{h_beh_warn_dnd},
927 'outgoing_fallback_to_ascii',
928 $xl::s{l_beh_out_ascii},
929 $xl::s{h_beh_out_ascii},
936 'primary_paste_unselects',
937 $xl::s{l_beh_pp_unsel},
938 $xl::s{h_beh_pp_unsel},
945 'show_inline_attachments',
946 $xl::s{l_beh_inline_at},
947 $xl::s{h_beh_inline_at},
954 'address_search_wildcard',
955 $xl::s{l_beh_addr_swc},
956 $xl::s{h_beh_addr_sw1},
963 'folder_search_wildcard',
964 $xl::s{l_beh_fold_swc},
965 $xl::s{h_beh_fold_sw1},
973 sub new_behaviour_page() {
974 my $bf = Gtk2::VBox->new (FALSE, 5);
975 $bf->set_border_width (PAGE_SPC);
977 my $tb_up_step = new_text_box_for_int (\%pr::beh, 'up_step');
978 my $tb_thread_a = new_text_box_for_int (\%pr::beh, 'thread_a');
980 $bf->pack_start (new_subpage_frame (
982 new_text_box_for_int (\%pr::beh, 'hover_t'),
983 new_check_button_for (\%pr::beh, 'warn_dnd')),
984 $xl::s{dnd_frame}, 'not-packed'),
985 FALSE, FALSE, FRAME_SPC);
986 $bf->pack_start (new_subpage_frame (
988 new_check_button_for (\%pr::beh, 'skip_ssl'),
989 new_check_button_for (\%pr::beh, 'unsafe_ssl')),
990 $xl::s{ssl_frame}, 'not-packed'),
991 FALSE, FALSE, FRAME_SPC);
992 $bf->pack_start ($tb_up_step, FALSE, FALSE, 0);
993 $bf->pack_start ($tb_thread_a, FALSE, FALSE, 0);
994 $bf->pack_start (new_subpage_frame (
996 new_check_button_for (\%pr::beh, 'flowed'),
997 new_check_button_for (\%pr::beh, 'parts_rw'),
998 new_check_button_for (\%pr::beh, 'use_utf8'),
999 new_check_button_for (\%pr::beh, 'dangerous'),
1000 new_check_button_for (\%pr::beh, 'out_ascii'),
1001 new_check_button_for (\%pr::beh, 'pp_unsel'),
1002 new_check_button_for (\%pr::beh, 'inline_at')),
1003 $xl::s{msgs_frame}, 'not-packed'),
1004 FALSE, FALSE, FRAME_SPC);
1005 $bf->pack_start (new_subpage_frame (
1007 new_check_button_for (\%pr::beh, 'addr_swc'),
1008 new_check_button_for (\%pr::beh, 'fold_swc')),
1009 $xl::s{swc_frame}, 'not-packed'),
1010 FALSE, FALSE, FRAME_SPC);
1014 %pr::col = ( # a variety of colours
1017 $xl::s{l_col_emphasis},
1018 $xl::s{h_col_emphasis},
1026 $xl::s{l_col_log_err},
1027 $xl::s{h_col_log_err},
1035 $xl::s{l_col_log_in},
1036 $xl::s{h_col_log_in},
1044 $xl::s{l_col_log_msg},
1045 $xl::s{h_col_log_msg},
1053 $xl::s{l_col_log_out},
1054 $xl::s{h_col_log_out},
1062 $xl::s{l_col_log_warn},
1063 $xl::s{h_col_log_warn},
1071 $xl::s{l_col_diff_add},
1072 $xl::s{h_col_diff_add},
1079 'diff_deleted_color',
1080 $xl::s{l_col_diff_del},
1081 $xl::s{h_col_diff_del},
1089 $xl::s{l_col_diff_hunk},
1090 $xl::s{h_col_diff_hunk},
1098 sub new_colours_page() {
1099 return new_vbox_pack (
1102 new_color_button_for (\%pr::col, 'emphasis')),
1103 $xl::s{msgview_frame}, 'not-packed'),
1106 new_color_button_for (\%pr::col, 'log_err'),
1107 new_color_button_for (\%pr::col, 'log_in'),
1108 new_color_button_for (\%pr::col, 'log_msg'),
1109 new_color_button_for (\%pr::col, 'log_out'),
1110 new_color_button_for (\%pr::col, 'log_warn')),
1111 $xl::s{log_frame}, 'not-packed'),
1114 new_color_button_for (\%pr::col, 'diff_add'),
1115 new_color_button_for (\%pr::col, 'diff_del'),
1116 new_color_button_for (\%pr::col, 'diff_hunk')),
1117 $xl::s{diff_frame}, 'not-packed')
1121 %pr::win = ( # tweak window positions and/or sizes
1126 'int,0,3000', # 0 pixels - 3000 pixels
1135 'int,0,3000', # 0 pixels - 3000 pixels
1144 'int,0,3000', # 0 pixels - 3000 pixels
1153 'int,0,3000', # 0 pixels - 3000 pixels
1159 'mainwin_maximised',
1160 $xl::s{l_win_main_mx},
1161 $xl::s{h_win_main_mx},
1168 'mainwin_fullscreen',
1169 $xl::s{l_win_main_fs},
1170 $xl::s{h_win_main_fs},
1177 'main_messagewin_x',
1180 'int,0,3000', # 0 pixels - 3000 pixels
1186 'main_messagewin_y',
1189 'int,0,3000', # 0 pixels - 3000 pixels
1198 'int,0,3000', # 0 pixels - 3000 pixels
1204 'messagewin_height',
1207 'int,0,3000', # 0 pixels - 3000 pixels
1216 'int,0,3000', # 0 pixels - 3000 pixels
1225 'int,0,3000', # 0 pixels - 3000 pixels
1234 'int,0,3000', # 0 pixels - 3000 pixels
1240 'receivewin_height',
1243 'int,0,3000', # 0 pixels - 3000 pixels
1252 'int,0,3000', # 0 pixels - 3000 pixels
1261 'int,0,3000', # 0 pixels - 3000 pixels
1267 'folderitemwin_width',
1270 'int,0,3000', # 0 pixels - 3000 pixels
1276 'folderitemwin_height',
1279 'int,0,3000', # 0 pixels - 3000 pixels
1285 'folderselwin_width',
1288 'int,0,3000', # 0 pixels - 3000 pixels
1294 'folderselwin_height',
1297 'int,0,3000', # 0 pixels - 3000 pixels
1306 'int,0,3000', # 0 pixels - 3000 pixels
1315 'int,0,3000', # 0 pixels - 3000 pixels
1321 'addressbookwin_width',
1324 'int,0,3000', # 0 pixels - 3000 pixels
1330 'addressbookwin_height',
1333 'int,0,3000', # 0 pixels - 3000 pixels
1339 'addressbookeditpersonwin_width',
1342 'int,0,3000', # 0 pixels - 3000 pixels
1348 'addressbookeditpersonwin_height',
1351 'int,0,3000', # 0 pixels - 3000 pixels
1357 'addressbookeditgroupwin_width',
1360 'int,0,3000', # 0 pixels - 3000 pixels
1366 'addressbookeditgroupwin_height',
1369 'int,0,3000', # 0 pixels - 3000 pixels
1375 'addressaddwin_width',
1378 'int,0,3000', # 0 pixels - 3000 pixels
1384 'addressaddwin_height',
1387 'int,0,3000', # 0 pixels - 3000 pixels
1393 'addressbook_folderselwin_width',
1396 'int,0,3000', # 0 pixels - 3000 pixels
1402 'addressbook_folderselwin_height',
1405 'int,0,3000', # 0 pixels - 3000 pixels
1411 'editaccountwin_width',
1414 'int,0,3000', # 0 pixels - 3000 pixels
1420 'editaccountwin_height',
1423 'int,0,3000', # 0 pixels - 3000 pixels
1429 'accountswin_width',
1432 'int,0,3000', # 0 pixels - 3000 pixels
1438 'accountswin_height',
1441 'int,0,3000', # 0 pixels - 3000 pixels
1447 'filteringwin_width',
1450 'int,0,3000', # 0 pixels - 3000 pixels
1456 'filteringwin_height',
1459 'int,0,3000', # 0 pixels - 3000 pixels
1465 'filteringactionwin_width',
1468 'int,0,3000', # 0 pixels - 3000 pixels
1474 'filteringactionwin_height',
1477 'int,0,3000', # 0 pixels - 3000 pixels
1483 'filtering_debugwin_width',
1486 'int,0,3000', # 0 pixels - 3000 pixels
1492 'filtering_debugwin_height',
1495 'int,0,3000', # 0 pixels - 3000 pixels
1504 'int,0,3000', # 0 pixels - 3000 pixels
1510 'matcherwin_height',
1513 'int,0,3000', # 0 pixels - 3000 pixels
1522 'int,0,3000', # 0 pixels - 3000 pixels
1531 'int,0,3000', # 0 pixels - 3000 pixels
1537 'templateswin_width',
1540 'int,0,3000', # 0 pixels - 3000 pixels
1546 'templateswin_height',
1549 'int,0,3000', # 0 pixels - 3000 pixels
1558 'int,0,3000', # 0 pixels - 3000 pixels
1564 'actionswin_height',
1567 'int,0,3000', # 0 pixels - 3000 pixels
1576 'int,0,3000', # 0 pixels - 3000 pixels
1585 'int,0,3000', # 0 pixels - 3000 pixels
1594 'int,0,3000', # 0 pixels - 3000 pixels
1600 'pluginswin_height',
1603 'int,0,3000', # 0 pixels - 3000 pixels
1612 'int,0,3000', # 0 pixels - 3000 pixels
1621 'int,0,3000', # 0 pixels - 3000 pixels
1627 'print_previewwin_width',
1630 'int,0,3000', # 0 pixels - 3000 pixels
1636 'print_previewwin_height',
1639 'int,0,3000', # 0 pixels - 3000 pixels
1646 sub new_winpos_subpage_main() {
1647 return new_subpage_frame (
1648 new_vbox_pack_compact (
1650 new_text_box_for_int (\%pr::win, 'main_x'),
1651 new_text_box_for_int (\%pr::win, 'main_y')),
1653 new_text_box_for_int (\%pr::win, 'main_w'),
1654 new_text_box_for_int (\%pr::win, 'main_h')),
1656 new_check_button_for (\%pr::win, 'main_fs'),
1657 new_check_button_for (\%pr::win, 'main_mx'))),
1662 sub new_winpos_subpage_msgs() {
1663 return new_subpage_frame (
1664 new_vbox_pack_compact (
1666 new_text_box_for_int (\%pr::win, 'msgs_x'),
1667 new_text_box_for_int (\%pr::win, 'msgs_y')),
1669 new_text_box_for_int (\%pr::win, 'msgs_w'),
1670 new_text_box_for_int (\%pr::win, 'msgs_h'))),
1675 sub new_winpos_subpage_sendrecv() {
1676 return new_vbox_pack (
1679 new_text_box_for_int (\%pr::win, 'send_w'),
1680 new_text_box_for_int (\%pr::win, 'send_h')),
1681 _('Send window'), 'not-packed'),
1684 new_text_box_for_int (\%pr::win, 'recv_w'),
1685 new_text_box_for_int (\%pr::win, 'recv_h')),
1686 _('Receive window'), 'not-packed')
1690 sub new_winpos_subpage_fold() {
1691 return new_vbox_pack (
1693 new_vbox_pack_compact (
1695 new_text_box_for_int (\%pr::win, 'fold_x'),
1696 new_text_box_for_int (\%pr::win, 'fold_y')),
1698 new_text_box_for_int (\%pr::win, 'fold_w'),
1699 new_text_box_for_int (\%pr::win, 'fold_h'))),
1700 _('Folder window'), 'not-packed'),
1703 new_text_box_for_int (\%pr::win, 'fsel_w'),
1704 new_text_box_for_int (\%pr::win, 'fsel_h')),
1705 _('Folder selection window'), 'not-packed')
1709 sub new_winpos_subpage_addrbook() {
1710 return new_vbox_pack (
1713 new_text_box_for_int (\%pr::win, 'addr_w'),
1714 new_text_box_for_int (\%pr::win, 'addr_h')),
1715 _('Addressbook main window'), 'not-packed'),
1718 new_text_box_for_int (\%pr::win, 'adep_w'),
1719 new_text_box_for_int (\%pr::win, 'adep_h')),
1720 _('Edit person window'), 'not-packed'),
1723 new_text_box_for_int (\%pr::win, 'adeg_w'),
1724 new_text_box_for_int (\%pr::win, 'adeg_h')),
1725 _('Edit group window'), 'not-packed'),
1728 new_text_box_for_int (\%pr::win, 'adda_w'),
1729 new_text_box_for_int (\%pr::win, 'adda_h')),
1730 _('Add address window'), 'not-packed'),
1733 new_text_box_for_int (\%pr::win, 'addf_w'),
1734 new_text_box_for_int (\%pr::win, 'addf_h')),
1735 _('Folder select window'), 'not-packed')
1739 sub new_winpos_subpage_accounts() {
1740 return new_vbox_pack (
1743 new_text_box_for_int (\%pr::win, 'acco_w'),
1744 new_text_box_for_int (\%pr::win, 'acco_h')),
1745 _('Accounts window'), 'not-packed'),
1748 new_text_box_for_int (\%pr::win, 'acce_w'),
1749 new_text_box_for_int (\%pr::win, 'acce_h')),
1750 _('Edit account window'), 'not-packed')
1754 sub new_winpos_subpage_filtering() {
1755 return new_vbox_pack (
1758 new_text_box_for_int (\%pr::win, 'filt_w'),
1759 new_text_box_for_int (\%pr::win, 'filt_h')),
1760 _('Filtering window'), 'not-packed'),
1763 new_text_box_for_int (\%pr::win, 'fila_w'),
1764 new_text_box_for_int (\%pr::win, 'fila_h')),
1765 _('Filtering actions window'), 'not-packed'),
1768 new_text_box_for_int (\%pr::win, 'fild_w'),
1769 new_text_box_for_int (\%pr::win, 'fild_h')),
1770 _('Filtering debug window'), 'not-packed'),
1773 new_text_box_for_int (\%pr::win, 'matc_w'),
1774 new_text_box_for_int (\%pr::win, 'matc_h')),
1775 _('Matcher window'), 'not-packed')
1779 sub new_winpos_subpage_prefs() {
1780 return new_vbox_pack (
1783 new_text_box_for_int (\%pr::win, 'pref_w'),
1784 new_text_box_for_int (\%pr::win, 'pref_h')),
1785 _('Preferences window'), 'not-packed'),
1788 new_text_box_for_int (\%pr::win, 'temp_w'),
1789 new_text_box_for_int (\%pr::win, 'temp_h')),
1790 _('Templates window'), 'not-packed'),
1793 new_text_box_for_int (\%pr::win, 'acti_w'),
1794 new_text_box_for_int (\%pr::win, 'acti_h')),
1795 _('Actions window'), 'not-packed'),
1798 new_text_box_for_int (\%pr::win, 'tags_w'),
1799 new_text_box_for_int (\%pr::win, 'tags_h')),
1800 _('Tags window'), 'not-packed'),
1803 new_text_box_for_int (\%pr::win, 'plug_w'),
1804 new_text_box_for_int (\%pr::win, 'plug_h')),
1805 _('Plugins window'), 'not-packed')
1809 sub new_winpos_subpage_misc() {
1810 return new_vbox_pack (
1813 new_text_box_for_int (\%pr::win, 'logw_w'),
1814 new_text_box_for_int (\%pr::win, 'logw_h')),
1815 _('Log window'), 'not-packed'),
1818 new_text_box_for_int (\%pr::win, 'prin_w'),
1819 new_text_box_for_int (\%pr::win, 'prin_h')),
1820 _('Print preview window'), 'not-packed'),
1823 new_text_box_for_int (\%pr::win, 'sour_w'),
1824 new_text_box_for_int (\%pr::win, 'sour_h')),
1825 _('View source window'), 'not-packed')
1829 sub new_winpos_page() {
1830 my $winbook = Gtk2::Notebook->new;
1831 $winbook->set_tab_pos ('right');
1832 $winbook->append_page (new_winpos_subpage_main, _('Main'));
1833 $winbook->append_page (new_winpos_subpage_msgs, _('Message'));
1834 $winbook->append_page (new_winpos_subpage_sendrecv, _('Send/Receive'));
1835 $winbook->append_page (new_winpos_subpage_fold, _('Folder'));
1836 $winbook->append_page (new_winpos_subpage_addrbook, _('Addressbook'));
1837 $winbook->append_page (new_winpos_subpage_accounts, _('Accounts'));
1838 $winbook->append_page (new_winpos_subpage_filtering, _('Filtering'));
1839 $winbook->append_page (new_winpos_subpage_prefs, _('Preferences'));
1840 $winbook->append_page (new_winpos_subpage_misc, _('Other'));
1845 sub print_version() {
1846 print $xl::s{about_title} . "\n";
1847 print $xl::s{about_version} . " $VERSION\n";
1848 print "Perl-GLib " . $Glib::VERSION;
1849 # version info stuff appeared in 1.040
1850 if ($Glib::VERSION >= 1.040) {
1851 print _(", built for ") . join(".", Glib->GET_VERSION_INFO)
1852 . _(", running with ") . join(".", &Glib::major_version,
1853 &Glib::minor_version, &Glib::micro_version);
1856 print "Perl-GTK2 " . $Gtk2::VERSION;
1857 if ($Gtk2::VERSION >= 1.040) {
1858 print _(", built for ") . join(".", Gtk2->GET_VERSION_INFO)
1859 . _(", running with ") . join(".", &Gtk2::major_version,
1860 &Gtk2::minor_version, &Gtk2::micro_version);
1863 my $clawsver = ($CLAWSV eq "") ?
1864 _("was not found!") :
1865 (_("returned version ") . $CLAWSV);
1866 print "Claws Mail " . $clawsver . "\n";
1869 # the command line help
1871 my $line = '-' x length ($xl::s{about_title}) . "\n";
1873 print $xl::s{about_title} . "\n";
1875 print _("Syntax:\n");
1876 print _(" clawsker [options]\n");
1877 print _("Options:\n");
1878 print _(" --help Prints this help screen.\n");
1879 print _(" --version Prints version infos.\n");
1880 print _(" --verbose More messages on standard output.\n");
1881 print _(" --alternate-config-dir <dir> Uses <dir> as Claws Mail config dir.\n");
1882 print _(" --clawsrc <file> Uses <file> as full resource name.\n");
1885 # handle errors which don't allow to run
1886 sub command_line_fatal {
1888 my $emsg = $xl::s{e_error} . $reason;
1889 error_dialog ($emsg);
1890 log_message ("$emsg", 'die');
1893 # parse the command line
1894 sub parse_command_line {
1895 $CLAWSV = get_claws_version ();
1897 while (defined($ARGV[$arg])) {
1911 /--use-claws-version/ && do {
1913 command_line_fatal ("required version")
1914 unless defined($ARGV[$arg]);
1915 command_line_fatal ("required a dotted numeric value")
1916 unless ($ARGV[$arg] =~ /[\d\.]+/);
1917 $CLAWSV = $ARGV[$arg];
1920 /--alternate-config-dir/ && do {
1922 command_line_fatal ($xl::s{e_requireddir})
1923 unless defined($ARGV[$arg]);
1924 command_line_fatal ($xl::s{e_notadir})
1925 unless -d $ARGV[$arg];
1926 $CONFIGDIR = $ARGV[$arg];
1928 unless ($CONFIGDIR =~ /.*\/$/);
1929 $ALTCONFIGDIR = TRUE;
1934 command_line_fatal($xl::s{e_requiredfile})
1935 unless defined($ARGV[$arg]);
1936 command_line_fatal($xl::s{e_notafile})
1937 unless -f $ARGV[$arg];
1938 set_rc_filename ($ARGV[$arg]);
1941 /.*/ && command_line_fatal (
1942 _("unknown option '{opt}'.\n", opt => $ARGV[$arg]));
1946 # eveything continues...
1950 # update the hidden preferences status from loaded values
1951 sub init_hidden_preferences {
1952 foreach my $hash (\%pr::beh, \%pr::col, \%pr::gui, \%pr::oth, \%pr::win) {
1953 foreach my $key (keys %$hash) {
1954 $HPVALUE{${$hash}{$key}[NAME]} = $PREFS{${$hash}{$key}[NAME]};
1960 # load current status from disc
1961 sub load_preferences {
1962 my $rc = get_rc_filename ();
1963 log_message ("Loading preferences from $rc\n");
1964 return FALSE unless check_rc_file ($rc);
1965 return FALSE unless check_claws_not_running ();
1969 if (/^([8a-z_]+)=(.*)$/) {
1970 $PREFS{$1} = decode('UTF-8', $2);
1977 # save current preferences to disc
1978 sub save_preferences {
1979 my $rc = get_rc_filename ();
1980 log_message ("Saving preferences to $rc\n");
1981 return FALSE unless check_rc_file ($rc);
1982 return FALSE unless check_claws_not_running ();
1983 my $rcbak = "$rc.backup";
1984 rename ($rc, $rcbak);
1986 open (RCB, "<$rcbak");
1989 if (/^([8a-z_]+)=(.*)$/) {
1990 if (defined($HPVALUE{$1})) {
1991 print RCF $1 . "=" . $HPVALUE{$1} . "\n";
1994 print RCF $_ . "\n";
1998 print RCF $_ . "\n";
2008 my $nb = Gtk2::Notebook->new;
2010 $nb->append_page (new_behaviour_page (), $xl::s{tab_behaviour});
2011 $nb->append_page (new_colours_page (), $xl::s{tab_colours});
2012 $nb->append_page (new_gui_page (), $xl::s{tab_gui});
2013 $nb->append_page (new_other_page (), $xl::s{tab_other});
2014 $nb->append_page (new_winpos_page (), $xl::s{tab_winpos});
2019 # create an about dialog
2020 sub new_about_dialog {
2022 my $title = $xl::s{about_title};
2023 my $lic = $xl::s{about_license};
2024 my $vers = $xl::s{about_version} . " $VERSION";
2026 "This program is free software: you can redistribute it and/or modify
2027 it under the terms of the GNU General Public License as published by
2028 the Free Software Foundation, either version 3 of the License, or
2029 (at your option) any later version.
2031 This program is distributed in the hope that it will be useful,
2032 but WITHOUT ANY WARRANTY; without even the implied warranty of
2033 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2034 GNU General Public License for more details.
2036 You should have received a copy of the GNU General Public License
2037 along with this program. If not, see <http://www.gnu.org/licenses/>.";
2038 my $year = "2007-2014";
2039 my $holder = "Ricardo Mones <ricardo\@mones.org>";
2040 my $url = "http://www.claws-mail.org/clawsker.php";
2042 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
2043 [qw/modal destroy-with-parent/],
2045 "<span size=\"x-large\" weight=\"bold\">$title</span>\n"
2046 . "<span size=\"large\">$vers</span>\n\n"
2047 . "<span color=\"blue\" size=\"large\">$url</span>\n\n"
2048 . "<span>Copyright $year by $holder</span>\n\n"
2049 . "<span size=\"large\">$lic</span>\n\n"
2050 . "<span size=\"small\">$license</span>");
2051 $dialog->set_title ($xl::s{about});
2056 # create buttons box
2057 sub new_button_box {
2058 my ($parent, $adlg) = @_;
2059 my $b_about = Gtk2::Button->new_from_stock ('gtk-about');
2060 my $b_exit = Gtk2::Button->new_from_stock ('gtk-quit');
2061 my $b_apply = Gtk2::Button->new_from_stock ('gtk-apply');
2062 # disable button until is really implemented
2063 # my $b_undo = Gtk2::Button->new_from_stock ('gtk-undo');
2064 my $hbox = Gtk2::HBox->new (FALSE, 5);
2066 $b_exit->signal_connect (clicked => sub { Gtk2->main_quit });
2067 $b_apply->signal_connect (clicked => sub { save_preferences ($parent) });
2068 # $b_undo->signal_connect (clicked => sub { undo_current_changes });
2069 $b_about->signal_connect (clicked => sub { $adlg->run; $adlg->hide });
2071 $hbox->pack_end ($b_apply, FALSE, FALSE, 0);
2072 $hbox->pack_end ($b_exit, FALSE, FALSE, 0);
2073 # $hbox->pack_end ($b_undo, FALSE, FALSE, 0);
2074 $hbox->pack_start ($b_about, FALSE, FALSE, 0);
2080 $main_window = Gtk2::Window->new ('toplevel');
2081 exit unless parse_command_line ();
2082 exit unless load_preferences ();
2083 exit unless init_hidden_preferences ();
2085 my $box = Gtk2::VBox->new (FALSE, 5);
2086 $box->set_border_width(3);
2087 my $about = new_about_dialog ();
2088 $box->pack_start (new_notebook (), FALSE, FALSE, 0);
2089 $box->pack_end (new_button_box ($main_window, $about), FALSE, FALSE, 0);
2090 $main_window->signal_connect (delete_event => sub { Gtk2->main_quit });
2091 $main_window->set_title ($xl::s{win_title});
2092 $main_window->add ($box);
2093 $main_window->show_all;