Want more features on Pastebin? Sign Up, it's FREE!
Guest

bug correction checkgmail ubuntu

By: a guest on Sep 18th, 2011  |  syntax: None  |  size: 199.90 KB  |  views: 538  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/perl -w
  2.  
  3. # CheckGmail
  4. # Uses Atom feeds to check Gmail for new mail and displays status in
  5. # system tray; optionally saves password in encrypted form using
  6. # machine-unique passphrase
  7.  
  8. # version 1.14pre2-svn (4/11/2010)
  9. # Copyright © 2005-10 Owen Marshall
  10.  
  11. # This program is free software; you can redistribute it and/or modify
  12. # it under the terms of the GNU General Public License as published by
  13. # the Free Software Foundation; either version 2 of the License, or (at
  14. # your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful, but
  17. # WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19. # General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with this program; if not, write to the Free Software
  23. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  24. # USA
  25.  
  26. use strict;
  27. # use utf8;
  28.  
  29.  
  30. ###########################
  31. # Command-line processing
  32. #
  33.  
  34. # global variables (can't be set global in the BEGIN block)
  35. my ($version, $silent, $nocrypt, $update, $notsexy, $profile, $disable_monitors_check,
  36.                 $private, $cookies, $popup_size, $hosted_tmp, $show_popup_delay,
  37.                 $popup_persistence, $usekwallet, $libsexy, $nologin, $mailno, $debug);
  38. BEGIN {
  39.         $version = "1.14pre2-svn";
  40.         $silent = 1;
  41.         $profile = "";
  42.         $cookies = 1;
  43.         $nologin = 1;
  44.         $show_popup_delay = 250;
  45.         $popup_persistence = 100;
  46.        
  47.         # simple command line option switch ...
  48.         foreach (@ARGV) {
  49.                 next unless m/\-(.*)/;
  50.                 for ($1) {
  51.                         /profile=(.*)/ && do {
  52.                                 $profile = "-$1";
  53.                                 last };
  54.                        
  55.                         /private/ && do {
  56.                                 $private = 1;
  57.                                 last };        
  58.                        
  59.                         /silent/ && do {
  60.                                 $silent = 1;
  61.                                 last };
  62.                                
  63.                         /disable-monitors-check/ && do {
  64.                                 $disable_monitors_check = 1;
  65.                                 last };
  66.                                
  67.                         /no-libsexy/ && do {
  68.                                 $notsexy = 1;
  69.                                 last };
  70.                                
  71.                         /no-login/ && do {
  72.                                 $nologin = 1;
  73.                                 last };
  74.                                
  75.                         /cookie_login/ && do {
  76.                                 $cookies = 1;
  77.                                 last };
  78.                                
  79.                         /no_cookies/ && do {
  80.                                 $cookies = 0;
  81.                                 last };
  82.                                
  83.                         # /label=(.*),(\d+)/ && do {
  84.                                 # $label_tmp{$1} = $2;
  85.                                 # last };
  86.                                
  87.                         /hosted=(.*)/ && do {
  88.                                 $hosted_tmp = $1;
  89.                                 last };
  90.                        
  91.                         /popup_delay=(\d+)/ && do {
  92.                                 $show_popup_delay = $1;
  93.                                 last };
  94.                                
  95.                         /popup_size=(\d+)/ && do {
  96.                                 $popup_size = $1;
  97.                                 last };
  98.                                
  99.                         /popup_persistence=(\d+)/ && do {
  100.                                 $popup_persistence = $1;
  101.                                 last };
  102.                        
  103.                         (/v$/ || /verbose/) && do {
  104.                                 $silent = 0;
  105.                                 print "CheckGmail v$version\nCopyright © 2005-7 Owen Marshall\n\n";
  106.                                 last };
  107.                                
  108.                         /nocrypt/ && do {
  109.                                 $nocrypt = 1;
  110.                                 last };
  111.                                
  112.                         /update/ && do {
  113.                                 $update = 1;
  114.                                 last };
  115.                                
  116.                                
  117.                         /numbers/ && do {
  118.                                 $mailno = 1;
  119.                                 last };
  120.                                
  121.                         /debug/ && do {
  122.                                 $debug = 1;
  123.                                 $silent = 0;
  124.                                 last };
  125.                                
  126.                                
  127.                                
  128.                         print "CheckGmail v$version\nCopyright © 2005-10 Owen Marshall\n\n";
  129.                         print "usage: checkgmail [-profile=profile_name] [-popup_delay=millisecs] [-hosted=hosted_domain] [-no_cookies] [-popup_persistence=millisecs] [-private] [-v | -verbose] [-nocrypt] [-no-libsexy] [-disable-monitors-check] [-numbers] [-update] [-h]\n\n";
  130.                         exit 1;
  131.                        
  132.                 }      
  133.         }
  134. }      
  135.        
  136.  
  137. #######################
  138. # Generate passphrase
  139. #
  140.  
  141. my ($passphrase);
  142. BEGIN {
  143.         # passphrase generator - needs to run before Crypt::Simple is loaded ...
  144.        
  145.         # The idea here is to at least make a non-local copy of .checkgmail
  146.         # secure (for example, that found on a backup disc) - it's
  147.         # impossible to store the password safely without requiring a user-entered
  148.         # passphrase otherwise, which defeats the purpose of it all. The
  149.         # passphrase used is based on the MAC address of the users ethernet
  150.         # setup if it exists and the entire info from uname - this is the
  151.         # most unique info I can think of to use here, though other suggestions
  152.         # are welcome!
  153.         #
  154.         # (obviously uname info isn't that unique unless you're running a kernel that
  155.         # you compiled yourself - which I do, but many don't ...)
  156.        
  157.         my $uname = `uname -a`;
  158.         chomp($uname);
  159.        
  160.         $_ = `whereis -b ifconfig`;
  161.         my ($ifconfig_path) = m/ifconfig:\s+([\w\/]+)/;
  162.         $ifconfig_path ||= "ifconfig";
  163.        
  164.         my $mac = `$ifconfig_path -a | grep -m 1 HWaddr | sed 's/ //g' | tail -18c`;
  165.         chomp($mac);
  166.        
  167.         $passphrase = "$mac$uname";
  168.         $passphrase =~ s/\s+//g;
  169. }
  170.  
  171.  
  172. ##################
  173. # Check packages
  174. #
  175.  
  176. BEGIN {
  177.         # A modular package checking routine ...
  178.         my $failed_packages;
  179.                
  180.         my $eval_sub = sub {
  181.                 print "$_\n" if $debug;
  182.                 eval $_;
  183.                 if ($@) {
  184.                         return unless m/(use|require)\s*([\w:-]+).*?\;/;
  185.                         my $package = $2;
  186.                        
  187.                         $failed_packages .= " $package ";                                      
  188.                         print "Warning: $package not found ...\n";
  189.                 }
  190.         };     
  191.        
  192.         # required packages
  193.         foreach (split("\n","
  194.         use Gtk2(\"init\");
  195.         use Gtk2::TrayIcon;
  196.         use threads;
  197.         use Thread::Queue;
  198.         use Thread::Semaphore;
  199.         use threads::shared;
  200.         use Encode;
  201.         use XML::Simple;
  202.         use FileHandle;
  203.         use LWP::UserAgent;
  204.         # use LWP::Debug qw(+);
  205.         use HTTP::Request::Common;
  206.         use Crypt::SSLeay;
  207.         ")) {&$eval_sub($_)};
  208.         if ($failed_packages) {
  209.                 unless ($failed_packages =~ /Gtk2\s/) {
  210.                         # Show a nice GTK2 error dialogue if we can ...
  211.                         my $explanation = "Try installing them if they're provided by your distro, and then run CheckGmail again ...";
  212.                         if ($failed_packages =~ /threads/i) {
  213.                                 $explanation = <<EOF;
  214. The threads packages are special: this means you're running a version of Perl that has been built without multi-threading support.  There may be a package for your distro that provides this, or you may have to rebuild Perl.
  215.  
  216. You'll also have to install the other packages listed above, and then run CheckGmail again ...
  217. EOF
  218.                                 chomp($explanation);
  219.                         }
  220.                         my $text = <<EOF;
  221. <b>CheckGmail v$version</b>
  222. Copyright &#169; 2005-6, Owen Marshall
  223.                        
  224. Sorry!  CheckGmail can't find the following package(s) on your system.  These packages are needed for CheckGmail to run.
  225.  
  226. <b>$failed_packages</b>
  227.  
  228. $explanation
  229.                                        
  230. <small>If that fails, you might have to download and install the packages from CPAN (http://search.cpan.org)</small>
  231. EOF
  232.                         chomp($text);
  233.                         my $dialog = Gtk2::MessageDialog->new_with_markup(undef,
  234.                                         'destroy-with-parent',
  235.                                         'error',
  236.                                         'ok',
  237.                                         $text,
  238.                                 );
  239.                         $dialog->run;
  240.                         $dialog->destroy;
  241.  
  242.                 }
  243.  
  244.                 print "\nCheckGmail requires the above packages to run\nPlease download and install from CPAN (http://search.cpan.org) and try again ...\n\n";
  245.                 exit 1;
  246.         }
  247.        
  248.         # Use kwallet if available
  249.         if (`which kwallet 2>/dev/null`) {
  250.                 $usekwallet = 1;
  251.                 $nocrypt = 1;
  252.         }
  253.        
  254.         # optional packages for encryption
  255.         unless ($nocrypt) {
  256.                 foreach (split("\n","
  257.                 use Crypt::Simple passphrase => \"$passphrase\";
  258.                 use Crypt::Blowfish;
  259.                 use FreezeThaw;
  260.                 use Compress::Zlib;
  261.                 use Digest::MD5;
  262.                 use MIME::Base64;
  263.                 ")) {&$eval_sub($_)};
  264.                 if ($failed_packages) {
  265.                         print "\nCheckGmail requires the above packages for password encryption\nPlease download and install from CPAN (http://search.cpan.org) if you want to use this feature ...\n\n";
  266.                         $nocrypt = 1;
  267.                 }
  268.         }
  269.        
  270.         # optional packages for urls in labels
  271.         foreach (split("\n","
  272.         use Gtk2::Sexy;
  273.         ")) {&$eval_sub($_)};
  274.         if (($failed_packages) && ($failed_packages =~ m/Sexy/i)) {
  275.                 print "\nCheckGmail uses Gtk2::Sexy for clickable URLs in mail messages\nPlease download and install from CPAN (http://search.cpan.org) if you want to use this feature ...\n\n";
  276.                 $libsexy = 0;
  277.         } else { $libsexy = 1 unless $notsexy; }
  278. }
  279.  
  280. # There's something wrong with Debian's Crypt::Simple, and it's causing problems ...
  281. unless (($nocrypt) || (eval("encrypt('test_encryption');"))) {
  282.         print "Hmmmm ... Crypt::Simple doesn't seem to be working!\nNot using Debian or Ubuntu, are you??\n\n";
  283.         print "Your best bet is to download the Crypt::Simple module from CPAN\n(http://search.cpan.org/~kasei/Crypt-Simple/) and install it manually.  Sorry!\n\n";
  284.         print "Disabling encrypted passwords for now ...\n\n";
  285.         $nocrypt = 1;
  286. }
  287.  
  288. # Show big fat warning if Crypt::Simple not found ...
  289. if ($nocrypt && !$silent && !$usekwallet) {
  290.         print <<EOF;
  291. *** Crypt::Simple not found, not working or disabled ***
  292. *** Passwords will be saved in plain text only ...   ***\n
  293. EOF
  294. }
  295.  
  296. ##################
  297. # Update utility
  298. #
  299.  
  300. # Pretty damn simple right now, but it works ...
  301. # ... idea taken from a script on the checkgmail forums (thanks, guys!)
  302.  
  303. # no version checking right now -- but does show the user a diff of the changes ...
  304.  
  305. if ($update) {
  306.         my $checkgmail_loc = $0;
  307.         my ($exec_dir) = $checkgmail_loc =~ m/(.*)checkgmail/;
  308.         chdir("/tmp");
  309.         print "Downloading latest version of checkgmail from SVN ...\n\n";
  310.         `wget http://checkgmail.svn.sourceforge.net/viewvc/*checkout*/checkgmail/checkgmail`;
  311.         print "\n\nDifferences between old and new versions:\n";
  312.         print "diff -urN checkgmail $checkgmail_loc\n";
  313.         my $diff_out = `diff -urN checkgmail $checkgmail_loc`;
  314.         print "$diff_out\n\n";
  315.         my $do_update = ask("\n\nOK to update to new version via 'sudo mv checkgmail $exec_dir'?(Y/n)");
  316.         if ($do_update eq "Y") {
  317.                 print "chmod a+x checkgmail\n";
  318.                 `chmod a+x checkgmail`;
  319.                 print "sudo mv checkgmail $exec_dir\n";
  320.                 `sudo mv checkgmail $exec_dir`;
  321.                 print "\nRestarting checkgmail ...\n";
  322.                 exec "$0";
  323.         } else {
  324.                 print "Update NOT performed ...\n";
  325.                 print "Deleting temp file ...\n";
  326.                 unlink("checkgmail");
  327.                 print "Continuing with application startup ...\n\n";
  328.         }
  329. }      
  330.  
  331.  
  332. sub ask {
  333.         my ($question,$prompt)=@_;
  334.         $prompt||="> ";
  335.         print "$question$prompt";
  336.         my $ans = <STDIN>;
  337.         chomp($ans);
  338.         return $ans;
  339. }
  340.                        
  341.                        
  342. ##########################################
  343. # Threads for non-blocking HTTP-requests
  344. #
  345.  
  346. # Shared variables between threads
  347. # - need to be declared here, unfortunately ... can't do it in the prefs hash :(
  348. my $gmail_address : shared;
  349. my $user : shared;
  350. my $passwd : shared;
  351. my $passwd_decrypt : shared;
  352. my $save_passwd : shared;
  353. my $translations : shared;
  354. my %trans : shared;
  355. my $language : shared;
  356. my $HOME : shared;
  357. my $icons_dir : shared;
  358. my $gmail_at : shared;
  359. my $gmail_ik : shared;
  360. my $gmail_hid : shared;
  361. my $gmail_sid : shared;
  362. my $gmail_gausr : shared;
  363. my $delay : shared;
  364. my %label_delay : shared;
  365. # my @labels : shared;
  366. my $hosted : shared = $hosted_tmp;
  367.  
  368. # URI escape codes to allow non alphanumeric usernames & passwords ...
  369. # thanks to Leonardo Ribeiro for suggesting this, and to the lcwa package for this implementation
  370. my %escapes : shared;
  371. for (0..255) {
  372.         $escapes{chr($_)} = sprintf("%%%02X", $_);
  373. }
  374.  
  375. # Thread controls
  376. my $request = new Thread::Queue;
  377. my $request_results = new Thread::Queue;
  378. my $http_status = new Thread::Queue;
  379. my $error_block = new Thread::Semaphore(0);
  380. my $fat_lady = new Thread::Semaphore(0);
  381. my $child_exit : shared = 0; # to signal exit to child
  382.  
  383. print "About to start new thread ...\n" if $debug;
  384. # Start http checking thread ...
  385. my $http_check = new threads(\&http_check);
  386. print "Parent: Process now continues ...\n" if $debug;
  387.  
  388.  
  389. #######################
  390. # Prefs and Variables
  391. #
  392.  
  393. print "Parent: Setting up global variables ...\n" if $debug;
  394. # Prefs hash
  395. my %pref_variables = (
  396.         user => \$user,
  397.         passwd => \$passwd,
  398.         hosted => \$hosted,
  399.         save_passwd => \$save_passwd,
  400.         atomfeed_address => \$gmail_address,
  401.         language => \$language,
  402.         delay => \$delay,
  403.         label_delay => \%label_delay,
  404.         popup_size => \$popup_size,
  405.         background => \(my $background),
  406.         gmail_command => \(my $gmail_command),
  407.         use_custom_mail_icon => \(my $custom_mail_icon),
  408.         use_custom_no_mail_icon => \(my $custom_no_mail_icon),
  409.         use_custom_error_icon => \(my $custom_error_icon),
  410.         mail_icon => \(my $mail_icon),
  411.         no_mail_icon => \(my $no_mail_icon),
  412.         error_icon => \(my $error_icon),
  413.         popup_delay => \(my $popup_delay),
  414.         show_popup_delay => \$show_popup_delay,
  415.         notify_command => \(my $notify_command),
  416.         nomail_command => \(my $nomail_command),
  417.         time_24 => \(my $time_24),
  418.         archive_as_read => \(my $archive_as_read),
  419. );
  420.  
  421. # Default prefs
  422. $delay = 120000;
  423. $popup_delay = 6000;
  424. $save_passwd = 0;
  425. $time_24 = 0;
  426. $archive_as_read = 0;
  427. $gmail_command = 'firefox %u';
  428. $language = 'English';
  429.  
  430. # Global variables
  431. $HOME = (getpwuid($<))[7];
  432. my $gmail_web_address = "https://mail.google.com/mail";
  433. my $prefs_dir = "$HOME/.checkgmail";
  434. $icons_dir = "$prefs_dir/attachment_icons";
  435. my $prefs_file_nonxml = "$prefs_dir/prefs$profile";
  436. my $prefs_file = "$prefs_file_nonxml.xml";
  437. $gmail_address = gen_prefix_url()."/feed/atom";
  438. # $gmail_address = $hosted ? "mail.google.com/a/$hosted/feed/atom" : "mail.google.com/mail/feed/atom";
  439.  
  440. # for every gmail action ...
  441. my %gmail_act = (
  442.         archive => 'rc_%5Ei',
  443.         read => 'rd',
  444.         spam => 'sp',
  445.         delete => 'tr',
  446.         star => 'st',
  447.         unstar => 'xst',
  448. );
  449.  
  450. # ... there's a gmail re-action :)
  451. my %gmail_undo = (
  452.         archive => 'ib',
  453.         read => 'ur',
  454.         spam => 'us',
  455.         delete => 'ib:trash',
  456.         star => 'xst',
  457. );
  458.  
  459. my @undo_buffer;
  460. my ($ua, $cookie_jar);
  461. my ($menu_x, $menu_y);
  462. my @popup_status;
  463. my $status_label;
  464. # my $message_flag;
  465.  
  466. print "Parent: Checking the existence of ~/.checkgmail ...\n" if $debug;
  467. # Create the default .checkgmail directory and migrate prefs from users of older versions
  468. unless (-d $prefs_dir) {
  469.         if (-e "$prefs_dir") {
  470.                 print "Moving ~/.checkgmail to ~/.checkgmail/prefs ...\n\n";
  471.                 rename("$HOME/.checkgmail", "$HOME/.checkgmailbak");
  472.                 mkdir($prefs_dir, 0777);
  473.                 rename("$HOME/.checkgmailbak", "$prefs_dir/prefs");
  474.         } else {
  475.                 # User hasn't run an old version, just create the dir
  476.                 mkdir($prefs_dir, 0700);
  477.         }
  478. }
  479.  
  480. unless (-d $icons_dir) {
  481.         mkdir($icons_dir, 0700);
  482. }
  483.  
  484.  
  485. #########
  486. # Icons
  487. #
  488.  
  489. print "Parent: Loading icon data ...\n" if $debug;
  490. # we load the pixmaps as uuencoded data
  491. my ($error_data, $no_mail_data, $mail_data, $compose_mail_data, $star_on_data, $star_off_data);
  492. load_icon_data();
  493.  
  494. my ($no_mail_pixbuf, $mail_pixbuf, $error_pixbuf, $star_pixbuf, $nostar_pixbuf);
  495. my ($custom_no_mail_pixbuf, $custom_mail_pixbuf, $custom_error_pixbuf);
  496. set_icons();
  497.  
  498. my $image = Gtk2::Image->new_from_pixbuf($no_mail_pixbuf);
  499.  
  500.  
  501. ##############
  502. # Setup tray
  503. #
  504.  
  505. print "Parent: Setting up system tray ...\n" if $debug;
  506. my $tray = Gtk2::TrayIcon->new("gmail");
  507. my $eventbox = Gtk2::EventBox->new;
  508. my $ebox2 = Gtk2::EventBox->new;
  509. my $tray_hbox = Gtk2::HBox->new(0,0);
  510. $tray_hbox->set_border_width(2);
  511.  
  512. my $win_notify;
  513. my ($notify_vbox_b, $notifybox);
  514. my ($old_x, $old_y);
  515. my $reshow;
  516. my $notify_enter = 0;
  517. my $popup_win;
  518. # my $scrolled;
  519. # my $vadj;
  520. my %new;
  521. my @messages;
  522. my %messages_ext;
  523. my %issued_h;
  524. my @labels;
  525.  
  526. $eventbox->add($ebox2);
  527. $ebox2->add($tray_hbox);
  528. $tray_hbox->pack_start($image,0,0,0);
  529.  
  530. # number of new mail messages (use -numbers)
  531. my $number_label;
  532. if ($mailno) {
  533.         $number_label = Gtk2::Label->new;
  534.         $number_label->hide;
  535.         $number_label->set_markup("0");
  536.         $tray_hbox->pack_start($number_label,0,0,2);
  537. }
  538.  
  539.  
  540. ########################
  541. # Read prefs and login
  542. #
  543.  
  544. print "Parent: Reading translations ...\n" if $debug;
  545. # Read translations if they exist ...
  546. read_translations();
  547.  
  548. print "Parent: Reading prefs ...\n" if $debug;
  549. # First time configuration ...
  550. unless (read_prefs()) {
  551.         show_prefs();
  552. }
  553.  
  554. # kdewallet integration if present - thanks to Joechen Hoenicke for this ...
  555. if (($usekwallet) && ($save_passwd)) {
  556.         $passwd = `kwallet -get checkgmail`;
  557.         chomp $passwd;
  558. }
  559.  
  560. # remove passwd from the pref_variables hash if the user requests it and prompt for login
  561. unless ($save_passwd && !$usekwallet) {
  562.         delete $pref_variables{passwd};
  563.         login($trans{login_title}) unless $passwd;
  564. }
  565.  
  566.  
  567. # changing the passphrase causes Crypt::Simple to die horribly -
  568. # here we use an eval routine to catch this and ask the user to login again
  569. # - this will only happen if you change your network interface card or
  570. # recompile your kernel ...
  571. unless ((eval ('$passwd_decrypt = decrypt_real($passwd);'))) {
  572.         login($trans{login_title});
  573. }
  574.  
  575. chomp($passwd_decrypt) if $passwd_decrypt;
  576.  
  577. # Continue building tray ...
  578. if ($background) {
  579.         my ($red, $green, $blue) = convert_hex_to_colour($background);
  580.         $eventbox->modify_bg('normal', Gtk2::Gdk::Color->new ($red, $green, $blue));
  581. }
  582.  
  583. $tray->add($eventbox);
  584. $tray->show_all;
  585. print "Parent: System tray now complete ...\n" if $debug;
  586.  
  587. ############################
  588. # enter/leave notification
  589. #
  590.  
  591. my $notify_vis = 0;
  592. my $notify_delay = 0;
  593. my $popup_delay_timeout;
  594. $eventbox->signal_connect('enter_notify_event', sub {
  595.         if ($show_popup_delay) {
  596.                 # Tooltip-like delay in showing the popup
  597.                 # return if $notify_vis;
  598.                 # $notify_delay=1;
  599.                 $notify_vis =1;
  600.                 $popup_delay_timeout = Glib::Timeout->add($show_popup_delay, sub {
  601.                         if ($win_notify && $notify_vis) {
  602.                                 # $notify_delay=0;
  603.                                 show_notify();
  604.                         }
  605.                 });
  606.         } else {
  607.                 if ($win_notify) {
  608.                         show_notify();
  609.                         $notify_vis=1;
  610.                 }
  611.         }
  612. });
  613.  
  614. $eventbox->signal_connect('leave_notify_event', sub {
  615.         if (@popup_status) {
  616.                 # This allows us to mouse into the popup by continuing to display it after
  617.                 # the mouse leaves the tray icon.  We only call it when there are messages
  618.                 # displayed - no one (I'm assuming! :) wants to be able to mouse into the
  619.                 # "No new mail" tooltip ... (well, OK, I actually did play around doing exactly
  620.                 # that when I wrote the routine, but that doesn't count ... :)
  621.                 my $persistence = Glib::Timeout->add($popup_persistence, sub {
  622.                         unless ($notify_enter) {
  623.                                 $win_notify->hide unless ($notify_enter || $notify_vis);
  624.                         }
  625.                         return 0;
  626.                 });
  627.         } else {
  628.                 $win_notify->hide if $win_notify;
  629.         }
  630.        
  631.         Glib::Source->remove($popup_delay_timeout) if $popup_delay_timeout;
  632.         $notify_vis=0;
  633. });
  634.  
  635.  
  636. ##################
  637. # Catch SIGs ...
  638. #
  639.  
  640. my %check;
  641. # my @labels;
  642.  
  643. $SIG{ALRM} = sub{
  644.         print "Alarm clock sent ...\n" unless $silent;
  645.         print "Resetting check delay ...\n" unless $silent;
  646.         reinit_checks();
  647. };
  648.  
  649. $SIG{TERM} = \&exit_prog;
  650.  
  651.  
  652. ############################
  653. # All set? Let's login ...
  654. #
  655.  
  656. print "Parent: Sending semaphore to child process ...\n" if $debug;
  657. # She's singing ...
  658. $fat_lady->up;
  659.  
  660.  
  661. ##############
  662. # Popup Menu
  663. #
  664.  
  665. my $menu;
  666. pack_menu();
  667.  
  668. #######################
  669. # Events and Mainloop
  670. #
  671.  
  672. # set popup trigger
  673. $eventbox->signal_connect('button_press_event', \&handle_button_press);
  674.  
  675. # set timeout for checking mail
  676. reinit_checks();
  677. my $real_check = Glib::Timeout->add(1000, \&check); # no wait-variables, so we're polling once a second.  No real CPU hit here ...
  678.  
  679. # do initial check
  680. queue_check();
  681.  
  682. Gtk2->main;
  683.  
  684. ################
  685. # Post GUI ...
  686. #
  687.  
  688. exit_prog();
  689.  
  690. sub exit_prog {
  691.         # After quitting the GUI we need to logout (if using the cookie_login method) and then clean up the threads ...
  692.         print "Exiting program ...\n" unless $silent;
  693.        
  694.         # if ($cookies) {
  695.                 # $http_status->enqueue("Logging out ...");
  696.                 # $request->enqueue("LOGOUT:mail.google.com/mail/?logout");
  697.                 # sleep 1;
  698.         # }
  699.        
  700.         $child_exit = 1;
  701.         queue_check();
  702.        
  703.         $http_check->join();
  704.        
  705.         exit 0;
  706. }
  707.  
  708.  
  709.  
  710. ##############################
  711. # Subroutines start here ...
  712. #
  713.  
  714.  
  715. ####################
  716. # Checking thread
  717. #
  718.  
  719. sub queue_check {
  720.         # Simply adds to the $request queue to signal the http_check thread
  721.         my ($label) = shift;
  722.         $label = $label ? "$label" : "";
  723.         $request->enqueue("GET:$gmail_address $label");
  724.         return 1;
  725. }
  726.  
  727. sub http_check {
  728.         # Threaded process for sending HTTP requests ...
  729.         print "Child: Checking thread now starting ... waiting for semaphore to continue\n" if $debug;
  730.        
  731.         # Variable initialisation isn't over until the fat lady sings ...
  732.         $fat_lady->down;
  733.         print "Initialisation complete\n" unless $silent;
  734.                
  735.         # set up the useragent ....
  736.         $ua = LWP::UserAgent->new();
  737.         $ua->requests_redirectable (['GET', 'HEAD', 'POST']);
  738.         # push @{ $ua->requests_redirectable }, 'POST';
  739.        
  740.         # set time-out - defaults to 90 seconds or $delay, whichever is shorter
  741.         $ua->timeout($delay/1000<90 ? $delay/1000 : 90);       
  742.                
  743.         # Get the cookie if requested
  744.         if ($cookies) {        
  745.                 use HTTP::Cookies;
  746.                 $cookie_jar = HTTP::Cookies->new();
  747.                
  748.                 $ua->cookie_jar($cookie_jar);
  749.                
  750.                 # Here we submit the login form to Google and the authorisation cookie gets saved
  751.                
  752.                 # This is only useful when Google's pulling an Error 503 party - it's less efficient
  753.                 # as there's a whole lot of unnecessary data associated with the process that slows
  754.                 # it all down ...
  755.                
  756.                 {
  757.                         # this loop is necessary as an incorrect login with Gmail's web form doesn't return a 401
  758.                         # So we simply check for the Gmail_AT cookie as confirmation of a successful login
  759.                         $http_status->enqueue($trans{notify_login});
  760.  
  761.                         my $URI_user = URI_escape($user);
  762.                         my $URI_passwd = URI_escape($passwd_decrypt);
  763.                        
  764.                         # clumsy error detection code uses this variable to differentiate between unable to
  765.                         # connect and unable to login - the Gmail login provides no unauthorised code if unsuccessful
  766.                         my $error;
  767.                                                
  768.                         # Thanks to that wonderful Firefox extension LiveHTTPHeaders for
  769.                         # deciphering the login form! :)
  770.                         unless ($hosted) {
  771.                                 # Normal Gmail login action ...
  772.                                 $error = http_get("Email=$URI_user&Passwd=$URI_passwd", "LOGIN");
  773.  
  774.                                 # $cookie_jar->scan(\&scan_at);
  775.                                 # unless ($error || !$gmail_sid || !$gmail_gausr) {
  776.                                         # $error = http_get("https://mail.google.com/mail/?pli=1&auth=$gmail_sid&gausr=$gmail_gausr", 'LOGIN');
  777.                                 # }
  778.  
  779.                                 # $error = http_get("https://mail.google.com/mail?nsr=0&auth=$gmail_sid&gausr=$gmail_gausr", "LOGIN");
  780.        
  781.                         } else {
  782.                                 # hosted domains work differently ...
  783.                                 # First we POST a login
  784.                                 # $error = http_get("https://www.google.com/a/$hosted/LoginAction|at=null&continue=http%3A%2F%2Fmail.google.com%2Fa%2F$hosted&service=mail&userName=$URI_user&password=$URI_passwd", "POST");
  785.                                 # thanks to Olinto Neto for this fix for hosted domains:
  786.                                 $error = http_get("https://www.google.com/a/$hosted/LoginAction2|at=null&continue=http%3A%2F%2Fmail.google.com%2Fa%2F$hosted&service=mail&Email=$URI_user&Passwd=$URI_passwd", "POST");
  787.  
  788.                                 # Then we grab the HID ("Hosted ID"?) cookie
  789.                                 $cookie_jar->scan(\&scan_at);
  790.                                
  791.                                 # And now we login with that cookie, which will give us the GMAIL_AT cookie!
  792.                                 unless ($error || !$gmail_hid) {                                       
  793.                                         $error = http_get("https://mail.google.com/a/$hosted?AuthEventSource=Internal&auth=$gmail_hid", 'GET');
  794.                                 }
  795.                         }
  796.  
  797.                         $cookie_jar->scan(\&scan_at);
  798.                        
  799.                         unless ($gmail_at) {
  800.                                 unless ($error) {
  801.                                         $http_status->enqueue("Error: 401 Unauthorised");
  802.                                         $error_block->down;
  803.                                 } else {
  804.                                         # simple block to prevent checkgmail hogging CPU if not connected!
  805.                                         sleep 30;
  806.                                 }
  807.                                
  808.                                 redo;
  809.                         }
  810.                 }
  811.  
  812.                 print "Logged in ... AT = $gmail_at\n" unless $silent;
  813.         }              
  814.  
  815.         while ((my $address = $request->dequeue) && ($child_exit==0)) {
  816.                 # this is a clumsy hack to allow POST methods to do things like mark messages as spam using the same queue
  817.                 # (can't send anonymous arrays down a queue, unfortunately!)
  818.                 # Now also used for labels ...
  819.                 my ($method, $address_real, $label) = ($address =~ /(.*?):([^\s]*)\s*(.*)/);
  820.                
  821.                 my $logon_string = "";
  822.                 unless ($cookies) {
  823.                         my $URI_user = URI_escape($user);
  824.                         my $URI_passwd = URI_escape($passwd_decrypt);
  825.                         $logon_string = "$URI_user:$URI_passwd\@";
  826.                 }
  827.                
  828.                 $request_results->enqueue(http_get("https://$logon_string$address_real", $method, $label))
  829.         }              
  830. }
  831.  
  832.  
  833. sub scan_at {
  834.         my $cookie_ref = \@_;
  835.                
  836.         unless ($silent) {
  837.                 # use Data::Dumper;
  838.                 # print Dumper(\@_);
  839.                 print "Saved cookie: ",$cookie_ref->[1],"\n",$cookie_ref->[2],"\n\n";
  840.         }
  841.        
  842.         # This sub is invoked for each cookie in the cookie jar.
  843.         # What we're looking for here is the Gmail authorisation key, GMAIL_AT
  844.         # - this is needed to interface with the Gmail server for actions on mail messages ...
  845.         # or the HID cookie which is set with Gmail hosted domains
  846.        
  847.         if ($cookie_ref->[1] =~ m/GMAIL_AT/) {
  848.                 $gmail_at = $cookie_ref->[2];
  849.         }
  850.        
  851.         if ($cookie_ref->[1] =~ m/HID/) {
  852.                 $gmail_hid = $cookie_ref->[2];
  853.         }
  854.        
  855.         if ($cookie_ref->[1] =~ m/GAUSR/) {
  856.                 $gmail_gausr = $cookie_ref->[2];
  857.         }
  858.        
  859.         if ($cookie_ref->[1] =~ m/SID/) {
  860.                 $gmail_sid = $cookie_ref->[2];
  861.         }
  862. }
  863.  
  864.  
  865. sub http_get {
  866.         # this is now called from the http-checking thread
  867.         # - all GUI activities are handled through queues
  868.         my ($address, $method, $label) = @_;
  869.         $label = "/$label" if $label;
  870.         $label||="";
  871.         my $error;
  872.        
  873.         if ($method eq 'POST') {
  874.                 # quick hack to use the POST method for Gmail actions ...
  875.                 my ($add1, $add2) = ($address =~ m/(.*)\|(.*)/);
  876.                 # print "($add1, $add2)\n" unless $silent;
  877.                
  878.                 my $req = HTTP::Request->new($method => $add1);
  879.                 $req->content_type('application/x-www-form-urlencoded');
  880.                 $req->content($add2);
  881.                
  882.                 $ua->request($req);
  883.                 return;
  884.                
  885.         } elsif ($method eq 'POST_MB') {
  886.                 # quick hack to grab the message text ...
  887.                 my ($add1, $add2) = ($address =~ m/(.*)\|(.*)/);
  888.                 # print "($add1, $add2)\n" unless $silent;
  889.                
  890.                 my $req = HTTP::Request->new('POST' => $add1);
  891.                 $req->content_type('application/x-www-form-urlencoded');
  892.                 $req->content($add2);
  893.                
  894.                 my $response = $ua->request($req);
  895.                
  896.                 my $http = $response->content;
  897.                 $label =~ s/\///g;
  898.                 return "LABEL=$label\n$http";
  899.                
  900.         } elsif ($method eq 'LOGIN') {
  901.                 # New LOGIN method written by Gerben van der Lubbe on Oct 6, 2009.
  902.                 # (based in turn on vially's (https://sourceforge.net/users/vially/) PHP code.
  903.                
  904.                 # Well, we did get a URL here, but it doesn't make any sense to send both LOGIN and the URL to this function.
  905.                 # So, this URL is just the username and password addition.
  906.                 my $req = HTTP::Request->new('GET' => "https://www.google.com/accounts/ServiceLogin?service=mail");
  907.                 my $response = $ua->request($req);
  908.                 if($response->is_error) {
  909.                         my $code = $response->code;
  910.                         my $message = $response->message;
  911.                         $error = "Error: $code $message";
  912.                         $http_status->enqueue($error);
  913.                         return $error;
  914.                 }
  915.                 my $http = $response->content;
  916.  
  917.                 # Find the value of the GALX input field
  918.                 my ($post_galx) = ($http =~ m/"GALX".*?value="(.*?)"/ismg);
  919.                 unless ($post_galx) {
  920.                         print "Error: No GALX input field found\n";
  921.                         return "Error: No GALX input field found";
  922.                 }
  923.                 $post_galx = URI_escape(URI_unescape($1));
  924. +               my $galx = URI_unescape($1);
  925. +               $post_galx = URI_escape($galx);
  926.                
  927.                 # Find the data to post
  928.                 my $post_data;
  929.  
  930.                 $post_data = "ltmpl=default&ltmplcache=2&continue=http://mail.google.com/mail/?ui%3Dhtml&service=mail&rm=false&scc=1&GALX=$post_galx&$address&PersistentCookie=yes&rmShown=1&signIn=Sign+in&asts=";
  931.                
  932.                 # Hide personal data from verbose display
  933.                 my $post_display = $post_data;
  934.                 $post_display =~ s/Email=(.*?)&/Email=******/;
  935.                 $post_display =~ s/Passwd=(.*?)&/Passwd=******/;
  936.                 print "Logging in with post data $post_display\n" unless $silent;
  937.  
  938.                 # Send the post data to the login URL
  939.                 my $post_req = HTTP::Request->new('POST' => "https://www.google.com/accounts/ServiceLoginAuth?service=mail");
  940.                 $post_req->content_type('application/x-www-form-urlencoded');
  941.                 $post_req->content($post_data);
  942. +               $post_req->header('Cookie' => "GALX=$galx");
  943.                 my $post_response = $ua->request($post_req);
  944.                 if ($post_response->is_error) {
  945.                         my $code = $response->code;
  946.  
  947.                         my $message = $response->message;
  948.                         $error = "Error: $code $message";
  949.                         $http_status->enqueue($error);
  950.                         return $error;
  951.                 }
  952.                 my $post_http = $post_response->content;
  953.  
  954.                 # Find the location we're directed to, if any
  955.                 if ($post_http =~ m/location\.replace\("(.*)"\)/) {
  956.                         # Rewrite the redirect URI.
  957.                         # This URI uses \xXX. Replace those, and just to be sure \\. \" we don't handle, though.
  958.                         my $redirect_address = $1;
  959.                         $redirect_address =~ s/\\\\/\\/g;
  960.                         $redirect_address =~ s/\\x([0-9a-zA-Z]{2})/chr(hex($1))/eg;
  961.                         print "Redirecting to ".$redirect_address."\n" unless $silent;
  962.  
  963.                         # And request the actual URL
  964.                         my $req = HTTP::Request->new('GET' => $redirect_address);
  965.                         my $response = $ua->request($req);
  966.                         if($response->is_error) {
  967.                                 my $code = $response->code;
  968.                                 my $message = $response->message;
  969.                                 $error = "Error: $code $message";
  970.                                 $http_status->enqueue($error);
  971.                                 return $error;
  972.                         }
  973.                 } else {
  974.                         print "No location.replace found in HTML\n" unless $silent;
  975.                 }
  976.                
  977.                 # Last part of the login process, in order to get Gmail's globar variables
  978.                 # (including the all-important ik parameter)
  979.                 $req = HTTP::Request->new('GET' => "https://mail.google.com/mail/?shva=1");
  980.                 $response = $ua->request($req);
  981.                 if($response->is_error) {
  982.                         my $code = $response->code;
  983.                         my $message = $response->message;
  984.                         $error = "Error: $code $message";
  985.                         $http_status->enqueue($error);
  986.                         return $error;
  987.                 }
  988.                 $http = $response->content;
  989.                
  990.                 # The globals.  Lots of goodies here, which we don't need right now
  991.                 # but which might come in handy later ...
  992.                 if ($http =~ m/var GLOBALS=\[,.*?,.*?,.*?,.*?,.*?,.*?,.*?,.*?,"(.*?)"/) {
  993.                         $gmail_ik = $1;
  994.                 } else {
  995.                         print "Unable to find gmail_ik ... full message text won't work :(\n\n";
  996.                 }
  997.  
  998.                
  999.                 return $error;
  1000.                
  1001.         } elsif ($method eq 'LOGOUT') {
  1002.                 # a  hack to streamline the logout process
  1003.                 print "Logging out of Gmail ...\n" unless $silent;
  1004.                
  1005.                 my $req = HTTP::Request->new('GET' => "$address");
  1006.                 my $response = $ua->request($req);
  1007.                
  1008.                 return;
  1009.         } elsif ($method eq 'IMAGE') {
  1010.                 # a hack to grab attachment images
  1011.                 my $image_name = $label;
  1012.                
  1013.                 my $req = HTTP::Request->new(GET => "$address");
  1014.                 my $response = $ua->request($req);
  1015.                 if ($response->is_error) {
  1016.                         print "error retrieving!\n";
  1017.                         return 0;
  1018.                 }
  1019.                
  1020.                 my $http = $response->content;
  1021.                
  1022.                 open (DATA, ">$icons_dir$image_name") || print "Error: Could not open file for writing: $!\n";
  1023.                 print DATA $http;
  1024.                 close DATA;
  1025.                
  1026.                 # we need a semaphore here so the GUI doesn't redraw until the image is obtained
  1027.                 $error_block->up;
  1028.                
  1029.                 return 0;
  1030.         }
  1031.  
  1032.        
  1033.         $http_status->enqueue($trans{notify_check});
  1034.                
  1035.         my $req = HTTP::Request->new($method => "$address$label");
  1036.  
  1037.         my $response = $ua->request($req);
  1038.         if ($response->is_error) {
  1039.                 my $code = $response->code;
  1040.                 my $message = $response->message;
  1041.                 $error = "Error: $code $message";
  1042.                 $http_status->enqueue($error);
  1043.                
  1044.                 # Incorrect username/password??
  1045.                 if ($code == 401) {
  1046.                         # Set a semaphore block to prevent multiple incorrect logins
  1047.                         # This is probably unneccessary because of the locked variables in the Login dialogue
  1048.                         # ... still, doesn't hurt to be careful ... :)
  1049.                         $error_block->down;
  1050.                 }
  1051.                
  1052.                 return 0;
  1053.         }
  1054.        
  1055.         my $http = $response->content;
  1056.        
  1057.         $label =~ s/\///g;
  1058.                
  1059.         return "LABEL=$label\n$http";
  1060. }
  1061.  
  1062.  
  1063. ############################
  1064. # Main thread checking ...
  1065. #
  1066.  
  1067. sub check {
  1068.         # The check routine is polled every second:
  1069.         # we always check first to see if there's a new status message and display it
  1070.         # Errors are also caught at this point ...
  1071.         my $status = $http_status->dequeue_nb;
  1072.         if ($status) {
  1073.                 notify($status);
  1074.                 if ($status =~ m/error/i) {
  1075.                         # General error notification
  1076.                         $image->set_from_pixbuf($error_pixbuf);
  1077.                        
  1078.                         if ($status =~ m/401/) {
  1079.                                 # Unauthorised error
  1080.                                 login("Error: Incorrect username or password");
  1081.                                 Gtk2->main_iteration while (Gtk2->events_pending);
  1082.                                
  1083.                                 # queue a new request to check mail
  1084.                                 queue_check();
  1085.                                
  1086.                                 # and release the semaphore block ...
  1087.                                 $error_block->up;
  1088.                         }
  1089.  
  1090.                 }
  1091.         }
  1092.                
  1093.         # Return if there aren't any Atom feeds in the queue ...
  1094.         return 1 unless my $atom = $request_results->dequeue_nb;
  1095.        
  1096.         if ($atom =~ m/while\(1\);/) {
  1097.                 # datapack shortcircuit
  1098.                 # we use this to grab the full text of messages ...
  1099.                
  1100.                 # uncomment below to see the datapack structure
  1101.                 print "atom:\n$atom\n\n" unless $silent;
  1102.                
  1103.                 # as of 2/11/10, we can no longer use the old ui=1 datapack
  1104.                 # Unfortunately, the new ui=2 datapack is quite a bit less pleasant
  1105.                 # to use, with no nice "mb" cues ...
  1106.                
  1107.                 my ($mb, $ma);
  1108.                
  1109.                 # if ($atom =~ m/\["ms",.*?,.*?,.*?,.*?,.*?,.*?,.*?,.*?,\[.*?"\].*?\[.*?\[.*?,.*?,.*?,.*?,.*?,"(.*?)",\[/s) {#.*?,.*?,.*?,\[,.*?,.*?,.*?,.*?,.*?,"(.*?)",\[/g);
  1110.                         # print "\n\n-----\nYYYYY!\n$1\n";
  1111.                 # } else {
  1112.                         # print "\n\n-----\nNOPE!\n\n";
  1113.                 # }
  1114.                
  1115.                 # See what you've made me do, Google??  Just look at this fugly regex ...
  1116.                 while ($atom =~ m/\["ms",.*?,.*?,.*?,.*?,.*?,.*?,.*?,.*?,\[.*?"\].*?\[.*?\[.*?,.*?,.*?,.*?,.*?,"(.*?)",\[/sg) {
  1117.                         $mb .= "$1";
  1118.                 }
  1119.                                
  1120.                 # ma is the attachment, if any
  1121.                 # (I suspect this doesn't work anymore with the new datapack ...)
  1122.                 while ($atom =~ m/\["ma",\[(.*?)\]/g) {
  1123.                         my $att = $1;
  1124.                         $ma = "/mail/images/paperclip.gif"; # default attachment
  1125.                         # print "attachment =\n$att\n\n";
  1126.                         if ($att =~ m/src\\u003d\\\"(.*?)\\\"/g) {
  1127.                                 $ma = $1;
  1128.                         }
  1129.                 }
  1130.                
  1131.                 $mb = clean_text_body($mb);
  1132.                 print "cleaned text is\n$mb\n\n" unless $silent;
  1133.                                                
  1134.                 # cs is the message id
  1135.                 my ($cs) = ($atom =~ m/.*\["ms","(.*?)"/s);
  1136.                 $messages_ext{$cs}->{text} = $mb;
  1137.                 $messages_ext{$cs}->{shown} = 1;
  1138.                 $messages_ext{$cs}->{attachment} = $ma;
  1139.                
  1140.                
  1141.                 notify();
  1142.                 return 1;
  1143.         }
  1144.        
  1145.         # Process the Atom feed ...
  1146.         my ($label, $atom_txt) = ($atom =~ m/LABEL=(.*?)\n(.*)/s);
  1147.         # $label ||= "";
  1148.         my $gmail = XMLin($atom_txt, ForceArray => 1);
  1149.        
  1150.         # # Uncomment below to view xml->array structure
  1151.         # use Data::Dumper;
  1152.         # print Dumper($gmail);
  1153.        
  1154.         # Count messages ...
  1155.         $new{$label} = 0;
  1156.         if ($gmail->{entry}) {
  1157.                 $new{$label} = @{$gmail->{entry}};
  1158.         }
  1159.        
  1160.         my $new_mail =0;
  1161.        
  1162.         # remove old messages with the same label ...
  1163.         my @new_messages;
  1164.         foreach my $i (0 .. @messages) {
  1165.                 next unless $messages[$i];
  1166.                 if ($messages[$i]->{label} eq $label) {
  1167.                         delete $issued_h{$messages[$i]->{time}};
  1168.                 } else {
  1169.                         push (@new_messages, $messages[$i]);
  1170.                 }
  1171.         }
  1172.         @messages = @new_messages;
  1173.        
  1174.         # print "\n--------\nmessages: @messages\n";
  1175.        
  1176.                        
  1177.         if ($new{$label}) {
  1178.                 # New messages - get the details ...
  1179.                 my (@tip_text, $popup_text, $popup_authors, @issued_l);
  1180.                 $image->set_from_pixbuf($mail_pixbuf);
  1181.                                        
  1182.                 CHECK: for my $i (0 .. $new{$label}-1) {
  1183.                        
  1184.                         my $author_name = $gmail->{entry}->[$i]->{author}->[0]->{name}->[0];
  1185.                         my $author_mail = $gmail->{entry}->[$i]->{author}->[0]->{email}->[0];
  1186.                         my $issued = $gmail->{entry}->[$i]->{issued}->[0];
  1187.                         my $title = $gmail->{entry}->[$i]->{title}->[0];
  1188.                         my $summary = $gmail->{entry}->[$i]->{summary}->[0];
  1189.                         my $href = $gmail->{entry}->[$i]->{link}->[0]->{href};
  1190.                        
  1191.                         my ($id) = ($href =~ m/message_id=(.*?)&/);
  1192.                                                
  1193.                         # No subject, summary or author name?
  1194.                         ref($title) && ($title = $trans{notify_no_subject});
  1195.                         ref($summary) && ($summary = $trans{notify_no_text});
  1196.                         my $author = $author_name || $author_mail;
  1197.                                                
  1198.                         # clean text for Pango compatible display ...
  1199.                         $title = clean_text_and_decode($title);
  1200.                         $author = clean_text_and_decode($author);
  1201.                         $summary = clean_text_and_decode($summary);
  1202.                        
  1203.                         my ($year, $month, $day, $hour, $min, $sec) = ($issued =~ m/(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)Z/);
  1204.                         my $time_abs = $sec+$min*60+$hour*3600+$day*86400+$month*2678400+$year*32140800;
  1205.                        
  1206.                         # check for duplicate labels
  1207.                         foreach (@messages) {
  1208.                                 next CHECK if $_->{id} eq $id;
  1209.                         }
  1210.                        
  1211.                         unless ($private) {
  1212.                                 push @messages, { href=>$href, id=>$id, time=>$time_abs, issued=>$issued, title=>$title, author=>$author, body=>$summary, label=>$label };
  1213.                         }
  1214.                                                
  1215.                         # Save authors and time stamps for popup text below ...
  1216.                         $issued_h{$time_abs}=$author;
  1217.                 }
  1218.                
  1219.                 # create the mail details window ...                           
  1220.                 notify('', $new{$label}-1);
  1221.                
  1222.                 # Now check if a popup needs to be displayed:
  1223.                
  1224.                 # find previously unread entries and remove            
  1225.                 if (@popup_status) {
  1226.                         for my $i (0 .. $#popup_status) {
  1227.                                 next unless $popup_status[$i];
  1228.                                 # print "$i: ",$popup_status[$i]->{time}," - ", $issued_h{$popup_status[$i]->{time}},"\n";
  1229.                                 $issued_h{$popup_status[$i]->{time}} && delete $issued_h{$popup_status[$i]->{time}};
  1230.                         }
  1231.                 }
  1232.                
  1233.                 # build unread authors from what's left
  1234.                 foreach (keys(%issued_h)) {
  1235.                         # eliminate duplicate authors
  1236.                         next if $popup_authors && ($popup_authors =~ m/\Q$issued_h{$_}\E/);
  1237.                         $popup_authors .= ($popup_authors ? ", $issued_h{$_}" : "$issued_h{$_}");
  1238.                 }
  1239.                
  1240.                 # Create popup text
  1241.                 if ($popup_authors) {
  1242.                         $popup_authors =~ s/, ([\w\s-]+)$/ $trans{notify_and} $1/; # replace final comma with "and"
  1243.                         $popup_authors = clean_text_and_decode($popup_authors);
  1244.                         $popup_text = "<span foreground=\"#000000\"><small>$trans{notify_new_mail}$popup_authors ...</small></span>";
  1245.                 }
  1246.                
  1247.                 # Save current unread list
  1248.                 @popup_status = @messages;
  1249.                                
  1250.                 # Finally, display popup if there's any new mail
  1251.                 # and run any command that the user has specified in the prefs
  1252.                 if ($popup_text) {
  1253.                         popup($popup_text);
  1254.                         run_command($notify_command) if $notify_command;
  1255.                 }
  1256.                                
  1257.         } elsif (!$new_mail) {         
  1258.                 notify();
  1259.         }
  1260.        
  1261.         # Need to return true to keep the timeout going ...
  1262.         return 1;
  1263. }
  1264.  
  1265. # Note -- for some reason (?? why ??) the title does not need decoding; all other data apparently does.  Very strange ...
  1266. sub clean_text_and_decode {
  1267.         ($_) = @_;
  1268.         # some basic replacements so that the text is readable ...
  1269.         # (these aren't used by pango markup, unlike other HTML escapes)
  1270.         s/&hellip;/\.\.\./g;
  1271.         s/&\s/\&amp; /g;
  1272.         s/\\u003c/</g;
  1273.         # s/\\n//g;
  1274.         s/<br\s*\/*\\*>/\n/g;
  1275.         s/</\&lt;/g;
  1276.         s/>/\&gt;/g;
  1277.         s/&(?>([\w\d\,\.]+))(?!;)/\&amp;$1/g; #not a great fix, but at least it's simple (heavy irony ... :)
  1278.         s/&nbsp;/ /g;
  1279.         # s/\\n/\n/g;
  1280.         # Encode::from_to($body, 'utf-8', 'iso-8859-15');
  1281.         # eval { decode("utf8", $_, Encode::FB_CROAK); };
  1282.         # my $body_decode = $@ ? $_ : decode("utf8", $_);
  1283.         #my $body_decode= decode("utf-8", $_);
  1284.        
  1285.         # I have no idea why this works ...
  1286.         my $body_encode = encode("utf8", $_);
  1287.         my $body_decode = decode("utf8", $body_encode);
  1288.        
  1289.         return $body_decode;
  1290. }
  1291.  
  1292. sub clean_text {
  1293.         ($_) = @_;
  1294.         # some basic replacements so that the text is readable ...
  1295.         # (these aren't used by pango markup, unlike other HTML escapes)
  1296.         s/&hellip;/\.\.\./g;
  1297.         s/&\s/\&amp; /g;
  1298.         s/\\u003c/</g;
  1299.         # s/\\n//g;
  1300.         s/<br\s*\/*\\*>/\n/g;
  1301.         s/</\&lt;/g;
  1302.         s/>/\&gt;/g;
  1303.         s/&(?>([\w\d\,\.]+))(?!;)/\&amp;$1/g; #not a great fix, but at least it's simple (heavy irony ... :)
  1304.         s/&nbsp;/ /g;
  1305.         # s/\\n/\n/g;
  1306.         return $_;
  1307. }
  1308.  
  1309.  
  1310. sub clean_text_body {
  1311.         ($_) = @_;
  1312.         # some basic replacements so that the text is readable ...
  1313.         # (these aren't used by pango markup, unlike other HTML escapes)
  1314.         s/&hellip;/\.\.\./g;
  1315.         # s/&\s/\&amp; /g;
  1316.         s/\\u003c/</g;
  1317.         s/\>/>/g;
  1318.         s/\\u([\d\w]{4})/"&#".hex($1).";";/gex;
  1319.         s/&\#(\d+)\;/chr($1)/gex;
  1320.                        
  1321.         s/\\t/\t/g;
  1322.         # s/\s\\n//g;
  1323.         # s/\\n\s//g;
  1324.         # s/\\n/ /g;
  1325.         s/(\w)\\n(\w)/$1 $2/g;
  1326.         s/\\n//g;
  1327.         s/(\\n)+/\n/g;
  1328.         s/\\(.)/$1/g;
  1329.         s/<br\s*\/*\\*>/\n/g;
  1330.         s/<p\s*\/*\\*>/\n\n/g;
  1331.         s/<\/div\\*>/\n/g; # GMail now uses div blocks for paragraphs!  Who'd have thought they could be so abhorrent?
  1332.         # s/(?:\n\s*){3,}/\n\n/sg;
  1333.         s/<.*?>//g unless $libsexy;
  1334.         s/<a.*?(href=".*?").*?>(.*?)<\/a>/<-a $1>$2<-\/a>/ig;
  1335.         s/<[^-].*?>//g;
  1336.         # s/<([\/]|[^a])[^a].*?>//g;
  1337.         # s/<a\s+>(.*?)<\/a>/$1/g;
  1338.         s/<-/</g;
  1339.         s/\\'/'/g;
  1340.         # s/</\&lt;/g;
  1341.         # s/>/\&gt;/g;
  1342.         # s/&(?>([\w\d\,\.]+))(?!;)/\&amp;$1/g; #not a great fix, but at least it's simple (heavy irony ... :)
  1343.         s/&nbsp;/ /g;
  1344.         # s/\\n/\n/g;
  1345.         # Encode::from_to($body, 'utf-8', 'iso-8859-15');
  1346.         # eval { decode("utf8", $_, Encode::FB_CROAK); };
  1347.         # my $body_decode = $@ ? $_ : decode("utf8", $_);
  1348.         # my $body_encode = encode("utf8", $_);
  1349.        
  1350.         # I have no idea why this works either ...
  1351.         my $body_decode = decode("utf8", $_);
  1352.  
  1353.         return $body_decode;
  1354. }
  1355.  
  1356.  
  1357. #################################
  1358. # External command handling ...
  1359. #
  1360.  
  1361. sub open_gmail {
  1362.         # a routine to open Gmail in a web browser ... or not, as the user prefers!
  1363.         my $command = $gmail_command;
  1364.         my $login_address = get_login_href($gmail_web_address);
  1365.         run_command($command, $login_address);
  1366. }
  1367.  
  1368. sub run_command {
  1369.         my ($command, $address) = @_;
  1370.        
  1371.         # We now allow the use of '%u' to delineate the web address
  1372.         if ($address) {
  1373.                 $command =~ s/\%u/"$address"/g;
  1374.         }
  1375.        
  1376.         # allows the number of new messages to be used in scripts! :)
  1377.         if ($command =~ m/\%m/) {
  1378.                 my $messages = @messages;
  1379.                 $command =~ s/\%m/$messages/g;
  1380.         }
  1381.        
  1382.         print "run command: $command\n" unless $silent;
  1383.         system("$command &");
  1384. }
  1385.  
  1386.  
  1387. #############
  1388. # Prefs I/O
  1389. #
  1390.  
  1391. # These routines read or save anything referenced in %pref_variables ... isn't that neat?
  1392. # NB: as of version 1.9.3, we've moved over to an XML format - this allows us to save more complex data structures
  1393. # (i.e. hashes for the check delay on various labels) with ease ...
  1394.  
  1395. sub read_prefs {
  1396.         unless (-e $prefs_file) {
  1397.                 # old, deprecated simple text tile method ...
  1398.                 return unless -e $prefs_file_nonxml;
  1399.                 open(PREFS, "<$prefs_file_nonxml") || die "Cannot open $prefs_file_nonxml for reading: $!\n";
  1400.                
  1401.                 # lock shared variables
  1402.                 lock($user);
  1403.                 lock($passwd);
  1404.                 lock($save_passwd);
  1405.                 lock($gmail_address);
  1406.                
  1407.                 while (<PREFS>) {
  1408.                         s/[\n\r]//g;
  1409.                         next if /^$/;
  1410.                         my ($key, $value) = split m/ = /;
  1411.                         my $pointer = $pref_variables{$key};
  1412.                         $$pointer = $value;
  1413.                 }
  1414.                 close (PREFS);
  1415.         } else {
  1416.                 # new xml method
  1417.                 # read translations file if it exists
  1418.                 open(PREFS, "<$prefs_file") || die("Could not open $prefs_file for reading: $!\n");
  1419.                 my $prefs = join("",<PREFS>);
  1420.                 close PREFS;
  1421.                
  1422.                 # lock shared variables
  1423.                 lock($user);
  1424.                 lock($passwd);
  1425.                 lock($save_passwd);
  1426.                 lock($gmail_address);
  1427.                                
  1428.                 my $prefs_xml = XMLin($prefs, ForceArray => 1);
  1429.  
  1430.                 ## For debugging ...
  1431.                 # use Data::Dumper;
  1432.                 # print Dumper $prefs_xml;
  1433.                
  1434.                 foreach my $i (keys %pref_variables) {
  1435.                         my $pointer = $pref_variables{$i};
  1436.                         for (ref($pointer)) {
  1437.                                 /SCALAR/ && do {
  1438.                                         $$pointer = $prefs_xml->{$i} if defined($prefs_xml->{$i});
  1439.                                         last };
  1440.                                
  1441.                                 /HASH/ && do {
  1442.                                         # last unless ref($prefs_xml->{$i}) eq "HASH";
  1443.                                         %$pointer = %{ $prefs_xml->{$i}->[0]} if defined($prefs_xml->{$i}->[0]);
  1444.                                         last };
  1445.                                        
  1446.                                 /ARRAY/ && do {
  1447.                                         # last unless ref($prefs_xml->{$i}) eq "HASH";
  1448.                                         @$pointer = @{ $prefs_xml->{$i}->[0]} if defined($prefs_xml->{$i}->[0]);
  1449.                                         last };
  1450.                         }
  1451.                 }
  1452.         }
  1453.        
  1454.         convert_labels_from_hash();
  1455.         set_icons();
  1456.         set_language();
  1457.        
  1458.         return 1;
  1459. }
  1460.  
  1461. sub write_prefs {
  1462.         # new XML-based preferences routine ...
  1463.        
  1464.         # lock shared variables
  1465.         lock($user);
  1466.         lock($passwd);
  1467.         lock($save_passwd);
  1468.         lock($gmail_address);
  1469.        
  1470.         convert_labels_from_array();
  1471.                
  1472.         my %xml_out;
  1473.         foreach my $i (keys %pref_variables) {
  1474.                 my $pointer = $pref_variables{$i};
  1475.                 for (ref($pointer)) {
  1476.                                 /SCALAR/ && do {
  1477.                                         $xml_out{$i} = $$pointer if defined($$pointer);
  1478.                                         last };
  1479.                                
  1480.                                 /HASH/ && do {
  1481.                                         $xml_out{$i} = {%$pointer}; # if defined(%$pointer);
  1482.                                         last };
  1483.                         }
  1484.                
  1485.         }
  1486.        
  1487.         my $prefs = XMLout(\%xml_out, AttrIndent=>1);
  1488.         open(PREFS, ">$prefs_file") || die("Could not open $prefs_file file for writing: $!");
  1489.         binmode PREFS, ":utf8";
  1490.         print PREFS $prefs;
  1491.         close PREFS;
  1492. }
  1493.  
  1494. # This seems a bit silly, I know - but I can't seem to share a multi-dimensional data structure,
  1495. # and if I keep things as a straightforward hash then we can't have nice GUI editing
  1496. # (because I need an ordered structure to do this)
  1497. #
  1498. # It's very cumbersome though - I'm not all that happy with this solution!!!
  1499. sub convert_labels_from_hash {
  1500.         @labels=();    
  1501.         push @labels, {label => "$_", delay => $label_delay{$_}} foreach sort(keys(%label_delay));
  1502. }
  1503.  
  1504. sub convert_labels_from_array {
  1505.         %label_delay=();
  1506.         $label_delay{$_->{label}} = $_->{delay} foreach @labels;
  1507. }
  1508.  
  1509.  
  1510. #####################
  1511. # Notify popups ...
  1512. #
  1513.  
  1514. sub notify {
  1515.         # popup notify code to replace tooltips
  1516.         # Why?  Because tooltips can't do nice pango markup! :-)
  1517.         my ($status, $text) = @_;      
  1518.         my $new_mail = @messages;
  1519.        
  1520.         # display number of messages
  1521.         if ($mailno) {
  1522.                 # print "setting \"$new_mail\"\n";
  1523.                 $number_label->set_markup("$new_mail");
  1524.                 $new_mail ? $number_label->show : $number_label->hide;
  1525.                 # $new_mail ? $number_label->set_markup("$new_mail") : $number_label->set_markup(" ")
  1526.         }
  1527.        
  1528.         my @sorted_messages = sort {$b->{time} <=> $a->{time}} @messages;
  1529.         @messages = @sorted_messages;
  1530.        
  1531.         unless ($status) {
  1532.                 if ($new_mail > 1) {
  1533.                         $status = "<small><span foreground=\"#000000\">$trans{notify_multiple1}$new_mail$trans{notify_multiple2}</span></small>";
  1534.                 } elsif ($new_mail) {
  1535.                         $status = "<small><span foreground=\"#000000\">$trans{notify_single1}$new_mail$trans{notify_single2}</span></small>";
  1536.                 } else {
  1537.                         # No new messages
  1538.                         $image->set_from_pixbuf($no_mail_pixbuf);
  1539.                        
  1540.                         my $time = $time_24 ? `date +\"%k:%M\"` : `date +\"%l:%M %P\"`;
  1541.                         chomp($time);
  1542.                         $time =~ s/^\s+//g;
  1543.                         $status = "<span foreground=\"#000000\">$trans{notify_no_mail} <small>($time)</small></span>";
  1544.                        
  1545.                         @popup_status = ();
  1546.                        
  1547.                         run_command($nomail_command) if $nomail_command;
  1548.                 }
  1549.         }
  1550.  
  1551.        
  1552.         # strip markup for command line ...
  1553.         unless ($silent) {
  1554.                 $_ = $status;
  1555.                 s/\<.*?\>//g;
  1556.                 print "$_\n";
  1557.         }
  1558.        
  1559.         # Check if popup is currently displayed ...
  1560.         my $redisplay = 1 if (($win_notify) && ($win_notify->visible));
  1561.        
  1562.         # *sigh* ... bloody gtk won't let me do this:
  1563.         # if (($win_notify) && ($win_notify->visible)) {
  1564.                 # print "getting vadj\n";
  1565.                 # $vadj = $scrolled->get_vadjustment if $scrolled;
  1566.         # } else {
  1567.                 # $vadj = 0;
  1568.         # }
  1569.        
  1570.         # Don't destroy the popup containing mail messages if we're just doing another check ...
  1571.         if (@messages && $redisplay && ($status =~ /$trans{notify_check}/ || $status =~ /$trans{notify_undoing}/)) {
  1572.                 $status_label->set_markup("<span foreground=\"#000000\"><small>$status</small></span>");
  1573.                 show_notify();
  1574.                 return;
  1575.         }
  1576.        
  1577.         # return if (@messages && !defined($text));
  1578.        
  1579.         if (!@messages && !$notify_vis && $redisplay) {
  1580.                 $redisplay = 0;
  1581.                 $win_notify->hide;
  1582.         }
  1583.        
  1584.         # Create new popup
  1585.         my $win_notify_temp = Gtk2::Window->new('popup');
  1586.        
  1587.         # If we're using enter/leave notification, we need to create borders with eventboxes
  1588.         # - if there's a gap between window and eventbox, moving into the eventbox is considered a leave notification from the window!
  1589.         my $notifybox_b = Gtk2::EventBox->new;
  1590.         $notifybox_b->modify_bg('normal', Gtk2::Gdk::Color->new (0, 0, 0));
  1591.        
  1592.         # we use the vbox here simply to give an outer border ...
  1593.         $notify_vbox_b = Gtk2::VBox->new (0, 0);
  1594.         $notify_vbox_b->set_border_width(1);
  1595.         $notifybox_b->add($notify_vbox_b);
  1596.        
  1597.         $notifybox = Gtk2::EventBox->new;
  1598.         $notifybox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1599.         $notify_vbox_b->pack_start($notifybox,0,0,0);
  1600.        
  1601.         # we use the vbox here simply to give an internal border ...
  1602.         my $notify_vbox = Gtk2::VBox->new (0, 0);
  1603.         $notify_vbox->set_border_width(4);
  1604.         $notifybox->add($notify_vbox);
  1605.        
  1606.         # display mail status
  1607.         my $status_hbox = Gtk2::HBox->new(0,0);
  1608.         $notify_vbox->pack_start($status_hbox,0,0,0);
  1609.        
  1610.         $status_label = Gtk2::Label->new;
  1611.         $status_label->set_markup("<span foreground=\"#000000\">$status</span>");
  1612.         $status_hbox->pack_start($status_label,0,0,0);
  1613.        
  1614.         # $message_flag = @text ? 1 : 0;
  1615.        
  1616.         if (@messages && $cookies) {
  1617.                 # mark all as read button and spacer
  1618.                 my $mark_all_label = Gtk2::Label->new;
  1619.                 $mark_all_label->set_markup(text_norm($trans{mail_mark_all}, "", ""));
  1620.                
  1621.                 my $mark_all_ebox = Gtk2::EventBox->new();
  1622.                 $mark_all_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1623.                 my $ma1 = $mark_all_ebox->signal_connect(enter_notify_event=>sub{$mark_all_label->set_markup(text_u($trans{mail_mark_all}, "", ""));});
  1624.                 my $ma2 = $mark_all_ebox->signal_connect(leave_notify_event=>sub{$mark_all_label->set_markup(text_norm($trans{mail_mark_all}, "", ""));});
  1625.                
  1626.                 $mark_all_ebox->signal_connect(button_press_event=>sub{
  1627.                         @undo_buffer=();
  1628.                         my @labels_to_check;
  1629.                         foreach (@messages) {
  1630.                                 my $id = $_->{id};
  1631.                                 push @labels_to_check, $_->{label};
  1632.                                 $request->enqueue(gen_action_url($gmail_act{read},$id));
  1633.                                 $mark_all_label->set_markup(text_u($trans{mail_marking_all}, "", ""));
  1634.                                
  1635.                                 # don't want to try to disconnect the signals multiple times!
  1636.                                 if ($ma1) {
  1637.                                         $mark_all_ebox->signal_handler_disconnect($ma1);
  1638.                                         $mark_all_ebox->signal_handler_disconnect($ma2);
  1639.                                         $ma1 = $ma2 = undef;
  1640.                                 }
  1641.                                 show_notify();
  1642.                                 push @undo_buffer, [$id, $_->{label}, 'read'];
  1643.                         }
  1644.                         queue_check($_) foreach @labels_to_check;
  1645.                 });
  1646.                
  1647.                 $mark_all_ebox->add($mark_all_label);
  1648.                 $status_hbox->pack_end($mark_all_ebox,0,0,0);
  1649.                
  1650.         }
  1651.        
  1652.         if (@messages) {
  1653.                 my $spacer = Gtk2::Label->new;
  1654.                 $spacer->set_markup("<small> </small>");
  1655.                 $notify_vbox->pack_start($spacer,0,0,0);
  1656.         }
  1657.                
  1658.         # display messages
  1659.         my $number = @messages;
  1660.         my $count;
  1661.         foreach (@messages) {
  1662.                 $count++;
  1663.                 my ($href, $id, $title, $author, $body, $label, $att) = ($_->{href}, $_->{id}, $_->{title}, $_->{author}, $_->{body}, $_->{label}, $_->{attachment});
  1664.                 my $mb;
  1665.                 if ($messages_ext{$id}) {
  1666.                         $mb = $messages_ext{$id}->{text};
  1667.                         $body = $messages_ext{$id}->{text} if $messages_ext{$id}->{shown};
  1668.                 }
  1669.                                
  1670.                 # --- title and author ---
  1671.                                
  1672.                 my $hbox_t = Gtk2::HBox->new(0,0);
  1673.                 $notify_vbox->pack_start($hbox_t,0,0,0);
  1674.                
  1675.                 my $vbox_t = Gtk2::VBox->new(0,0);
  1676.                 $hbox_t->pack_start($vbox_t,0,0,0);    
  1677.                
  1678.                 my $hbox_tt = Gtk2::HBox->new(0,0);
  1679.                 $vbox_t->pack_start($hbox_tt,0,0,0);
  1680.                        
  1681.                                
  1682.                
  1683.                 my $title_l = Gtk2::Label->new;
  1684.                 $title_l->set_markup("<span foreground=\"#000000\"><b><u>$title</u></b></span><small> <span foreground=\"#006633\">$label</span></small>");
  1685.                 $title_l->set_line_wrap(1);
  1686.                
  1687.                 my $title_l_ebox = Gtk2::EventBox->new();
  1688.                 $title_l_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1689.                 my $s1 = $title_l_ebox->signal_connect(enter_notify_event=>sub{$title_l->set_markup("<span foreground=\"#000000\"><b><u><i>$title</i></u></b></span><small> <span foreground=\"#006633\">$label</span></small>")});
  1690.                 my $s2 = $title_l_ebox->signal_connect(leave_notify_event=>sub{$title_l->set_markup("<span foreground=\"#000000\"><b><u>$title</u></b></span><small> <span foreground=\"#006633\">$label</span></small>")});
  1691.                 $title_l_ebox->signal_connect(button_press_event=>sub{
  1692.                         # grabbing the full text of a message
  1693.                         return unless $cookies;
  1694.                         $title_l_ebox->signal_handler_disconnect($s1);
  1695.                         $title_l_ebox->signal_handler_disconnect($s2);
  1696.                         unless ($mb) {
  1697.                                 # print "Message ID = $id\n";
  1698.                                 # yep, here's the magic code.  This accesses the datapack, which we read with a little hack in the check routine ...
  1699.                                 #$request->enqueue("GET:".gen_prefix_url()."/?ui=1&view=cv&search=all&th=$id&qt=&prf=1&pft=undefined&rq=xm&at=$gmail_at");
  1700.                                
  1701.                                 # As of 3/11/10, Gmail has removed access to the old ui=1 version of Gmail
  1702.                                 # ui=2 requires a POST command to get the datapack (which has also changed formats slightly)
  1703.                                 $request->enqueue("POST_MB:".gen_prefix_url()."/?ui=2&ik=$gmail_ik&rid=&view=cv&prf=1&_reqid=&nsc=1|&mb=0&rt=j&cat=all&search=cat&th=$id&at=$gmail_at");
  1704.                         } else {
  1705.                                 # this allows the message text to be toggled ...
  1706.                                 # oh yes, we're all about usability here, folks! :)
  1707.                                 $messages_ext{$id}->{shown} = 1-$messages_ext{$id}->{shown};
  1708.                         }                              
  1709.                         notify();
  1710.                 });
  1711.                
  1712.                 $title_l_ebox->add($title_l);          
  1713.                 $hbox_tt->pack_start($title_l_ebox,0,0,0);
  1714.                
  1715.                 # short spacer
  1716.                 my $title_spacer = Gtk2::HBox->new(0,0);
  1717.                 $title_spacer->set_border_width(1);
  1718.                 $vbox_t->pack_start($title_spacer,0,0,0);
  1719.                
  1720.                 # my god, gtk2 has the most stupid packing routines imaginable!!!
  1721.                 my $hbox_from = Gtk2::HBox->new(0,0);
  1722.                 $vbox_t->pack_start($hbox_from,0,0,0);
  1723.                
  1724.                
  1725.                 # --- Starring messages ---
  1726.                 # Note: there's no way to check the star-status of a message from the atom feed
  1727.                 # of course, we're gradually getting to the stage where it'd be much easier to
  1728.                 # poll the server via http requests now, than to retrieve messages via the feed.
  1729.                 # (I'm thinking about it!  Definitely thinking about it ... :)
  1730.                 #
  1731.                 # In the meantime, the icon adds a quick way to star messages that you'd like
  1732.                 # to come back to later, but ignore for the present.
  1733.                
  1734.                 # Star icons are taken from Mozilla Firefox 3 (http://getfirefox.com), licensed under
  1735.                 # the Creative Commons license
  1736.                
  1737.                 my $star_i = Gtk2::Image->new();
  1738.                 if ($messages_ext{$id}->{star}) {
  1739.                         $star_i->set_from_pixbuf($star_pixbuf);
  1740.                 } else {
  1741.                         $messages_ext{$id}->{star}=0;
  1742.                         $star_i->set_from_pixbuf($nostar_pixbuf);
  1743.                 }
  1744.                
  1745.                 my $star_ebox = Gtk2::EventBox->new();
  1746.                 $star_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1747.                 $star_ebox->signal_connect(button_press_event=>sub{
  1748.                         # setting the star
  1749.                         return unless $cookies;
  1750.                         $messages_ext{$id}->{star} = 1-$messages_ext{$id}->{star};
  1751.                         if ($messages_ext{$id}->{star}) {
  1752.                                 $star_i->set_from_pixbuf($star_pixbuf);
  1753.                                 $request->enqueue(gen_action_url($gmail_act{star},$id));
  1754.                         } else {
  1755.                                 $star_i->set_from_pixbuf($nostar_pixbuf);
  1756.                                 $request->enqueue(gen_action_url($gmail_act{unstar},$id));
  1757.                         }                              
  1758.                 });    
  1759.                
  1760.                 $star_ebox->add($star_i);              
  1761.                
  1762.                 my $star_space = Gtk2::HBox->new(0,0);
  1763.                 $star_space->set_border_width(3);      
  1764.                
  1765.                 # From: line (with star)
  1766.                 my $from_l = Gtk2::Label->new;
  1767.                 $from_l->set_markup("<b>$trans{notify_from}</b> $author");
  1768.                 $from_l->set_line_wrap(1);
  1769.                
  1770.                 $hbox_from->pack_start($from_l,0,0,0);
  1771.                 $hbox_from->pack_start($star_space,0,0,0);     
  1772.                 $hbox_from->pack_start($star_ebox,0,0,0);      
  1773.                
  1774.                
  1775.                 # --- Attachment icon ---
  1776.                 if ($messages_ext{$id}->{attachment}) {
  1777.                         $att = $messages_ext{$id}->{attachment};
  1778.                         my ($image_name) = ($att =~ m/.*\/(.*)$/);             
  1779.                        
  1780.                         check_icon($att);
  1781.                        
  1782.                         my $att_image = Gtk2::Image->new_from_pixbuf(set_icon("$icons_dir/$image_name", 16));
  1783.                         $hbox_t->pack_end($att_image,0,0,0);
  1784.                        
  1785.                         # my $title_att = Gtk2::Label->new;
  1786.                         # $title_att->set_markup("<span foreground=\"#000000\"><small>[$att]</small></span>");
  1787.                         # $title_att->set_line_wrap(1);
  1788.                         # $hbox_t->pack_end($title_att,0,0,0);
  1789.                        
  1790.                 }
  1791.                        
  1792.  
  1793.                
  1794.                 # --- options ---
  1795.                
  1796.                 my $hbox_opt = Gtk2::HBox->new(0,0);
  1797.                 $notify_vbox->pack_start($hbox_opt,0,0,0);
  1798.                
  1799.                 my $command_label = Gtk2::Label->new;
  1800.                 $command_label->set_markup(text_norm($trans{mail_open}, ""));
  1801.                
  1802.                 my $title_ebox = Gtk2::EventBox->new();
  1803.                 $title_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1804.                 $title_ebox->signal_connect(button_press_event=>sub{
  1805.                         run_command($gmail_command, get_login_href($href));
  1806.                         if ($cookies) {
  1807.                                 # mark as read if we can - otherwise opened messages hang around ...
  1808.                                 ### probably need an option for this!
  1809.                                 $request->enqueue(gen_action_url($gmail_act{read},$id));
  1810.                                 @undo_buffer=([$id, $label, 'read']);
  1811.                                 queue_check($label);
  1812.                         }
  1813.                 });
  1814.                 $title_ebox->signal_connect(enter_notify_event=>sub{$command_label->set_markup(text_u($trans{mail_open},""));});
  1815.                 $title_ebox->signal_connect(leave_notify_event=>sub{$command_label->set_markup(text_norm($trans{mail_open}, ""));});
  1816.                
  1817.                 $title_ebox->add($command_label);
  1818.                 $hbox_opt->pack_start($title_ebox,0,0,0);
  1819.                
  1820.                
  1821.                 if ($cookies) {
  1822.                         # We can only do these cute things when we've got a Gmail_at string to work with ...
  1823.                         # thus it's limited to the cookie_login method
  1824.                        
  1825.                         # ---- mark as read
  1826.                        
  1827.                         my $mark_label = Gtk2::Label->new;
  1828.                         $mark_label->set_markup(text_norm($trans{mail_mark}));
  1829.                        
  1830.                         my $mark_ebox = Gtk2::EventBox->new();
  1831.                         $mark_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1832.                         my $s1 = $mark_ebox->signal_connect(enter_notify_event=>sub{$mark_label->set_markup(text_u($trans{mail_mark}));});
  1833.                         my $s2 = $mark_ebox->signal_connect(leave_notify_event=>sub{$mark_label->set_markup(text_norm($trans{mail_mark}));});
  1834.                         $mark_ebox->signal_connect(button_press_event=>sub{
  1835.                                 $request->enqueue(gen_action_url($gmail_act{read},$id));
  1836.                                 $mark_label->set_markup(text_u($trans{mail_marking}));
  1837.                                 $mark_ebox->signal_handler_disconnect($s1);
  1838.                                 $mark_ebox->signal_handler_disconnect($s2);
  1839.                                 show_notify();
  1840.                                 @undo_buffer=([$id, $label, 'read']);
  1841.                                 queue_check($label);
  1842.                         });
  1843.                         $mark_ebox->add($mark_label);
  1844.                         $hbox_opt->pack_start($mark_ebox,0,0,0);
  1845.                        
  1846.                         # ---- archive
  1847.                        
  1848.                         my $archive_label = Gtk2::Label->new;
  1849.                         $archive_label->set_markup(text_norm($trans{mail_archive}));
  1850.                        
  1851.                         my $archive_ebox = Gtk2::EventBox->new();
  1852.                         $archive_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1853.                         my $s1a = $archive_ebox->signal_connect(enter_notify_event=>sub{$archive_label->set_markup(text_u($trans{mail_archive}));});
  1854.                         my $s2a = $archive_ebox->signal_connect(leave_notify_event=>sub{$archive_label->set_markup(text_norm($trans{mail_archive}));});
  1855.                         $archive_ebox->signal_connect(button_press_event=>sub{
  1856.                                 $request->enqueue(gen_action_url($gmail_act{archive},$id));
  1857.                                 $request->enqueue(gen_action_url($gmail_act{read},$id)) if $archive_as_read;
  1858.                                 $archive_label->set_markup(text_u($trans{mail_archiving}));
  1859.                                 $archive_ebox->signal_handler_disconnect($s1a);
  1860.                                 $archive_ebox->signal_handler_disconnect($s2a);
  1861.                                 show_notify();
  1862.                                 @undo_buffer=([$id, $label, 'archive']);
  1863.                                 push(@{$undo_buffer[0]}, 'read') if $archive_as_read;
  1864.                                 queue_check($label);
  1865.                         });
  1866.                         $archive_ebox->add($archive_label);
  1867.                         $hbox_opt->pack_start($archive_ebox,0,0,0);
  1868.                        
  1869.                         # ---- report spam
  1870.                        
  1871.                         my $spam_label = Gtk2::Label->new;
  1872.                         $spam_label->set_markup(text_norm($trans{mail_report_spam}));
  1873.                        
  1874.                         my $spam_ebox = Gtk2::EventBox->new();
  1875.                         $spam_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1876.                         my $s1s = $spam_ebox->signal_connect(enter_notify_event=>sub{$spam_label->set_markup(text_u($trans{mail_report_spam}));});
  1877.                         my $s2s = $spam_ebox->signal_connect(leave_notify_event=>sub{$spam_label->set_markup(text_norm($trans{mail_report_spam}));});
  1878.                         $spam_ebox->signal_connect(button_press_event=>sub{
  1879.                                 $request->enqueue(gen_action_url($gmail_act{read},$id));
  1880.                                 $request->enqueue(gen_action_url($gmail_act{spam},$id));
  1881.                                 $spam_label->set_markup(text_u($trans{mail_reporting_spam}));
  1882.                                 $spam_ebox->signal_handler_disconnect($s1s);
  1883.                                 $spam_ebox->signal_handler_disconnect($s2s);
  1884.                                 show_notify();
  1885.                                 @undo_buffer=([$id, $label, 'spam', 'read']);
  1886.                                 queue_check($label);
  1887.                         });
  1888.                         $spam_ebox->add($spam_label);
  1889.                         $hbox_opt->pack_start($spam_ebox,0,0,0);
  1890.                        
  1891.                         # ---- delete
  1892.                        
  1893.                         my $delete_label = Gtk2::Label->new;
  1894.                         $delete_label->set_markup(text_norm($trans{mail_delete}));
  1895.                        
  1896.                         my $delete_ebox = Gtk2::EventBox->new();
  1897.                         $delete_ebox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  1898.                         my $s1d = $delete_ebox->signal_connect(enter_notify_event=>sub{$delete_label->set_markup(text_u($trans{mail_delete}));});
  1899.                         my $s2d = $delete_ebox->signal_connect(leave_notify_event=>sub{$delete_label->set_markup(text_norm($trans{mail_delete}));});
  1900.                         $delete_ebox->signal_connect(button_press_event=>sub{
  1901.                                 $request->enqueue(gen_action_url($gmail_act{delete},$id));
  1902.                                 $delete_label->set_markup(text_u($trans{mail_deleting}));
  1903.                                 $delete_ebox->signal_handler_disconnect($s1d);
  1904.                                 $delete_ebox->signal_handler_disconnect($s2d);
  1905.                                 show_notify();
  1906.                                 @undo_buffer=([$id, $label, 'delete']);
  1907.                                 queue_check($label);
  1908.                         });
  1909.                         $delete_ebox->add($delete_label);
  1910.                         $hbox_opt->pack_start($delete_ebox,0,0,0);
  1911.                        
  1912.                 }
  1913.                
  1914.                 # --- Mail body ---
  1915.                
  1916.                 my $hbox_b = Gtk2::HBox->new(0,0);
  1917.                 $notify_vbox->pack_start($hbox_b,0,0,0);
  1918.                
  1919.                 my $body_l;
  1920.                 if ($libsexy) {
  1921.                         $body_l = Gtk2::Sexy::UrlLabel->new;
  1922.                         $body_l->signal_connect(url_activated => sub{
  1923.                                 my ($url_label, $url) = @_;
  1924.                                 run_command($gmail_command, $url);
  1925.                         });
  1926.                 } else {
  1927.                         $body_l = Gtk2::Label->new;
  1928.                 }
  1929.                 $body_l->set_line_wrap(1);
  1930.                 # my ($w, $h) = $body_l->get_size_request;
  1931.                 # print "($w, $h)\n";
  1932.                 $body_l->set_size_request($popup_size) if $popup_size;
  1933.                 # $body_l->set_width_chars(20);
  1934.                 # $body_l->set_selectable(1);
  1935.                 # $body_l->set_max_width_chars(100);
  1936.  
  1937.                
  1938.                 my $term = ($count == $number) ? "" : "\n";
  1939.                 $body_l->set_markup("<span foreground=\"grey25\">$body</span>$term");
  1940.                 $hbox_b->pack_start($body_l,0,0,0);
  1941.         }
  1942.                                
  1943.         $win_notify_temp->add($notifybox_b);
  1944.                
  1945.         # If popup was previously displayed, re-show it ...
  1946.         if ($redisplay) {
  1947.                 show_notify($win_notify_temp);
  1948.         } else {
  1949.                 $win_notify->destroy if $win_notify;
  1950.                 $win_notify="";
  1951.                 $win_notify = $win_notify_temp;
  1952.         }
  1953. }
  1954.  
  1955.  
  1956. sub check_icon {
  1957.         # download the icon if it doesn't exist ...
  1958.         my ($image) = @_;
  1959.         my ($image_name) = ($image =~ m/.*\/(.*)$/);
  1960.         unless (-e "$icons_dir/$image_name") {
  1961.                 print "Retrieving $image from mail.google.com ...\n" unless $silent;
  1962.                 $request->enqueue("IMAGE:mail.google.com$image $image_name");
  1963.                 # return unless $data;
  1964.                 # print "data is $data\ngoing to >$icons_dir/$image_name";
  1965.                 # open (DATA, ">$icons_dir/$image_name") || die "Could not open file for writing: $!\n";
  1966.                 # print DATA $data;
  1967.                 # close DATA;
  1968.                 $error_block->down;
  1969.         }
  1970. }
  1971.  
  1972. sub http_get_main {
  1973.         my ($address) = @_;
  1974.        
  1975.         my $ua = LWP::UserAgent->new();        
  1976.         my $req = HTTP::Request->new(GET => "$address");
  1977.  
  1978.         my $response = $ua->request($req);
  1979.         if ($response->is_error) {
  1980.                 print "error!\n";
  1981.                 return 0;
  1982.         }
  1983.        
  1984.         my $http = $response->content;
  1985.        
  1986.         return $http;
  1987.        
  1988.        
  1989. }
  1990.  
  1991. sub text_norm {
  1992.         my ($body, $pre, $post) = @_;
  1993.         $pre = "| " unless defined($pre);
  1994.         $post = " " unless defined($post);
  1995.         return "$pre<small><span foreground=\"darkred\">$body</span></small>$post";
  1996. }
  1997.  
  1998. sub text_u {
  1999.         my ($body, $pre, $post) = @_;
  2000.         $pre = "| " unless defined($pre);
  2001.         $post = " " unless defined($post);
  2002.         return "$pre<small><span foreground=\"darkred\"><u>$body</u></span></small>$post";
  2003. }
  2004.  
  2005.  
  2006. sub get_login_href {
  2007.         # Login directly to gmail ...
  2008.         $_ = shift;
  2009.        
  2010.         # The following is for people who like to stay permanently logged in ...
  2011.         # (enable with -no-login on the command-line for now ...)
  2012.         return $_ if $nologin;
  2013.        
  2014.         my ($options) = m/.*?\?(.*)/;
  2015.         my $options_uri = $options ? "?&$options" : "";
  2016.        
  2017.         s/@/%40/g; # @ needs to be escaped in gmail address
  2018.         s/http([^s])/https$1/g; # let's make it secure!
  2019.        
  2020.         print "login command is: $_\n" unless $silent;
  2021.  
  2022.         my $escaped_uri = URI_escape($_);      
  2023.         my $URI_user = URI_escape($user);
  2024.         my $URI_passwd = URI_escape($passwd_decrypt);
  2025.        
  2026.         my $target_uri;
  2027.         if ($hosted) {
  2028.                 $target_uri = "http://mail.google.com/a/$hosted/$options_uri";
  2029.         } else {
  2030.                 $target_uri = "https://www.google.com/accounts/ServiceLoginAuth?ltmpl=yj_wsad&ltmplcache=2&continue=$escaped_uri&service=mail&rm=false&ltmpl=yj_wsad&Email=$URI_user&Passwd=$URI_passwd&rmShown=1&null=Sign+in";
  2031.         }
  2032.        
  2033.         return $target_uri;
  2034. }
  2035.        
  2036.  
  2037. sub gen_action_url {
  2038.         # I have a feeling that these complicated form post arguments are going to change
  2039.         # without warning more than once in the future - collating things here should make
  2040.         # updates a bit easier!
  2041.         my ($act, $id) = @_;
  2042.         my $search;
  2043.        
  2044.         # Now that we can grab the full text of messages, we'd better clear the cache while we're here ...
  2045.         # NB - I realise this won't remove all cached text, in the rare event someone looks at the full message text,
  2046.         # and then opens it manually in the webbrowser - but it's the simplest solution for now ...
  2047.         unless ($act =~ m/st/) {
  2048.                 $messages_ext{$id}=undef;
  2049.         }
  2050.        
  2051.         # Undeleting items from trash needs to have the search variable as "trash"
  2052.         # - this is a quick hack to get around it!
  2053.         ($act, $search) = split(":",$act);
  2054.         $search ||= 'all';
  2055.        
  2056.         my $prefix = gen_prefix_url();
  2057.         return ("POST:$prefix/?&ik=&search=$search&view=tl&start=0|&act=$act&at=$gmail_at&vp=&msq=&ba=false&t=$id&fs=1&rt=j");
  2058.        
  2059.         # if ($hosted) {
  2060.                 # return ("POST:mail.google.com/a/$hosted/?&ik=&search=$search&view=tl&start=0|&act=$act&at=$gmail_at&vp=&msq=&ba=false&t=$id&fs=1");
  2061.         # } else {
  2062.                 # return ("POST:mail.google.com/mail/?&ik=&search=$search&view=tl&start=0|&act=$act&at=$gmail_at&vp=&msq=&ba=false&t=$id&fs=1");
  2063.         # }
  2064. }
  2065.  
  2066. sub gen_prefix_url {
  2067.         if ($hosted) {
  2068.                 return ("mail.google.com/a/$hosted");
  2069.         } else {
  2070.                 return ("mail.google.com/mail");
  2071.         }
  2072. }
  2073.  
  2074.  
  2075. sub undo_last {
  2076.         # Undo last Gmail action ...
  2077.         print "undo called\n" unless $silent;
  2078.         return unless @undo_buffer;
  2079.        
  2080.         notify($trans{notify_undoing});
  2081.        
  2082.         my $label;
  2083.         foreach my $i (@undo_buffer) {
  2084.                 my $id = shift(@$i);
  2085.                 $label = shift(@$i);
  2086.                 print "undoing $id, @$i\n" unless $silent;
  2087.                 foreach (@$i) {
  2088.                         $request->enqueue(gen_action_url($gmail_undo{$_},$id));
  2089.                 }
  2090.         }
  2091.         queue_check($label);
  2092. }
  2093.  
  2094. sub get_screen {
  2095.         my ($boxx, $boxy)=@_;
  2096.        
  2097.         # get screen resolution
  2098.         my $monitor = $eventbox->get_screen->get_monitor_at_point($boxx,$boxy);
  2099.         my $rect = $eventbox->get_screen->get_monitor_geometry($monitor);
  2100.         my $height = $rect->height;
  2101.        
  2102.         # support multiple monitors (thanks to Philip Jagielski for this simple solution!)
  2103.         my $width;
  2104.         unless ($disable_monitors_check) {
  2105.                 for my $i (0 .. $monitor) {
  2106.                         $width += $eventbox->get_screen->get_monitor_geometry($i)->width;
  2107.                 }
  2108.         } else {
  2109.                 $width = $eventbox->get_screen->get_monitor_geometry($monitor)->width;
  2110.         }
  2111.        
  2112.         return ($monitor,$rect,$width,$height);
  2113. }
  2114.  
  2115. sub show_notify {
  2116.         # We can only get the allocated width when the window is shown,
  2117.         # so we do all this calculation in a separate subroutine ...
  2118.         my ($win_notify_temp) = @_;    
  2119.         my $new_win = $win_notify_temp ? $win_notify_temp : $win_notify;
  2120.        
  2121.         # get eventbox origin and icon height
  2122.         my ($boxx, $boxy) = $eventbox->window->get_origin;
  2123.         my $icon_height = $eventbox->allocation->height;
  2124.        
  2125.         # get screen resolution
  2126.         my ($monitor,$rect,$width,$height)=get_screen($boxx, $boxy);
  2127.        
  2128.         # if the tray icon is at the top of the screen, it's safe to move the window
  2129.         # to the previous window's position - this makes things look a lot smoother
  2130.         # (we can't do it when the tray icon's at the bottom of the screen, because
  2131.         # a larger window will cover the icon, and when we move it we'll get another
  2132.         # show_notify() event)
  2133.         $new_win->move($old_x,$old_y) if (($boxy<($height/2)) && ($old_x || $old_y));
  2134.        
  2135.         # show the window to get width and height
  2136.         $new_win->show_all unless ($new_win->visible);
  2137.         my $notify_width=$new_win->allocation->width;
  2138.         my $notify_height=$new_win->allocation->height;
  2139.                
  2140.         if ($notify_height>($height-$icon_height-20)) {
  2141.                 # print "begin block\n";
  2142.                 $reshow=1;
  2143.                 $new_win->hide;
  2144.  
  2145.                 my $scrolled = Gtk2::ScrolledWindow->new;
  2146.                 $scrolled->modify_bg('normal', Gtk2::Gdk::Color->new (0, 0, 0));
  2147.                 $scrolled->set_policy('never','automatic');
  2148.                 $scrolled->set_shadow_type('GTK_SHADOW_NONE');
  2149.                 $notify_vbox_b->pack_start($scrolled,1,1,0);
  2150.                
  2151.                 my $scrolled_event = Gtk2::EventBox->new;
  2152.                 $scrolled_event->modify_bg('normal', Gtk2::Gdk::Color->new (0, 0, 0));
  2153.                
  2154.                 $scrolled->add_with_viewport($scrolled_event);
  2155.                
  2156.                                
  2157.                 $new_win->resize($notify_width, $height-$icon_height-20);
  2158.                 $notifybox->reparent($scrolled_event);
  2159.                
  2160.                 $new_win->show_all;
  2161.                 $new_win->resize($notify_width, $height-$icon_height-20);
  2162.                 # print "vadj = $vadj\n";
  2163.                                
  2164.                 $notify_height=$new_win->allocation->height;
  2165.                 $notify_width=$new_win->allocation->width;
  2166.         }
  2167.                        
  2168.         # calculate best position
  2169.         my $x_border = 4;
  2170.         my $y_border = 5;
  2171.         my $move_x = ($boxx+$notify_width+$x_border > $width) ? ($width-$notify_width-$x_border) : ($boxx);
  2172.         my $move_y = ($boxy>($height/2)) ? ($boxy-$notify_height-$y_border) : ($boxy+$icon_height+$y_border);
  2173.        
  2174.         # move the window
  2175.         $new_win->move($move_x,$move_y) if ($move_x || $move_y);
  2176.         Gtk2->main_iteration while (Gtk2->events_pending);
  2177.        
  2178.         # $new_win->show_all unless ($new_win->visible);
  2179.         # Gtk2->main_iteration while (Gtk2->events_pending);
  2180.  
  2181.         # $scrolled->set_vadjustment($vadj) if $vadj;
  2182.        
  2183.         # a small sleep to make compiz work better
  2184.         # select(undef, undef, undef, 0.150);
  2185.         if ($win_notify_temp) {
  2186.                 $win_notify->destroy;
  2187.                 $win_notify="";
  2188.                 $win_notify=$new_win;
  2189.         }
  2190.         # Gtk2->main_iteration while (Gtk2->events_pending);
  2191.  
  2192.        
  2193.         ($old_x, $old_y) = ($move_x,$move_y);
  2194.        
  2195.         # Enter/leave notification
  2196.         $win_notify->signal_connect('enter_notify_event', sub {
  2197.                 # print "enter\n";
  2198.                 $notify_enter = 1;
  2199.                 my $persistence = Glib::Timeout->add($popup_persistence, sub {
  2200.                         $reshow=0;
  2201.                 });
  2202.         });
  2203.        
  2204.         $win_notify->signal_connect('leave_notify_event', sub {
  2205.                 # print "leave event ...\n";
  2206.                 return if ($reshow);
  2207.  
  2208.                 ### these four lines fix the XGL/Compiz problem where clicking on the links closes the notifier window
  2209.                 my ($widget, $event, $data) = @_;
  2210.                 if ($event->detail eq 'inferior') {
  2211.                         return;
  2212.                 }
  2213.                
  2214.                 # print "leave and hide\n";
  2215.                 $notify_enter = 0;
  2216.                 $notify_vis = 0;
  2217.                 $win_notify->hide;
  2218.         });
  2219. }
  2220.  
  2221. sub popup {
  2222.         # pops up a little message for new mail - disable by setting popup time to 0
  2223.         return unless $popup_delay;
  2224.        
  2225.         # no point displaying if the user is already looking at the popup ..
  2226.         return if (($win_notify) && ($win_notify->visible));
  2227.        
  2228.         my ($text) = @_;
  2229.        
  2230.         $popup_win->destroy if $popup_win;
  2231.        
  2232.         $popup_win = Gtk2::Window->new('popup');
  2233.         $popup_win->set('allow-shrink',1);
  2234.         $popup_win->set_border_width(2);
  2235.         $popup_win->modify_bg('normal', Gtk2::Gdk::Color->new (14756, 20215, 33483));
  2236.        
  2237.         # the eventbox is needed for the background ...
  2238.         my $popupbox = Gtk2::EventBox->new;
  2239.         $popupbox->modify_bg('normal', Gtk2::Gdk::Color->new (65000, 65000, 65000));
  2240.        
  2241.         # the hbox gives an internal border, and allows us to chuck an icon in, too!
  2242.         my $popup_hbox = Gtk2::HBox->new (0, 0);
  2243.         $popup_hbox->set_border_width(4);
  2244.         $popupbox->add($popup_hbox);
  2245.        
  2246.         # Popup icon
  2247.         my $popup_icon = Gtk2::Image->new_from_pixbuf($mail_pixbuf);
  2248.         $popup_hbox->pack_start($popup_icon,0,0,3);
  2249.        
  2250.         my $popuplabel = Gtk2::Label->new;
  2251.         $popuplabel->set_line_wrap(1);
  2252.        
  2253.         $popuplabel->set_markup("$text");
  2254.         $popup_hbox->pack_start($popuplabel,0,0,3);
  2255.         $popupbox->show_all;
  2256.        
  2257.         $popup_win->add($popupbox);
  2258.        
  2259.         # get eventbox origin and icon height
  2260.         my ($boxx, $boxy) = $eventbox->window->get_origin;
  2261.         my $icon_height = $eventbox->allocation->height;
  2262.        
  2263.         # get screen resolution
  2264.         my ($monitor,$rect,$width,$height)=get_screen($boxx, $boxy);
  2265.                
  2266.         # show the window to get width and height
  2267.         $popup_win->show_all;
  2268.         my $popup_width=$popup_win->allocation->width;
  2269.         my $popup_height=$popup_win->allocation->height;
  2270.         $popup_win->hide;
  2271.         $popup_win->resize($popup_width, 1);
  2272.        
  2273.         # calculate best position
  2274.         my $x_border = 4;
  2275.         my $y_border = 6;
  2276.         my $move_x = ($boxx+$popup_width+$x_border > $width) ? ($width-$popup_width-$x_border) : ($boxx);
  2277.         my $move_y = ($boxy>($height/2)) ? ($boxy-$popup_height-$y_border) : ($icon_height+$y_border);
  2278.        
  2279.         my $shift_y = ($boxy>($height/2)) ? 1 : 0;
  2280.        
  2281.         $popup_win->move($move_x,$move_y);
  2282.         $popup_win->show_all;
  2283.                        
  2284.         # and popup ...
  2285.         my $ani_delay = 0.015;
  2286.         for (my $i = 1; $i<=$popup_height; $i++) {
  2287.                 my $move_y = ($shift_y) ? ($boxy-$i-$y_border) : $move_y;
  2288.                
  2289.                 # move the window
  2290.                 $popup_win->move($move_x,$move_y);
  2291.                 $popup_win->resize($popup_width, $i);
  2292.                 Gtk2->main_iteration while (Gtk2->events_pending);
  2293.                
  2294.                 select(undef,undef,undef,$ani_delay);
  2295.         }
  2296.        
  2297.                
  2298.         my $close = Glib::Timeout->add($popup_delay, sub { popdown($popup_height, $popup_width, $shift_y, $move_y, $boxy, $y_border, $move_x) });
  2299. }
  2300.  
  2301. sub popdown {
  2302.         # Hides the popup box with animation ...
  2303.         my ($popup_height, $popup_width, $shift_y, $move_y, $boxy, $y_border, $move_x) = @_;
  2304.        
  2305.         for (my $i = $popup_height; $i>0; $i--) {
  2306.                 my $move_y = ($shift_y) ? ($boxy-$i-$y_border) : $move_y;
  2307.  
  2308.                 # move the window
  2309.                 $popup_win->move($move_x,$move_y);
  2310.                 $popup_win->resize($popup_width, $i);
  2311.                 Gtk2->main_iteration while (Gtk2->events_pending);
  2312.                
  2313.                 select(undef,undef,undef,0.015);
  2314.         }
  2315.        
  2316.         $popup_win->destroy;
  2317. }
  2318.  
  2319.        
  2320. #######################
  2321. # Popup menu handling
  2322. #
  2323.  
  2324. sub handle_button_press {
  2325.         # Modified from yarrsr ...
  2326.         my ($widget, $event) = @_;
  2327.        
  2328.         my $x = $event->x_root - $event->x;
  2329.         my $y = $event->y_root - $event->y;
  2330.        
  2331.         if ($event->button == 1) {
  2332.                 open_gmail();
  2333.         } else {
  2334.                 $menu->popup(undef,undef, sub{return position_menu($x, $y)},0,$event->button,$event->time);
  2335.         }
  2336. }
  2337.  
  2338. sub position_menu {
  2339.         # Modified from yarrsr
  2340.         my ($x, $y) = @_;
  2341.        
  2342.         my $monitor = $menu->get_screen->get_monitor_at_point($x,$y);
  2343.         my $rect = $menu->get_screen->get_monitor_geometry($monitor);
  2344.        
  2345.         my $space_above = $y - $rect->y;
  2346.         my $space_below = $rect->y + $rect->height - $y;
  2347.        
  2348.         my $requisition = $menu->size_request();
  2349.        
  2350.         if ($requisition->height <= $space_above || $requisition->height <= $space_below) {
  2351.                 if ($requisition->height <= $space_below) {
  2352.                         $y = $y + $eventbox->allocation->height;
  2353.                 } else {
  2354.                         $y = $y - $requisition->height;
  2355.                 }
  2356.         } elsif ($requisition->height > $space_below && $requisition->height > $space_above) {
  2357.                 if ($space_below >= $space_above) {
  2358.                         $y = $rect->y + $rect->height - $requisition->height;
  2359.                 } else {
  2360.                         $y = $rect->y;
  2361.                 }
  2362.         } else {
  2363.                         $y = $rect->y;
  2364.         }
  2365.        
  2366.         return ($x,$y,1);
  2367. }
  2368.  
  2369.  
  2370. sub pack_menu {
  2371.         # This code (and the relevant menu display routine) is based
  2372.         # on code from yarrsr (Yet Another RSS Reader) (http://yarrsr.sf.net)
  2373.  
  2374.         $menu = Gtk2::Menu->new;
  2375.        
  2376.         my $menu_check = Gtk2::ImageMenuItem->new($trans{menu_check});
  2377.         $menu_check->set_image(Gtk2::Image->new_from_stock('gtk-refresh','menu'));
  2378.         $menu_check->signal_connect('activate',sub {
  2379.                 queue_check();
  2380.                 foreach my $label (keys(%label_delay)) {
  2381.                         queue_check($label);
  2382.                 }
  2383.         });
  2384.        
  2385.         my $menu_undo;
  2386.         if ($cookies) {
  2387.                 # Undo last POST action
  2388.                 $menu_undo = Gtk2::ImageMenuItem->new($trans{menu_undo});
  2389.                 $menu_undo->set_image(Gtk2::Image->new_from_stock('gtk-undo','menu'));
  2390.                 $menu_undo->signal_connect('activate', \&undo_last);
  2391.         }
  2392.        
  2393.         my $menu_compose = Gtk2::ImageMenuItem->new($trans{menu_compose});
  2394.         $menu_compose->set_image(Gtk2::Image->new_from_pixbuf(load_pixbuf($compose_mail_data)));
  2395.         $menu_compose->signal_connect('activate',sub {
  2396.                 run_command($gmail_command, get_login_href("https://mail.google.com/mail/??view=cm&tf=0#compose"));
  2397.         });
  2398.        
  2399.         my $menu_prefs = Gtk2::ImageMenuItem->new($trans{menu_prefs});
  2400.         $menu_prefs->set_image(Gtk2::Image->new_from_stock('gtk-preferences','menu'));
  2401.         $menu_prefs->signal_connect('activate',sub {
  2402.                 show_prefs();
  2403.         });
  2404.        
  2405.         my $menu_about = Gtk2::ImageMenuItem->new($trans{menu_about});
  2406.         $menu_about->set_image(Gtk2::Image->new_from_stock('gtk-about','menu'));
  2407.         $menu_about->signal_connect('activate',sub {
  2408.                 about();
  2409.         });
  2410.        
  2411.         my $menu_restart = Gtk2::ImageMenuItem->new($trans{menu_restart});
  2412.         #$menu_about->set_image(Gtk2::Image->new_from_stock('gtk-about','menu'));
  2413.         $menu_restart->signal_connect('activate',sub {
  2414.                 restart();
  2415.         });
  2416.        
  2417.         my $menu_quit = Gtk2::ImageMenuItem->new_from_stock('gtk-quit');
  2418.         $menu_quit->signal_connect('activate',sub {
  2419.                         Gtk2->main_quit;
  2420.         });
  2421.        
  2422.         # Pack menu ...
  2423.         $menu->append($menu_check);
  2424.         $menu->append($menu_undo) if $cookies;
  2425.         $menu->append($menu_compose);
  2426.         $menu->append(Gtk2::SeparatorMenuItem->new);
  2427.         $menu->append($menu_prefs);
  2428.         $menu->append($menu_about);
  2429.         $menu->append(Gtk2::SeparatorMenuItem->new);
  2430.         $menu->append($menu_restart);
  2431.         $menu->append($menu_quit);
  2432.        
  2433.         $menu->show_all;
  2434. }
  2435.  
  2436. sub restart {
  2437.         exec "$0 @ARGV";
  2438. }
  2439.  
  2440.  
  2441. #################
  2442. # GUI dialogues
  2443. #
  2444.  
  2445. sub show_prefs {
  2446.         # The preferences dialogue ...
  2447.         # Yes, I know, I know - it's getting seriously ugly, isn't it?? :)
  2448.        
  2449.         my $dialog = Gtk2::Dialog->new ($trans{prefs}, undef,
  2450.                                         'destroy-with-parent',
  2451.                                         'gtk-ok' => 'ok',
  2452.                                         'gtk-cancel' => 'cancel',
  2453.                         );
  2454.        
  2455.         my $hbox = Gtk2::HBox->new (0, 0);
  2456.         $hbox->set_border_width (4);
  2457.         $dialog->vbox->pack_start ($hbox, 0, 0, 0);
  2458.        
  2459.         my $vbox = Gtk2::VBox->new (0, 4);
  2460.         $hbox->pack_start ($vbox, 0, 0, 4);
  2461.        
  2462.         my $frame_login = Gtk2::Frame->new ("$trans{prefs_login}");
  2463.         $vbox->pack_start ($frame_login, 0, 0, 4);
  2464.        
  2465.                 my $table_login = Gtk2::Table->new (2, 3, 0);
  2466.                 $table_login->set_row_spacings (4);
  2467.                 $table_login->set_col_spacings (4);
  2468.                 $table_login->set_border_width (5);
  2469.  
  2470.                 $frame_login->add($table_login);
  2471.                
  2472.                 my $label_user = Gtk2::Label->new_with_mnemonic ($trans{prefs_login_user});
  2473.                 $label_user->set_alignment (0, 0.5);
  2474.                 $table_login->attach_defaults ($label_user, 0, 1, 0, 1);
  2475.                
  2476.                 my $entry_user = Gtk2::Entry->new;
  2477.                 $entry_user->set_width_chars(15);
  2478.                 $entry_user->append_text($user) if $user;
  2479.                 $table_login->attach_defaults ($entry_user, 1, 2, 0, 1);
  2480.                 $label_user->set_mnemonic_widget ($entry_user);
  2481.                
  2482.                 my $label_pwd = Gtk2::Label->new_with_mnemonic ($trans{prefs_login_pass});
  2483.                 $label_pwd->set_alignment (0, 0.5);
  2484.                 $table_login->attach_defaults ($label_pwd, 0, 1, 1, 2);
  2485.                
  2486.                 my $entry_pwd = Gtk2::Entry->new;
  2487.                 $entry_pwd->set_width_chars(15);
  2488.                 $entry_pwd->set_invisible_char('*');
  2489.                 $entry_pwd->set_visibility(0);
  2490.                 $entry_pwd->append_text($passwd_decrypt) if $passwd_decrypt;
  2491.                 $table_login->attach_defaults ($entry_pwd, 1, 2, 1, 2);
  2492.                 $label_pwd->set_mnemonic_widget ($entry_pwd);
  2493.                 $entry_pwd->signal_connect(activate=>sub {$dialog->response('ok')});
  2494.                
  2495.                 my $button_passwd = Gtk2::CheckButton->new_with_label($trans{prefs_login_save});
  2496.                 $table_login->attach_defaults($button_passwd, 0, 2, 2, 3 );
  2497.                 $button_passwd->set_active(1) if ($save_passwd);
  2498.                 $button_passwd->set_label("$trans{prefs_login_save} ($trans{prefs_login_save_plain})") if ($nocrypt && !$usekwallet);
  2499.                 $button_passwd->set_label("$trans{prefs_login_save} ($trans{prefs_login_save_kwallet})") if ($usekwallet);
  2500.                 $button_passwd->signal_connect(toggled=>sub {
  2501.                                 $save_passwd = ($button_passwd->get_active) ? 1 : 0;
  2502.                         }
  2503.                 );
  2504.        
  2505.         my $frame_lang = Gtk2::Frame->new ("$trans{prefs_lang}");
  2506.         $vbox->pack_start ($frame_lang, 0, 0, 4);
  2507.                
  2508.                 my $vbox_lang = Gtk2::VBox->new (0, 0);
  2509.                 $frame_lang->add($vbox_lang);
  2510.                 $vbox_lang->set_border_width(6);
  2511.                
  2512.                         my $lang_option = Gtk2::OptionMenu->new;
  2513.                         my $lang_menu = Gtk2::Menu->new;
  2514.                        
  2515.                         my $xmlin = XMLin($translations, ForceArray => 1);
  2516.                         my $count = 0;
  2517.                         my $index;
  2518.                        
  2519.                         my @langs = keys(%{$xmlin->{Language}});
  2520.                         @langs = sort(@langs);
  2521.                         # foreach (keys(%{$xmlin->{Language}})) {
  2522.                         foreach (@langs) {
  2523.                                 my $item = make_menu_item($_);
  2524.                                 $lang_menu->append($item);
  2525.                                 $index = $count if ($_ eq $language); # check which index number is the currently selected langauge
  2526.                                 $count++;
  2527.                         }
  2528.                        
  2529.                         $lang_option->set_menu($lang_menu);
  2530.                         $lang_option->set_history($index);
  2531.                         $vbox_lang->pack_start($lang_option,0,0,3);
  2532.  
  2533.                                                                                        
  2534.         my $frame_external = Gtk2::Frame->new ("$trans{prefs_external}");
  2535.         $vbox->pack_start ($frame_external, 0, 0, 4);
  2536.                
  2537.                 my $vbox_external = Gtk2::VBox->new (0, 0);
  2538.                 $frame_external->add($vbox_external);
  2539.                 $vbox_external->set_border_width(6);
  2540.                
  2541.                         # my $hbox_browser = Gtk2::HBox->new (0,0);
  2542.                         # $vbox_external->pack_start($hbox_browser,1,1,2);
  2543.                                
  2544.                         my $exe_label = Gtk2::Label->new_with_mnemonic($trans{prefs_external_browser});
  2545.                         $exe_label->set_line_wrap(1);
  2546.                         $exe_label->set_alignment (0, 0.5);
  2547.                         $vbox_external->pack_start($exe_label,0,0,2);
  2548.                        
  2549.                         my $exe_label2 = Gtk2::Label->new();
  2550.                         $exe_label2->set_markup("<small>$trans{prefs_external_browser2}</small>");
  2551.                         $exe_label2->set_line_wrap(1);
  2552.                         $exe_label2->set_alignment (0, 0.5);
  2553.                         $vbox_external->pack_start($exe_label2,0,0,2);
  2554.                        
  2555.                        
  2556.                         my $hbox_exe = Gtk2::HBox->new (0,0);
  2557.                         $vbox_external->pack_start($hbox_exe,1,1,3);
  2558.                        
  2559.                                 my $label_exe_sp = Gtk2::Label->new("   ");
  2560.                                 $label_exe_sp->set_alignment (0, 0.5);
  2561.                                 $hbox_exe->pack_start($label_exe_sp, 0, 0, 0);
  2562.                                
  2563.                                 my $exe_entry = Gtk2::Entry->new();
  2564.                                 $exe_entry->set_width_chars(14);
  2565.                                 $exe_entry->set_text($gmail_command);
  2566.                                 $hbox_exe->pack_end($exe_entry,1,1,0);
  2567.                                
  2568.                         $vbox_external->pack_start (Gtk2::HSeparator->new, 0, 0, 4);
  2569.                        
  2570.                         my $label_notify = Gtk2::Label->new_with_mnemonic ($trans{prefs_external_mail_command});
  2571.                         $label_notify->set_line_wrap(1);
  2572.                         $label_notify->set_alignment (0, 0.5);
  2573.                         $vbox_external->pack_start($label_notify,0,0,3);
  2574.                        
  2575.                         my $hbox_notify = Gtk2::HBox->new (0,0);
  2576.                         $vbox_external->pack_start($hbox_notify,1,1,3);
  2577.                
  2578.                                 my $label_notify_sp = Gtk2::Label->new("   ");
  2579.                                 $label_notify_sp->set_alignment (0, 0.5);
  2580.                                 $hbox_notify->pack_start($label_notify_sp, 0, 0, 0);
  2581.                                
  2582.                                 my $entry_notify = Gtk2::Entry->new;
  2583.                                 $entry_notify->append_text($notify_command) if $notify_command;
  2584.                                 $entry_notify->set_width_chars(15);
  2585.                                 $hbox_notify->pack_start($entry_notify, 1, 1, 0);
  2586.                                 $label_notify->set_mnemonic_widget ($entry_notify);
  2587.                                
  2588.                         my $label_notify_none = Gtk2::Label->new_with_mnemonic ($trans{prefs_external_nomail_command});
  2589.                         $label_notify_none->set_alignment (0, 0.5);
  2590.                         $label_notify_none->set_line_wrap(1);
  2591.                         $vbox_external->pack_start($label_notify_none,0,0,3);
  2592.                        
  2593.                         my $hbox_notify_none = Gtk2::HBox->new (0,0);
  2594.                         $vbox_external->pack_start($hbox_notify_none,1,1,3);
  2595.                
  2596.                                 my $label_notify_none_sp = Gtk2::Label->new("   ");
  2597.                                 $label_notify_none_sp->set_alignment (0, 0.5);
  2598.                                 $hbox_notify_none->pack_start($label_notify_none_sp, 0, 0, 0);
  2599.                                
  2600.                                 my $entry_notify_none = Gtk2::Entry->new;
  2601.                                 $entry_notify_none->set_width_chars(15);
  2602.                                 $entry_notify_none->append_text($nomail_command) if $nomail_command;
  2603.                                 $hbox_notify_none->pack_start($entry_notify_none, 1, 1, 0);
  2604.                                 $label_notify_none->set_mnemonic_widget ($entry_notify_none);
  2605.                                 # $vbox_external->pack_start($entry_notify_none,0,0,3);
  2606.                                
  2607.  
  2608.         my $vbox2 = Gtk2::VBox->new (0, 4);
  2609.         $hbox->pack_start ($vbox2, 0, 0, 4);
  2610.                
  2611.         my $frame_check = Gtk2::Frame->new ("$trans{prefs_check}");
  2612.         $vbox2->pack_start ($frame_check, 0, 0, 4);
  2613.                
  2614.                 my $vbox_check = Gtk2::VBox->new (0, 0);
  2615.                 $frame_check->add($vbox_check);
  2616.                 $vbox_check->set_border_width(6);
  2617.  
  2618.                         my $hbox_delay = Gtk2::HBox->new (0,0);
  2619.                         $vbox_check->pack_start($hbox_delay,0,0,2);
  2620.                        
  2621.                                 my $label_delay = Gtk2::Label->new_with_mnemonic ($trans{prefs_check_delay});
  2622.                                 $label_delay->set_alignment (0, 0.5);
  2623.                                 $hbox_delay->pack_start($label_delay, 0, 0, 0);
  2624.                                
  2625.                                 my $entry_delay = Gtk2::Entry->new;
  2626.                                 $entry_delay->set_width_chars(4);
  2627.                                 $entry_delay->append_text($delay/1000) if $delay;
  2628.                                 $hbox_delay->pack_start($entry_delay, 0, 0, 0);
  2629.                                 $label_delay->set_mnemonic_widget ($entry_delay);
  2630.                                
  2631.                                 my $label_secs = Gtk2::Label->new_with_mnemonic ($trans{prefs_check_delay2});
  2632.                                 $label_secs->set_alignment (0, 0.5);
  2633.                                 $hbox_delay->pack_start($label_secs, 0, 0, 0);
  2634.                        
  2635.                        
  2636.                         ##########
  2637.                         # Labels
  2638.                         #
  2639.                        
  2640.                                 my $labels_label = Gtk2::Label->new_with_mnemonic($trans{prefs_check_labels});
  2641.                                 $labels_label->set_line_wrap(1);
  2642.                                 $labels_label->set_alignment (0, 0.5);
  2643.                                 $vbox_check->pack_start($labels_label,0,0,4);
  2644.                                
  2645.                                 convert_labels_from_hash();
  2646.                                
  2647.                                 # most of this code is adapted from the treeview.pl example provided with Gtk2-perl ...
  2648.                                 my $sw = Gtk2::ScrolledWindow->new;
  2649.                                 $sw->set_shadow_type ('etched-in');
  2650.                                 $sw->set_policy ('automatic', 'automatic');
  2651.                                 $vbox_check->pack_start ($sw, 1, 1, 0);
  2652.                                
  2653.                                 # create model
  2654.                                 my $model = Gtk2::ListStore->new (qw/Glib::String Glib::Int/);
  2655.                                                        
  2656.                                 # add labels to model
  2657.                                 foreach my $a (@labels) {
  2658.                                         my $iter = $model->append;
  2659.                                         $model->set ($iter,
  2660.                                                         0, $a->{label},
  2661.                                                         1, $a->{delay});
  2662.                                 }
  2663.        
  2664.                                 # create tree view
  2665.                                 my $treeview = Gtk2::TreeView->new_with_model ($model);
  2666.                                 $treeview->set_rules_hint (1);
  2667.                                 $treeview->get_selection->set_mode ('single');
  2668.                                
  2669.                                 # label columns
  2670.                                 my $renderer = Gtk2::CellRendererText->new;
  2671.                                 $renderer->signal_connect (edited => \&cell_edited, $model);
  2672.                                 $renderer->set_data (column => 0);
  2673.                                
  2674.                                 $treeview->insert_column_with_attributes (-1, $trans{prefs_check_labels_label}, $renderer,
  2675.                                                                         text => 0,
  2676.                                                                         editable => 1);
  2677.                                
  2678.                                 # delay column
  2679.                                 $renderer = Gtk2::CellRendererText->new;
  2680.                                 $renderer->signal_connect (edited => \&cell_edited, $model);
  2681.                                 $renderer->set_data (column => 1);
  2682.                                
  2683.                                 $treeview->insert_column_with_attributes (-1, $trans{prefs_check_labels_delay}, $renderer,
  2684.                                                                         text => 1,
  2685.                                                                         editable => 1);
  2686.                                 $sw->add ($treeview);
  2687.                                
  2688.                                 # buttons for adding and removing labels ...
  2689.                                 my $label_button_hbox = Gtk2::HBox->new (1, 4);
  2690.                                 $vbox_check->pack_start ($label_button_hbox, 0, 0, 0);
  2691.                                
  2692.                                 my $button_addlabel = Gtk2::Button->new ($trans{prefs_check_labels_add});
  2693.                                 $button_addlabel->signal_connect (clicked => sub {
  2694.                                                 push @labels, {
  2695.                                                         label => $trans{prefs_check_labels_new},
  2696.                                                         delay => 300,
  2697.                                                 };
  2698.                                                
  2699.                                                 my $iter = $model->append;
  2700.                                                 $model->set ($iter,
  2701.                                                         0, $labels[-1]{label},
  2702.                                                         1, $labels[-1]{delay},);
  2703.                                         }, $model);
  2704.                                 $label_button_hbox->pack_start ($button_addlabel, 1, 1, 0);
  2705.                                
  2706.                                 my $button_removelabel = Gtk2::Button->new ($trans{prefs_check_labels_remove});
  2707.                                 $button_removelabel->signal_connect (clicked => sub {
  2708.                                                 my $selection = $treeview->get_selection;
  2709.                                                 my $iter = $selection->get_selected;
  2710.                                                 if ($iter) {
  2711.                                                         my $path = $model->get_path ($iter);
  2712.                                                         my $i = ($path->get_indices)[0];
  2713.                                                         $model->remove ($iter);
  2714.                                                         splice @labels, $i, 1;
  2715.                                                 }
  2716.                                         }, $treeview);
  2717.                                 $label_button_hbox->pack_start ($button_removelabel, 1, 1, 0);
  2718.                        
  2719.                        
  2720.                         $vbox_check->pack_start (Gtk2::HSeparator->new, 0, 0, 4);
  2721.                        
  2722.                         my $hbox_atom = Gtk2::HBox->new (0,0);
  2723.                         $vbox_check->pack_start($hbox_atom,1,1,2);
  2724.                        
  2725.                                 my $atom_label = Gtk2::Label->new_with_mnemonic($trans{prefs_check_atom});
  2726.                                 $hbox_atom->pack_start($atom_label,0,0,2);
  2727.                                
  2728.                                 my $atom_entry = Gtk2::Entry->new();
  2729.                                 $atom_entry->set_width_chars(14);
  2730.                                 $atom_entry->set_text($gmail_address);
  2731.                                 $hbox_atom->pack_end($atom_entry,1,1,2);
  2732.                        
  2733.  
  2734.                        
  2735.                         # Thanks to Rune Maagensen for adding the 24 hour clock button ...                             
  2736.                         my $button_24h = Gtk2::CheckButton->new_with_label($trans{prefs_check_24_hour});
  2737.                         $vbox_check->pack_start($button_24h, 0, 0, 2);
  2738.                         $button_24h->set_active(1) if ($time_24);
  2739.                         $button_24h->signal_connect(toggled=>sub {
  2740.                                         $time_24 = ($button_24h->get_active) ? 1 : 0;
  2741.                                 }
  2742.                         );
  2743.                        
  2744.                         my $button_archive = Gtk2::CheckButton->new_with_label($trans{prefs_check_archive});
  2745.                         $vbox_check->pack_start($button_archive, 0, 0, 2);
  2746.                         $button_archive->set_active(1) if ($archive_as_read);
  2747.                         $button_archive->signal_connect(toggled=>sub {
  2748.                                         $archive_as_read = ($button_archive->get_active) ? 1 : 0;
  2749.                                 }
  2750.                         );
  2751.                        
  2752.  
  2753.        
  2754.                
  2755.        
  2756.         my $frame_tray = Gtk2::Frame->new ("$trans{prefs_tray}");
  2757.         $vbox2->pack_start ($frame_tray, 0, 0, 4);
  2758.                
  2759.                 my $vbox_tray = Gtk2::VBox->new (0, 0);
  2760.                 $frame_tray->add($vbox_tray);
  2761.                 $vbox_tray->set_border_width(6);
  2762.                
  2763.                 # There's a lot of Gtk2-perl modules included in distros with only
  2764.                 # Gtk-2.4 bindings ... the following code needs 2.6 bindings to funtion
  2765.                 if (Gtk2->CHECK_VERSION (2, 6, 0)) {
  2766.                                                
  2767.                         my $hbox_icon_m = Gtk2::HBox->new (0,6);
  2768.                         $vbox_tray->pack_start($hbox_icon_m, 0, 0, 2);
  2769.                        
  2770.                                 my $button_m = Gtk2::CheckButton->new_with_label($trans{prefs_tray_mail_icon});
  2771.                                 $hbox_icon_m->pack_start($button_m, 0, 0, 0 );
  2772.                                 $button_m->set_active(1) if ($custom_mail_icon);
  2773.                                 $button_m->signal_connect(toggled=>sub {
  2774.                                                 $custom_mail_icon = ($button_m->get_active) ? 1 : 0;
  2775.                                         }
  2776.                                 );
  2777.                                
  2778.                                 my $button_m_open = Gtk2::Button->new("");
  2779.                                 $button_m_open->set_image(Gtk2::Image->new_from_pixbuf($custom_mail_pixbuf));
  2780.                                 $button_m_open->signal_connect(clicked=>sub {
  2781.                                                 get_icon_file(\$mail_icon);
  2782.                                                 set_icons();
  2783.                                                 $button_m_open->set_image(Gtk2::Image->new_from_pixbuf($custom_mail_pixbuf));
  2784.                                         }
  2785.                                 );
  2786.                                 $hbox_icon_m->pack_end($button_m_open, 0, 0, 0);
  2787.                        
  2788.                         my $hbox_icon_nom = Gtk2::HBox->new (0,6);
  2789.                         $vbox_tray->pack_start($hbox_icon_nom, 1, 1, 2);
  2790.                        
  2791.                                 my $button_nom = Gtk2::CheckButton->new_with_label($trans{prefs_tray_no_mail_icon});
  2792.                                 $hbox_icon_nom->pack_start($button_nom, 0, 0, 0 );
  2793.                                 $button_nom->set_active(1) if ($custom_no_mail_icon);
  2794.                                 $button_nom->signal_connect(toggled=>sub {
  2795.                                                 $custom_no_mail_icon = ($button_nom->get_active) ? 1 : 0;
  2796.                                         }
  2797.                                 );
  2798.                                
  2799.                                 my $button_nom_open = Gtk2::Button->new("");
  2800.                                 $button_nom_open->set_image(Gtk2::Image->new_from_pixbuf($custom_no_mail_pixbuf));
  2801.                                 $button_nom_open->signal_connect(clicked=>sub {
  2802.                                                 get_icon_file(\$no_mail_icon);
  2803.                                                 set_icons();
  2804.                                                 $button_nom_open->set_image(Gtk2::Image->new_from_pixbuf($custom_no_mail_pixbuf));
  2805.                                         }
  2806.                                 );
  2807.                                 $hbox_icon_nom->pack_end($button_nom_open, 0, 0, 0);
  2808.                                
  2809.                         my $hbox_icon_error = Gtk2::HBox->new (0,6);
  2810.                         $vbox_tray->pack_start($hbox_icon_error, 1, 1, 2);
  2811.                        
  2812.                                 my $button_error = Gtk2::CheckButton->new_with_label($trans{prefs_tray_error_icon});
  2813.                                 $hbox_icon_error->pack_start($button_error, 0, 0, 0 );
  2814.                                 $button_error->set_active(1) if ($custom_error_icon);
  2815.                                 $button_error->signal_connect(toggled=>sub {
  2816.                                                 $custom_error_icon = ($button_error->get_active) ? 1 : 0;
  2817.                                         }
  2818.                                 );
  2819.                                
  2820.                                 my $button_error_open = Gtk2::Button->new("");
  2821.                                 $button_error_open->set_image(Gtk2::Image->new_from_pixbuf($custom_error_pixbuf));
  2822.                                 $button_error_open->signal_connect(clicked=>sub {
  2823.                                                 get_icon_file(\$error_icon);
  2824.                                                 set_icons();
  2825.                                                 $button_error_open->set_image(Gtk2::Image->new_from_pixbuf($custom_error_pixbuf));
  2826.                                         }
  2827.                                 );
  2828.                                 $hbox_icon_error->pack_end($button_error_open, 0, 0, 0);
  2829.                                
  2830.                 } else {
  2831.                         # Warning message if user doesn't have Gtk2.6 bindings ...
  2832.                         my $button_gtk_label = Gtk2::Label->new();
  2833.                         my $error_text = "<i>Button image functions are disabled</i>\n\nPlease upgrade to Gtk v2.6 or later and/or update Gtk2-perl bindings";
  2834.                         $button_gtk_label->set_line_wrap(1);
  2835.                         $button_gtk_label->set_markup($error_text);
  2836.  
  2837.                         $vbox_tray->pack_start($button_gtk_label, 1, 1, 2);
  2838.                 }      
  2839.                                        
  2840.                         $vbox_tray->pack_start (Gtk2::HSeparator->new, 0, 0, 4);
  2841.                        
  2842.                         my $hbox_pdelay = Gtk2::HBox->new (0,0);
  2843.                         $vbox_tray->pack_start($hbox_pdelay,0,0,3);
  2844.                        
  2845.                                 my $label_pdelay = Gtk2::Label->new_with_mnemonic ($trans{prefs_tray_pdelay});
  2846.                                 $label_pdelay->set_alignment (0, 0.5);
  2847.                                 $hbox_pdelay->pack_start($label_pdelay, 0, 0, 0);
  2848.                                
  2849.                                 my $entry_pdelay = Gtk2::Entry->new;
  2850.                                 $entry_pdelay->set_width_chars(3);
  2851.                                 $entry_pdelay->append_text($popup_delay/1000) if $popup_delay;
  2852.                                 $hbox_pdelay->pack_start($entry_pdelay, 0, 0, 0);
  2853.                                 $label_pdelay->set_mnemonic_widget ($entry_pdelay);
  2854.                                
  2855.                                 my $label_psecs = Gtk2::Label->new_with_mnemonic ($trans{prefs_tray_pdelay2});
  2856.                                 $label_psecs->set_alignment (0, 0.5);
  2857.                                 $hbox_pdelay->pack_start($label_psecs, 0, 0, 0);
  2858.                                
  2859.                         $vbox_tray->pack_start (Gtk2::HSeparator->new, 0, 0, 3);
  2860.                        
  2861.                         my $button_colour = Gtk2::Button->new($trans{prefs_tray_bg});
  2862.                         $button_colour->signal_connect(clicked=>\&set_bg_colour);
  2863.                         $vbox_tray->pack_start($button_colour,0,0,3);
  2864.                        
  2865.                                
  2866.         $dialog->show_all;
  2867.         my $response = $dialog->run;
  2868.        
  2869.         if ($response eq 'ok') {
  2870.                 # remove password from the hash if user requests it ...
  2871.                 if ($save_passwd && !$usekwallet) {
  2872.                         $pref_variables{passwd}=\$passwd;
  2873.                 } else {
  2874.                         delete $pref_variables{passwd};
  2875.                 }
  2876.                
  2877.                 # grab all entry variables ...
  2878.                 $user = $entry_user->get_text;
  2879.                 $passwd_decrypt = $entry_pwd->get_text;
  2880.                 $passwd = encrypt_real($passwd_decrypt);
  2881.                 $delay = ($entry_delay->get_text)*1000;
  2882.                 $popup_delay = ($entry_pdelay->get_text)*1000;
  2883.                 $gmail_address = $atom_entry->get_text;
  2884.                 $gmail_command = $exe_entry->get_text;
  2885.                 $notify_command = $entry_notify->get_text;
  2886.                 $nomail_command = $entry_notify_none->get_text;
  2887.                
  2888.                 if ($usekwallet && $save_passwd) {
  2889.                         open KWALLET, "|kwallet -set checkgmail";
  2890.                         print KWALLET "$passwd\n";
  2891.                         close KWALLET;
  2892.                 }
  2893.  
  2894.                 reinit_checks();
  2895.                                
  2896.                 write_prefs();
  2897.                 set_icons();
  2898.                 set_language();
  2899.                 pack_menu();
  2900.                 queue_check();
  2901.         }
  2902.        
  2903.         $dialog->destroy;      
  2904. }
  2905.  
  2906.  
  2907. sub reinit_checks {
  2908.         Glib::Source->remove($check{inbox}) if $check{inbox};
  2909.         $check{inbox} = Glib::Timeout->add($delay, \&queue_check);
  2910.        
  2911.         foreach my $label (keys(%label_delay)) {
  2912.                 Glib::Source->remove($check{$label}) if $check{$label};
  2913.                 $check{$label} = Glib::Timeout->add(($label_delay{$label}*1000), sub{queue_check($label)});
  2914.                 queue_check($label);
  2915.         }              
  2916. }
  2917.  
  2918.  
  2919. sub cell_edited {
  2920.   my ($cell, $path_string, $new_text, $model) = @_;
  2921.   my $path = Gtk2::TreePath->new_from_string ($path_string);
  2922.  
  2923.   my $column = $cell->get_data ("column");
  2924.  
  2925.   my $iter = $model->get_iter ($path);
  2926.  
  2927.   if ($column == 0) {
  2928.         my $i = ($path->get_indices)[0];
  2929.         $labels[$i]{label} = $new_text;
  2930.  
  2931.         $model->set ($iter, $column, $labels[$i]{label});
  2932.  
  2933.   } elsif ($column == 1) {
  2934.         my $i = ($path->get_indices)[0];
  2935.         $labels[$i]{delay} = $new_text;
  2936.  
  2937.         $model->set ($iter, $column, $labels[$i]{delay});
  2938.   }
  2939. }
  2940.  
  2941.  
  2942. sub make_menu_item
  2943. {
  2944.         my ($name) = @_;
  2945.         my $item = Gtk2::MenuItem->new_with_label($name);
  2946.         $item->signal_connect(activate => sub{$language=$name});
  2947.         $item->show;
  2948.  
  2949.         return $item;
  2950. }
  2951.  
  2952. sub login {
  2953.         # a login dialogue - just ripped from the prefs above ...
  2954.        
  2955.         # lock shared variables
  2956.         lock($user);
  2957.         lock($passwd);
  2958.         lock($save_passwd);
  2959.         lock($gmail_address);
  2960.  
  2961.         my ($title) = @_;
  2962.         my $dialog = Gtk2::Dialog->new ($title, undef,
  2963.                                         'destroy-with-parent',
  2964.                                         'gtk-ok' => 'ok',
  2965.                                         'gtk-cancel' => 'cancel',
  2966.                         );
  2967.         # $dialog_login->set_default_response('ok');
  2968.        
  2969.         my $hbox = Gtk2::HBox->new (0, 0);
  2970.         $hbox->set_border_width (4);
  2971.         $dialog->vbox->pack_start ($hbox, 0, 0, 0);
  2972.        
  2973.         my $vbox = Gtk2::VBox->new (0, 4);
  2974.         $hbox->pack_start ($vbox, 0, 0, 4);
  2975.                
  2976.         my $table_login = Gtk2::Table->new (2, 3, 0);
  2977.         $table_login->set_row_spacings (4);
  2978.         $table_login->set_col_spacings (4);
  2979.         $table_login->set_border_width (5);
  2980.  
  2981.         $hbox->add($table_login);
  2982.        
  2983.         my $label_user = Gtk2::Label->new_with_mnemonic ($trans{prefs_login_user});
  2984.         $label_user->set_alignment (0, 0.5);
  2985.         $table_login->attach_defaults ($label_user, 0, 1, 0, 1);
  2986.        
  2987.         my $entry_user = Gtk2::Entry->new;
  2988.         $entry_user->set_width_chars(12);
  2989.         $entry_user->append_text($user) if $user;
  2990.         $table_login->attach_defaults ($entry_user, 1, 2, 0, 1);
  2991.         $label_user->set_mnemonic_widget ($entry_user);
  2992.        
  2993.         my $label_pwd = Gtk2::Label->new_with_mnemonic ($trans{prefs_login_pass});
  2994.         $label_pwd->set_alignment (0, 0.5);
  2995.         $table_login->attach_defaults ($label_pwd, 0, 1, 1, 2);
  2996.        
  2997.         my $entry_pwd = Gtk2::Entry->new;
  2998.         $entry_pwd->set_width_chars(12);
  2999.         $entry_pwd->set_invisible_char('*');
  3000.         $entry_pwd->set_visibility(0);
  3001.         $entry_pwd->append_text($passwd_decrypt) if $passwd_decrypt;
  3002.         $table_login->attach_defaults ($entry_pwd, 1, 2, 1, 2);
  3003.         $label_pwd->set_mnemonic_widget ($entry_pwd);
  3004.         $entry_pwd->signal_connect(activate=>sub {$dialog->response('ok')});
  3005.        
  3006.         my $button_passwd = Gtk2::CheckButton->new_with_label($trans{prefs_login_save});
  3007.         $table_login->attach_defaults($button_passwd, 0, 2, 2, 3 );
  3008.         $button_passwd->set_active(1) if ($save_passwd);
  3009.         $button_passwd->set_label("$trans{prefs_login_save} ($trans{prefs_login_save_plain})") if ($nocrypt && !$usekwallet);
  3010.         $button_passwd->set_label("$trans{prefs_login_save} ($trans{prefs_login_save_kwallet})") if ($usekwallet);
  3011.         $button_passwd->signal_connect(toggled=>sub {
  3012.                         $save_passwd = ($button_passwd->get_active) ? 1 : 0;
  3013.                 }
  3014.         );
  3015.        
  3016.         $dialog->show_all;
  3017.         my $response = $dialog->run;
  3018.         if ($response eq 'ok') {
  3019.                 if (($save_passwd)) {
  3020.                         $pref_variables{passwd}=\$passwd;
  3021.                 } else {
  3022.                         delete $pref_variables{passwd};
  3023.                 }
  3024.                 $user = $entry_user->get_text;
  3025.                 $passwd_decrypt = $entry_pwd->get_text;
  3026.                 $passwd = encrypt_real($passwd_decrypt);
  3027.                 write_prefs();
  3028.                
  3029.                 if ($usekwallet && $save_passwd) {
  3030.                         open KWALLET, "|kwallet -set checkgmail";
  3031.                         print KWALLET "$passwd\n";
  3032.                         close KWALLET;
  3033.                 }
  3034.  
  3035.         } else {
  3036.                 $dialog->destroy;      
  3037.                 exit 0;
  3038.         }
  3039.         $dialog->destroy;      
  3040. }
  3041.  
  3042. sub about {
  3043.         my $text = <<EOF;
  3044. <b>CheckGmail v$version</b>
  3045. Copyright &#169; 2005-7, Owen Marshall
  3046.                        
  3047. <small>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.</small>
  3048.  
  3049. <small>Special thanks to Sandro Tosi, Rune Maagensen, Jean-Baptiste Denis, Jochen Hoenicke, Melita Ivkovic, Poika Pilvimaa, Alvaro Arenas, Marek Drwota, Dennis van der Staal, Jordi Sanfeliu, Fernando Pereira, Matic Ahacic, Johan Gustafsson, Satoshi Tanabe, Marius Mihai, Marek Malysz, Ruszkai &#193;kos, Nageswaran Rajendran, &#23385;&#32487;&#19996;, Martin Kody&#353;, Rune Gangst&#248;, Christian M&#252;ller, Luciano Ziegler, Igor Donev and anonymous contributors for translations ...</small>
  3050.                
  3051. http://checkgmail.sf.net               
  3052. EOF
  3053.         chomp($text);
  3054.         my $dialog = Gtk2::MessageDialog->new_with_markup(undef,
  3055.                         'destroy-with-parent',
  3056.                         'info',
  3057.                         'ok',
  3058.                         $text,
  3059.                 );
  3060.         $dialog->run;
  3061.         $dialog->destroy;
  3062. }
  3063.  
  3064. sub set_bg_colour {
  3065.         my $colour;
  3066.         my $dialog = Gtk2::ColorSelectionDialog->new ("Set tray background");
  3067.         my $colorsel = $dialog->colorsel;
  3068.         if ($background) {
  3069.                 my ($red, $green, $blue) = convert_hex_to_colour($background);
  3070.                 $colour = Gtk2::Gdk::Color->new($red, $green, $blue);
  3071.                 $colorsel->set_current_color ($colour);
  3072.         }
  3073.        
  3074.         $colorsel->set_has_palette(1);
  3075.        
  3076.         my $response = $dialog->run;
  3077.         if ($response eq 'ok') {
  3078.                 $colour = $colorsel->get_current_color;
  3079.                 $eventbox->modify_bg('normal', $colour);
  3080.                 my $colour_hex =
  3081.                           sprintf("%.2X", ($colour->red  /256))
  3082.                         . sprintf("%.2X", ($colour->green/256))
  3083.                         . sprintf("%.2X", ($colour->blue /256));
  3084.                 $background = $colour_hex;
  3085.         }
  3086.        
  3087.         $dialog->destroy;
  3088.        
  3089. }
  3090.  
  3091. sub get_icon_file {
  3092.         my ($pointer) =  @_;
  3093.        
  3094.         my $icon_browser = Gtk2::FileChooserDialog->new(
  3095.                         "Select icon file ...",
  3096.                         undef,
  3097.                         'open',
  3098.                         'gtk-cancel' => 'cancel',
  3099.                         'gtk-ok' => 'ok',
  3100.         );
  3101.        
  3102.         my $filter = Gtk2::FileFilter->new;
  3103.         $filter->add_pixbuf_formats;
  3104.         $filter->set_name("Image files");
  3105.  
  3106.         $icon_browser->add_filter($filter);
  3107.  
  3108.        
  3109.         my $response = $icon_browser->run;
  3110.        
  3111.         my $icon;
  3112.         if ($response eq 'ok') {
  3113.                 $icon = $icon_browser->get_filename;
  3114.                 $$pointer = $icon;
  3115.         }
  3116.        
  3117.         $icon_browser->destroy;
  3118. }
  3119.  
  3120. sub set_icons {
  3121.        
  3122.         # Load custom or default icons for mail status notification ...
  3123.        
  3124.         # load defaults
  3125.         $mail_pixbuf = load_pixbuf($mail_data);
  3126.         $no_mail_pixbuf = load_pixbuf($no_mail_data);
  3127.         $error_pixbuf = load_pixbuf($error_data);
  3128.         $star_pixbuf = load_pixbuf($star_on_data);
  3129.         $nostar_pixbuf = load_pixbuf($star_off_data);
  3130.        
  3131.         # load custom icons if defined
  3132.         $custom_mail_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($mail_icon) if $mail_icon;
  3133.         $custom_no_mail_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($no_mail_icon) if $no_mail_icon;
  3134.         $custom_error_pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($error_icon) if $error_icon;
  3135.        
  3136.         # set custom pixbufs to defaults if undefined
  3137.         $custom_mail_pixbuf ||= $mail_pixbuf;
  3138.         $custom_no_mail_pixbuf ||= $no_mail_pixbuf;
  3139.         $custom_error_pixbuf ||= $error_pixbuf;
  3140.        
  3141.         # set icon pixbufs to custom pixbufs if user requested
  3142.         $mail_pixbuf = $custom_mail_pixbuf if $custom_mail_icon;
  3143.         $no_mail_pixbuf = $custom_no_mail_pixbuf if $custom_no_mail_icon;
  3144.         $error_pixbuf = $custom_error_pixbuf if $custom_error_icon;
  3145.                
  3146. }
  3147.  
  3148. sub set_icon {
  3149.         my ($file, $size) = @_;
  3150.         my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file($file);
  3151.         my $scaled = $pixbuf->scale_simple($size, $size, "hyper");
  3152.         return $scaled;
  3153. }
  3154.  
  3155.  
  3156.  
  3157. #######################
  3158. # Encryption routines
  3159. #
  3160.  
  3161. sub encrypt_real {
  3162.         $_ = shift;
  3163.         if ($nocrypt) {
  3164.                 return $_;
  3165.         } else {
  3166.                 return encrypt($_);
  3167.         }
  3168. }
  3169.  
  3170. sub decrypt_real {
  3171.         $_ = shift;
  3172.         if ($nocrypt) {
  3173.                 return $_;
  3174.         } else {
  3175.                 return decrypt($_);
  3176.         }
  3177. }
  3178.  
  3179.  
  3180. ########
  3181. # Misc
  3182. #
  3183.  
  3184. sub convert_hex_to_colour {
  3185.         my ($colour) = @_;
  3186.         my ($red, $green, $blue) = $colour =~ /(..)(..)(..)/;
  3187.  
  3188.         $red = hex($red)*256;
  3189.         $green = hex($green)*256;
  3190.         $blue = hex($blue)*256;
  3191.        
  3192.         return ($red, $green, $blue);
  3193. }
  3194.  
  3195.  
  3196. #############
  3197. # Icon data
  3198. #
  3199.  
  3200. sub load_pixbuf {
  3201.         my $data = shift;
  3202.        
  3203.         my $loader = Gtk2::Gdk::PixbufLoader->new;
  3204.         $loader->write ($data);
  3205.         $loader->close;
  3206.        
  3207.         return $loader->get_pixbuf;
  3208. }
  3209.  
  3210. sub load_icon_data {
  3211.        
  3212.         $error_data = unpack("u",
  3213. 'MB5!.1PT*&@H````-24A$4@```!`````0"`8````?\_]A````!F)+1T0`_P#_
  3214. M`/^@O:>3````"7!(67,```QU```,=0$M>)1U````!W1)344\'U047"@0$Y9]#
  3215. MH0```85)1$%4.,NUTL%*XU`4QO&_-J3,3$-WTC()(Y\'6G;L+@;CH-AN?0\'P%
  3216. MWZ#*>0.?YFZSF(!KEPF#E@2]N"L%P9B*"TTF&<O,@\'AV(?E]^6Y.X(.SE0;!
  3217. M67TQBB+ZT^G?GJ\>T[0P6L=`,;V\7%OMNT9K)DI!%&W$:%TL6AA@N_WVH>^3
  3218. MB8#6&W$F$@]]O\$`30-G/@<1`#(1)E`W:?#HZ,CP].2E03`#7*#7.4(KI,I$
  3219. M\'B;0!^XRD?C[^;GY^OP\SD0:W&G0A"A5`05PE8FXP%4;#WW?_;*_WS-OQ^P&
  3220. MY\'E5+I>%HU0,&.#7X.3D\4_LS.?4`=L=G"2%\'8;QZO[>&*W[.\?\'&W%[Z@8-
  3221. M9K4R+!;CH>\?9"(%<-!@I=[MU@(JX!4/!J9,DK&CU`P8`7O`MQJ7RR5VGH/G
  3222. M=0)N@)_KVUNSOKX>VV$XP_-<)XIZB/2;[0!VGE,F"788_OZ5`=(@L\'Z<GKHU
  3223. MKE>T<=Y"%A<7KQ\Q#0(+^#\,X\'F=!A:P"QR62?)O_!GS`K6COO-L,Q_/````
  3224. )`$E%3D2N0F""');
  3225.        
  3226.         $no_mail_data = unpack("u",
  3227. 'MB5!.1PT*&@H````-24A$4@```!`````0"`0```"U^C?J`````F)+1T0`_X>/
  3228. MS+\````)<$A9<P``#\'4```QU`2UXE\'4````\'=$E-10?5!!D#+C1^0]HI````
  3229. MB$E$050HS\7/H1&#0!!&X2^9E\'"2X!DD+K7@HE)%*L%1"PY)!;%("HBXRW\'$
  3230. M1N1WN^_M[BR_YO1XPLWU"[Q,X!++R5U7X#EASG&^,I@+/*C<=J%7%TK$M;X\
  3231. MT1LQP`%G@29!*G6J"F&UY6:ML5F%75@M6D%G1)\[68A8@A"TEOV+#RX3CAO^
  3232. 6FC<\3AZN>\`BO0````!)14Y$KD)@@@``');
  3233.        
  3234.         $mail_data = unpack("u",
  3235. 'MB5!.1PT*&@H````-24A$4@```!`````0"`8````?\_]A````"7!(67,```QU
  3236. M```,=0$M>)1U````!W1)344\'U008#C<OWT).ZP```-))1$%4.,OED3$.@S`,
  3237. M15^KBHHA8NV2!:EP`B0D3I!+9<BE<@(N`5.5I2MC6=H%(A?2KAWZISCV^[83
  3238. M^+4.0]L^U^!B#.>J^@H\AH&[]S$^R>3=>ZY-`\:D:>^Y"1C@*+L79<GH\'&R*
  3239. M5GATCJ(LN8@&T4!92U[7:1,!YW6-LC:]@K(6G`-@=([K<O\)WAD`J*:)YW$Q
  3240. MB[#(I0U"8)ZF7>$*S]-$%@)HG3`(@;GOR;H.M$89$]=9Q\YDS=9`PF]O(J4U
  3241. E6=<Q]_W^%[;P1RTFR0G^5"_P^T_]<U3R]`````!)14Y$KD)@@@``');
  3242.        
  3243.         $compose_mail_data = unpack("u",
  3244. 'MB5!.1PT*&@H````-24A$4@```!`````0"`8````?\_]A````!F)+1T0`_P#_
  3245. M`/^@O:>3````"7!(67,```L2```+$@\'2W7[\````!W1)344\'U0L#%PT06C)B
  3246. M\'P```?A)1$%4.,NMDTUH$U$4A;]))LEDR*1-4],L(H7J2A1+,6E$$"VF8HJ"
  3247. M%05_$%V)2,&-".X%<6,1"M*-NJG[4D\'MRK;XLTAB4(QH*5ALJN`B8\J;3)+)
  3248. MN!"C0Q)0].[>>><<WKWW//C\'DOZ4:)?=4?#O0Y+[L6T!9D;2*L_D=N0;-Z\/
  3249. M`KF?9[>KSOQBGKW);-;G"T2A7`4Q;Y?Y)G<27[UR[1=HY:!61!CQ(5M."XF/
  3250. M56IW4U#-R)W$[PMY2KI.I6*"]9*!_@*QS7$L:9?JLD&2-"_HMMQ)G,OGB42B
  3251. M=\'>\'\\\'H&<<DKF,8+?\'X08E5UL_\'.YZD___T%N3.GSO+D\1S+RQ\8\'1TCU-.#
  3252. MWZ^BJG&H!RE^NH>[](JN4(S91R-#Q\?NOW&T$`[W(H3)N?,74%75,9NOI6UL
  3253. M5"<PQ3I=?0E65J>1-,MV&"B*PO!P@H=SL^P?.0"`$`+#,#`,@\+;UQP^<A3%
  3254. MKS4U+5O8%(F0W)WDP<P,6[<,`.#UR:RM?6\'\V#BRRQF=MCD(:D\'"H0"I@ZDF
  3255. M-G7[%EY9PC1-%`)-W-4:.9N%A:><.\'FZ"36L.A<O3;"XM(1A"`>]Q2";R7`H
  3256. MG:9>-;$;#:Q:%0F)AM5@YX[M%-<_=VY!UW42R3T_+F2?@^@!%%6CMR^&KNMM
  3257. B#2;O3$]=_HN/.,G_J.\25[KK%,1Y@@````!)14Y$KD)@@@``');
  3258.  
  3259.         $star_on_data = unpack("u",
  3260. 'MB5!.1PT*&@H````-24A$4@```!`````0"`8````?\_]A````!\'-"250("`@(
  3261. M?`ADB`````EP2%ES```-UP``#=<!0BB;>````!ET15AT4V]F=\'=A<F4`=W=W
  3262. M+FEN:W-C87!E+F]R9YON/!H```)\241!5#B-G5-=2U11%%W[W\'-GQID[V1A^
  3263. MI2/-1&9?.D%*,>)3/?10T4-%)4R1^!1!1(\1%/4#`B\'ZH!DMD`KRH;>@\'IIK
  3264. M0F$@E*$&HYD.(I0?,Z-S[SV[A]`<\'%_:<&"S66NOM0[G$#.C6)D)JA="O`-1
  3265. M3CG.L6B,AXOA1%$V`")Q,]AXN7);Y\'I("\'%G(QR8>=U)QE\'1W^.V\'&N6E3W\'
  3266. M\'YX9=C*.ZF+8C1QT5NUH9U(_`?LKMNZZQ``ZBSI-QN$"<`5`2`BMAHBJ&=38
  3267. M<BKE$3P,J%]P1#,^OMRY3\'"&F\'E:*6<2P#B`>V1VBQ?EX=,G:O=>TZ6[$IHT
  3268. M0)H/1*Y_,FH!2EFP<Q/(YU+(9Z=X:OBA-3\[]$:P4JD2?UB4E!Z`[@E"R$`A
  3269. M&0"$%\33D\'(*/K\;@=J3Y/+5"&9.43(./PG15Q$^W[;]8)<D`0`Z``6H!;"3
  3270. M!NP)L#T&0$#I;1A)7K5^I]\/L%+\'B9EA)D@2T7VW$;JP[W"W)C$`ML8!7@(X
  3271. M\_>R9!UL[2B^O.UP<O-CO<Q\,1IC2P)`-,8V@`XS09[TV/,SM0U\')%2V,(:K
  3272. M$3.CK^WLW&A?-,;M*V-9$%73*XPM$0EA@/0&0!@`"%`+@/##*&N20G-5%7!6
  3273. M&C-!Q$R\'O(\'](*T6Y&E%+K<)V44/R-,*TH(HV=P$5JK93-"J\%H\'>Z2[S\'!Y
  3274. MZV\';B_@Q>,M*CSY>)I!=\'C[KJXO<UG5O$+JWRI7/3$8`?"IP`*!461F5\'GG`
  3275. M@Z\:G/3(HUYVED+*R85FOO<\^=RW6TU_ZV)E916`TM67N/8W]O>XGQ*)@\'*6
  3276. M[D9C;*[-:B:H16B>&\PJPRI_+AICM6[!_]0?8_PDB6*NF@(`````245.1*Y"
  3277. "8((`');
  3278.  
  3279.         $star_off_data = unpack("u",
  3280. 'MB5!.1PT*&@H````-24A$4@```!`````0"`8````?\_]A````!\'-"250("`@(
  3281. M?`ADB````?9)1$%4.(VMD\%J$V$4A;_)C&,F36B2,;1-:TA;720N3+.H@R!(
  3282. M$0*&K+((:.)3]`&ZRK)TF3?(&R3071]`*18B5!$%H8(FFC).F.DTU\4,4FLB
  3283. M")[5SW_//=S_W/.KS(<.;`(F8`.7LTB1OPB8@\\\'@SG`XO`_<FD>:)Z#&X_%D
  3284. MH5!82Z?3J5PNEP2T?Q%(=CJ=-/`)^\'!P<)`"DK.("J"&Q1OA60-BCN,4#<-X
  3285. M"7B3R>11+!9[#3@$7OC`!?!=`Y;W]_=7&XW&RG0ZO5A<7-0U33,,P_@!?%04
  3286. M143$=EUWRW5=9SP>>Y%(1.UVNY]W=W?/-.`RG\\\\;V6QV"7@#O`<FP#=%422<
  3287. MM*?K>E+7=2.12*P#]\KELA,^D0BPMK>WM^W[?DM$[L[Q!1\'9%)$7[7;[`7#[
  3288. MNH=+]7I]RW7=9R*R/J,YY_O^\V:S60:60__^0+[?[S\6D8<S!+:/CHYV@(VK
  3289. M]]?7Z)=*I07@2]BT(B*K8>UKL5A<(-C`+UP/1RR3R9C`1$2>>IZ7\#Q/1,0!
  3290. M7J52*1,PYDUPLU:KQ555C0([AX>\'MFF:)Z9IGO1ZO7/@B:JJ>JO52@#160):
  3291. M-!J=CD:CD659QY5*Y9UMVZ>>YYU6J]6WEF4=V[9]KBC*)4\'H@-^=5`C<58$1
  3292. C0>JNPB#XF5/@#!#^!WX"JHNT6FM(-L<`````245.1*Y"8((`');
  3293.        
  3294. }
  3295.  
  3296.  
  3297. #############
  3298. # Languages
  3299. #
  3300.  
  3301. sub URI_escape {
  3302.         # Turn text into HTML escape codes
  3303.         ($_) = @_;
  3304.         s/([^a-zA-Z0-9])/$escapes{$1}/g;
  3305.         return $_;
  3306. }
  3307.  
  3308. sub URI_unescape {
  3309.         # Turn HTML escape code into text
  3310.         ($_) = @_;
  3311.         s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
  3312.         return $_;
  3313. }
  3314.  
  3315. sub read_translations {
  3316.         my $default_translations = <<EOF;
  3317. <opt Version="1.12">
  3318.   <Language name="Català"
  3319.             login_err="Error: Nom d'usuari o contrassenya incorrecte"
  3320.             login_title="Entrant a Gmail ..."
  3321.             mail_archive="Arxiva"
  3322.             mail_archiving="Arxivant ..."
  3323.             mail_delete="Suprimeix"
  3324.             mail_deleting="Suprimint ..."
  3325.             mail_mark="Marca'l com a llegit"
  3326.             mail_mark_all="Marca'ls tots com a llegits"
  3327.             mail_marking="Marcant com a llegit ..."
  3328.             mail_marking_all="Marcant tots com a llegits ..."
  3329.             mail_open="Obre"
  3330.             mail_report_spam="Marca'l com a correu brossa"
  3331.             mail_reporting_spam="Marcant com a correu brossa ..."
  3332.             menu_about="_Quant a"
  3333.             menu_check="_Comprova correu electrònic"
  3334.             menu_compose="Redacta un missatge"
  3335.             menu_prefs="_Preferències"
  3336.             menu_undo="_Desfés la darrera acció"
  3337.             notify_and="i"
  3338.             notify_check="S'està comprovant Gmail ..."
  3339.             notify_from="De:"
  3340.             notify_login="S'està entrant a Gmail ..."
  3341.             notify_multiple1="Hi ha"
  3342.             notify_multiple2="nous missatges ..."
  3343.             notify_new_mail="Nou missatge de"
  3344.             notify_no_mail="No hi ha missatges nous"
  3345.             notify_no_subject="(sense assumpte)"
  3346.             notify_no_text="(sense text)"
  3347.             notify_single1="Hi ha"
  3348.             notify_single2="un nou missatge ..."
  3349.             notify_undoing="Desfent la darrera acció ..."
  3350.             prefs="Preferències de CheckGmail"
  3351.             prefs_check="Comprovació de missatges"
  3352.             prefs_check_24_hour="rellotje de 24 hores"
  3353.             prefs_check_archive="Arxiu també marca'l com a llegit"
  3354.             prefs_check_atom="Adreça de l'alimentador"
  3355.             prefs_check_delay="Verifica nous missatges a la safata d'entrada cada"
  3356.             prefs_check_delay2="segs"
  3357.             prefs_check_labels="També verifica les següents etiquetes:"
  3358.             prefs_check_labels_add="Afegeix una etiqueta"
  3359.             prefs_check_labels_delay="Verifica cada (segs)"
  3360.             prefs_check_labels_label="Etiqueta"
  3361.             prefs_check_labels_new="[nova etiqueta]"
  3362.             prefs_check_labels_remove="Suprimeix etiqueta"
  3363.             prefs_external="Ordres Externes"
  3364.             prefs_external_browser="Ordre a executar quan feu clic a la icona de la safata"
  3365.             prefs_external_browser2="(feu servir %u per representar l'adreça web de Gmail)"
  3366.             prefs_external_mail_command="Ordre a executar a cada nou missatge:"
  3367.             prefs_external_nomail_command="Ordre a executar quan no hi hagi missatges:"
  3368.             prefs_lang="Idioma"
  3369.             prefs_login="Detalls d'accés"
  3370.             prefs_login_pass="_Contrasenya"
  3371.             prefs_login_save="Desa contrasenya"
  3372.             prefs_login_save_kwallet="a la carpeta de KDE"
  3373.             prefs_login_save_plain="com a text"
  3374.             prefs_login_user="_Nom d'usuari"
  3375.             prefs_tray="Safata del sistema"
  3376.             prefs_tray_bg="Configura el color de fons de la safata ..."
  3377.             prefs_tray_error_icon="Personalitza la icona d'error"
  3378.             prefs_tray_mail_icon="Personalitza la icona de quan hi ha missatges"
  3379.             prefs_tray_no_mail_icon="Personalitza la icona de quan no hi ha missatges"
  3380.             prefs_tray_pdelay="Mostra finestra emergent de nous missatges durant"
  3381.             prefs_tray_pdelay2="segs" />
  3382.   <Language name="Dansk"
  3383.             login_err="Fejl: forkert brugernavn eller adgangskode"
  3384.             login_title="Gmail login"
  3385.             mail_archive="Arkivér"
  3386.             mail_archiving="Arkiverer ..."
  3387.             mail_delete="Slet"
  3388.             mail_deleting="Sletter ..."
  3389.             mail_mark="Marker læst"
  3390.             mail_mark_all="Marker alle som læst"
  3391.             mail_marking="Markerer læst ..."
  3392.             mail_marking_all="Markerer alle læst ..."
  3393.             mail_open="Åbn"
  3394.             mail_report_spam="Rapporter spam"
  3395.             mail_reporting_spam="Rapporterer spam ..."
  3396.             menu_about="_Om Checkgmail"
  3397.             menu_check="_Se efter ny post på Gmail"
  3398.             menu_compose="Skriv email"
  3399.             menu_prefs="_Indstilinger"
  3400.             menu_undo="_Fortyd sidste handling ..."
  3401.             notify_and="og"
  3402.             notify_check="Ser efter ny post på Gmail ..."
  3403.             notify_from="Fra:"
  3404.             notify_login="Logger ind på Gmail ..."
  3405.             notify_multiple1="Der er "
  3406.             notify_multiple2=" nye breve ..."
  3407.             notify_new_mail="Nyt brev fra "
  3408.             notify_no_mail="Ingen nye breve"
  3409.             notify_no_subject="(intet emne)"
  3410.             notify_no_text="(ingen tekst)"
  3411.             notify_single1="Der er "
  3412.             notify_single2=" nyt brev ..."
  3413.             notify_undoing="Fortryder sidste handling ..."
  3414.             prefs="CheckGmail indstillinger"
  3415.             prefs_check="Se efter ny post"
  3416.             prefs_check_24_hour="24 timers ur"
  3417.             prefs_check_archive="Arkivér markerer også læst"
  3418.             prefs_check_atom="Feed adresse"
  3419.             prefs_check_delay="Se efter ny post i Inbox hver "
  3420.             prefs_check_delay2=" sekunder"
  3421.             prefs_check_labels="Se også efter følgende mærker:"
  3422.             prefs_check_labels_add="Tilføj mærke"
  3423.             prefs_check_labels_delay="Se hvert (sekunder)"
  3424.             prefs_check_labels_label="Mærke"
  3425.             prefs_check_labels_new="[nyt mærke]"
  3426.             prefs_check_labels_remove="Fjern Mærke"
  3427.             prefs_external="Eksterne programmer"
  3428.             prefs_external_browser="Browser"
  3429.             prefs_external_browser2="(%u repræsenterer Gmail adressen)"
  3430.             prefs_external_mail_command="Kommando ved nyt brev:"
  3431.             prefs_external_nomail_command="Kommando ved ingen nye breve:"
  3432.             prefs_lang="Sprog"
  3433.             prefs_login="Logindetaljer"
  3434.             prefs_login_pass="_Adgangskode"
  3435.             prefs_login_save="Gem adgagnskode"
  3436.             prefs_login_save_kwallet="i KDE tegnebog"
  3437.             prefs_login_save_plain="som tekst"
  3438.             prefs_login_user="_Brugernavn"
  3439.             prefs_tray="Statusfelt"
  3440.             prefs_tray_bg="Sæt statusfelt baggrund ..."
  3441.             prefs_tray_error_icon="Brug selvvalgt 'fejl' ikon"
  3442.             prefs_tray_mail_icon="Brug selvvalgt 'ny post' ikon"
  3443.             prefs_tray_no_mail_icon="Brug selvvalgt 'ingen post' ikon"
  3444.             prefs_tray_pdelay="Vis nyt brev popup i "
  3445.             prefs_tray_pdelay2=" sekunder" />
  3446.   <Language name="Deutsch"
  3447.             login_err="Fehler: Falsches Login oder Passwort"
  3448.             login_title="Google-Mail Login ..."
  3449.             mail_archive="Archivieren"
  3450.             mail_archiving="Archiviere ..."
  3451.             mail_delete="Löschen"
  3452.             mail_deleting="Lösche ..."
  3453.             mail_mark="Als gelesen markieren"
  3454.             mail_mark_all="Alle als gelesen markieren"
  3455.             mail_marking="Markiere als gelesen ..."
  3456.             mail_marking_all="Markiere alle als gelesen ..."
  3457.             mail_open="Öffnen"
  3458.             mail_report_spam="Spam melden"
  3459.             mail_reporting_spam="Melde Spam ..."
  3460.             menu_about="Ü_ber"
  3461.             menu_check="_Mail abfragen"
  3462.             menu_compose="Neue Nachricht"
  3463.             menu_prefs="_Einstellungen"
  3464.             menu_undo="_Rückgängig machen"
  3465.             notify_and="und"
  3466.             notify_check="Frage Google-Mail ab ..."
  3467.             notify_from="Von:"
  3468.             notify_login="Anmelden bei Google-Mail ..."
  3469.             notify_multiple1="Sie haben "
  3470.             notify_multiple2=" neue Nachrichten ..."
  3471.             notify_new_mail="Neue Nachricht von "
  3472.             notify_no_mail="Keine neuen Nachrichten"
  3473.             notify_no_subject="(kein Betreff)"
  3474.             notify_no_text="(kein Text)"
  3475.             notify_single1="Sie haben "
  3476.             notify_single2=" neue Nachricht ..."
  3477.             notify_undoing="Mache letzte Aktion rückgängig ..."
  3478.             prefs="CheckGmail Einstellungen"
  3479.             prefs_check="Nachrichtenabfrage"
  3480.             prefs_check_24_hour="24 Stunden-Uhr"
  3481.             prefs_check_archive="Beim Archivieren als gelesen markieren"
  3482.             prefs_check_atom="Feed Adresse:"
  3483.             prefs_check_delay="Frage Nachrichten alle "
  3484.             prefs_check_delay2=" Sekunden ab"
  3485.             prefs_check_labels="Auch die folgenden Labels abfragen:"
  3486.             prefs_check_labels_add="Label hinzufügen"
  3487.             prefs_check_labels_delay="Frage ab alle (Sekunden)"
  3488.             prefs_check_labels_label="Label"
  3489.             prefs_check_labels_new="[neues Label]"
  3490.             prefs_check_labels_remove="Label entfernen"
  3491.             prefs_external="Externe Programme"
  3492.             prefs_external_browser="Web-Browser"
  3493.             prefs_external_browser2="(Für %u wird die Webadresse (URL) eingesetzt)"
  3494.             prefs_external_mail_command="Ausführen wenn neue Nachricht:"
  3495.             prefs_external_nomail_command="Ausführen wenn keine neuen Nachrichten:"
  3496.             prefs_lang="Sprache"
  3497.             prefs_login="Login-Einstellungen"
  3498.             prefs_login_pass="_Passwort"
  3499.             prefs_login_save="Passwort speichern"
  3500.             prefs_login_save_kwallet="in der KDE-Wallet"
  3501.             prefs_login_save_plain="unverschlüsselt"
  3502.             prefs_login_user="_Login"
  3503.             prefs_tray="Systemabschnitt der Kontrollleiste"
  3504.             prefs_tray_bg="Hintergrundfarbe ..."
  3505.             prefs_tray_error_icon="Benutze eigenes Icon für Fehler"
  3506.             prefs_tray_mail_icon="Benutze eigenes Icon für Mail"
  3507.             prefs_tray_no_mail_icon="Benutze eigenes Icon für keine Mail"
  3508.             prefs_tray_pdelay="Zeige Popupfenster für neue Mail für "
  3509.             prefs_tray_pdelay2=" Sekunden" />
  3510.   <Language name="English"
  3511.             login_err="Error: Incorrect username or password"
  3512.             login_title="Login to Gmail ..."
  3513.             mail_archive="Archive"
  3514.             mail_archiving="Archiving ..."
  3515.             mail_delete="Delete"
  3516.             mail_deleting="Deleting ..."
  3517.             mail_mark="Mark as read"
  3518.             mail_mark_all="Mark all as read"
  3519.             mail_marking="Marking read ..."
  3520.             mail_marking_all="Marking all read ..."
  3521.             mail_open="Open"
  3522.             mail_report_spam="Report spam"
  3523.             mail_reporting_spam="Reporting spam ..."
  3524.             menu_about="_About"
  3525.             menu_check="_Check mail"
  3526.             menu_compose="Compose mail"
  3527.             menu_prefs="_Preferences"
  3528.             menu_undo="_Undo last action"
  3529.                         menu_restart="Restart ..."
  3530.             notify_and="and"
  3531.             notify_check="Checking Gmail ..."
  3532.             notify_from="From:"
  3533.             notify_login="Logging in to Gmail ..."
  3534.             notify_multiple1="There are "
  3535.             notify_multiple2=" new messages ..."
  3536.             notify_new_mail="New mail from "
  3537.             notify_no_mail="No new mail"
  3538.             notify_no_subject="(no subject)"
  3539.             notify_no_text="(no text)"
  3540.             notify_single1="There is "
  3541.             notify_single2=" new message ..."
  3542.             notify_undoing="Undoing last action ..."
  3543.             prefs="CheckGmail preferences"
  3544.             prefs_check="Mail checking"
  3545.             prefs_check_24_hour="24 hour clock"
  3546.             prefs_check_archive="Archive also marks as read"
  3547.             prefs_check_atom="Feed address"
  3548.             prefs_check_delay="Check Inbox for mail every "
  3549.             prefs_check_delay2=" secs"
  3550.             prefs_check_labels="Also check the following labels:"
  3551.             prefs_check_labels_add="Add label"
  3552.             prefs_check_labels_delay="Check every (secs)"
  3553.             prefs_check_labels_label="Label"
  3554.             prefs_check_labels_new="[new label]"
  3555.             prefs_check_labels_remove="Remove label"
  3556.             prefs_external="External Commands"
  3557.             prefs_external_browser="Command to execute on clicking the tray icon"
  3558.             prefs_external_browser2="(use %u to represent the Gmail web address)"
  3559.             prefs_external_mail_command="Command to execute on new mail:"
  3560.             prefs_external_nomail_command="Command to execute for no mail:"
  3561.             prefs_lang="Language"
  3562.             prefs_login="Login details"
  3563.             prefs_login_pass="_Password"
  3564.             prefs_login_save="Save password"
  3565.             prefs_login_save_kwallet="in KDE wallet"
  3566.             prefs_login_save_plain="as plain text"
  3567.             prefs_login_user="_Username"
  3568.             prefs_tray="System tray"
  3569.             prefs_tray_bg="Set tray background ..."
  3570.             prefs_tray_error_icon="Use custom error icon"
  3571.             prefs_tray_mail_icon="Use custom mail icon"
  3572.             prefs_tray_no_mail_icon="Use custom no mail icon"
  3573.             prefs_tray_pdelay="Show new mail popup for "
  3574.             prefs_tray_pdelay2=" secs" />
  3575.   <Language name="Español"
  3576.             login_err="Error: Nombre de usuario o contraseña incorreta"
  3577.             login_title="Autentificando en Gmail ..."
  3578.             mail_archive="Archivar"
  3579.             mail_archiving="Archivando ..."
  3580.             mail_delete="Delete"
  3581.             mail_deleting="Deleting ..."
  3582.             mail_mark="Marcar como leído"
  3583.             mail_mark_all="Marcar todos como leído"
  3584.             mail_marking="Marcando como leído ..."
  3585.             mail_marking_all="Marcando todos com leído ..."
  3586.             mail_open="Abrir"
  3587.             mail_report_spam="Marcar como spam"
  3588.             mail_reporting_spam="Marcando como spam ..."
  3589.             menu_about="_Acerca de Checkgmail"
  3590.             menu_check="_Revisar correo"
  3591.             menu_compose="Compose mail"
  3592.             menu_prefs="_Configurar"
  3593.             menu_undo="_Deshacer última acción"
  3594.             notify_and="y"
  3595.             notify_check="Conectactando Gmail ..."
  3596.             notify_from="De:"
  3597.             notify_login="Autentificando en Gmail ..."
  3598.             notify_multiple1="Hay "
  3599.             notify_multiple2=" nuevos mensajes ..."
  3600.             notify_new_mail="Nuevo correo de "
  3601.             notify_no_mail="No hay nuevos mensajes"
  3602.             notify_no_subject="(sin asunto)"
  3603.             notify_no_text="(sin texto)"
  3604.             notify_single1="Hay "
  3605.             notify_single2=" nuevo mensaje ..."
  3606.             notify_undoing="Deshacer la última acción ..."
  3607.             prefs="Configuración de CheckGmail"
  3608.             prefs_check="Verificación de correo"
  3609.             prefs_check_24_hour="reloj de 24 horas"
  3610.             prefs_check_archive="Archivar también marca como leído"
  3611.             prefs_check_atom="Dirección del alimentador (feed)"
  3612.             prefs_check_delay="Revisar la bandeja de entrada cada "
  3613.             prefs_check_delay2=" segs"
  3614.             prefs_check_labels="También verificar las siguientes etiquetas:"
  3615.             prefs_check_labels_add="Agregar etiqueta"
  3616.             prefs_check_labels_delay="Verificar cada (segs)"
  3617.             prefs_check_labels_label="Etiqueta"
  3618.             prefs_check_labels_new="[nueva etiqueta]"
  3619.             prefs_check_labels_remove="Eliminar etiqueta"
  3620.             prefs_external="Comandos Externos"
  3621.             prefs_external_browser="Navegador"
  3622.             prefs_external_browser2="(%u representa la dirección web de Gmail)"
  3623.             prefs_external_mail_command="Comando a ejecutar para nuevos mensajes:"
  3624.             prefs_external_nomail_command="Comando a ejecutar si no hay nuevos mensajes:"
  3625.             prefs_lang="Lenguaje"
  3626.             prefs_login="Detalles de Autentificación"
  3627.             prefs_login_pass="_Contraseña"
  3628.             prefs_login_save="Guardar contraseña"
  3629.             prefs_login_save_kwallet="en KDE wallet"
  3630.             prefs_login_save_plain="como texto plano"
  3631.             prefs_login_user="_Nombre de usuario"
  3632.             prefs_tray="Área de notificaciones"
  3633.             prefs_tray_bg="Seleccionar color de fondo ..."
  3634.             prefs_tray_error_icon="Personalizar ícono de error"
  3635.             prefs_tray_mail_icon="Personalizar ícono de nuevos mensajes"
  3636.             prefs_tray_no_mail_icon="Personalizar ícono de no mensajes"
  3637.             prefs_tray_pdelay="Mostrar la ventana emergente para nuevos mensajes por "
  3638.             prefs_tray_pdelay2=" segs" />
  3639.   <Language name="Français"
  3640.             login_err="Erreur: Nom d'utilisateur ou mot de passe incorrect"
  3641.             login_title="Connexion à Gmail..."
  3642.             mail_archive="Archiver"
  3643.             mail_archiving="Archivage..."
  3644.             mail_delete="Supprimer"
  3645.             mail_deleting="Suppression..."
  3646.             mail_mark="Marquer comme lu"
  3647.             mail_mark_all="Tout marquer comme lu"
  3648.             mail_marking="Marquage comme lu..."
  3649.             mail_marking_all="Marquage comme lu..."
  3650.             mail_open="Ouvrir"
  3651.             mail_report_spam="Signaler comme spam"
  3652.             mail_reporting_spam="Signalisation comme spam..."
  3653.             menu_about="_À propos"
  3654.             menu_check="_Vérifier les messages"
  3655.             menu_compose="Nouveau message"
  3656.             menu_prefs="_Préférences"
  3657.             menu_undo="_Annuler la dernière action"
  3658.             notify_and="et"
  3659.             notify_check="Vérification Gmail..."
  3660.             notify_from="De:"
  3661.             notify_login="Connexion à Gmail..."
  3662.             notify_multiple1="Il y a "
  3663.             notify_multiple2=" nouveaux messages..."
  3664.             notify_new_mail="Nouveau message de "
  3665.             notify_no_mail="Pas de nouveaux messages"
  3666.             notify_no_subject="(pas d'objet)"
  3667.             notify_no_text="(pas de texte)"
  3668.             notify_single1="Il y a "
  3669.             notify_single2=" nouveau message..."
  3670.             notify_undoing="Annulation de la dernière action..."
  3671.             prefs="Préférences de CheckGmail"
  3672.             prefs_check="Vérification des messages"
  3673.             prefs_check_24_hour="Format horaire 24h "
  3674.             prefs_check_archive="Archives marquées comme lues"
  3675.             prefs_check_atom="Adresse de flux"
  3676.             prefs_check_delay="Vérification toutes les "
  3677.             prefs_check_delay2=" secs"
  3678.             prefs_check_labels="Also check the following labels:"
  3679.             prefs_check_labels_add="Add label"
  3680.             prefs_check_labels_delay="Check every (secs)"
  3681.             prefs_check_labels_label="Label"
  3682.             prefs_check_labels_new="[new label]"
  3683.             prefs_check_labels_remove="Remove label"
  3684.             prefs_external="Commandes externes"
  3685.             prefs_external_browser="Navigateur Web"
  3686.             prefs_external_browser2="(utiliser %u pour réprésenter l'adresse web de Gmail)"
  3687.             prefs_external_mail_command="Commande à exécuter en cas de nouveaux messages:"
  3688.             prefs_external_nomail_command="Commande à exécuter si il n'y a pas de messages:"
  3689.             prefs_lang="Langues"
  3690.             prefs_login="Informations utilisateur"
  3691.             prefs_login_pass="_Mot de passe"
  3692.             prefs_login_save="Sauver le mot de passe"
  3693.             prefs_login_save_kwallet="dans le portefeuille KDE"
  3694.             prefs_login_save_plain="en clair"
  3695.             prefs_login_user="_Nom d'utilisateur"
  3696.             prefs_tray="Zone de notification"
  3697.             prefs_tray_bg="Couleur de fond..."
  3698.             prefs_tray_error_icon="Icône d'erreur personnalisée"
  3699.             prefs_tray_mail_icon="Icône de mail personnalisée"
  3700.             prefs_tray_no_mail_icon="Icône d'absence de mail personnalisée"
  3701.             prefs_tray_pdelay="Afficher un popup de notification durant "
  3702.             prefs_tray_pdelay2=" secs" />
  3703.   <Language name="Hrvatski"
  3704.             login_err="Greška: neispravan korisnik ili lozinka"
  3705.             login_title="Prijava na Gmail ..."
  3706.             mail_archive="Arhiv"
  3707.             mail_archiving="Arhiviranje ..."
  3708.             mail_delete="Obriši"
  3709.             mail_deleting="Brisanje ..."
  3710.             mail_mark="Označi kao pročitano"
  3711.             mail_mark_all="Označi sve kao pročitano"
  3712.             mail_marking="Označavanje pročitanog ..."
  3713.             mail_marking_all="Označavanje svega kao pročitanog ..."
  3714.             mail_open="Otvori"
  3715.             mail_report_spam="Prijavi spam"
  3716.             mail_reporting_spam="Prijava spama ..."
  3717.             menu_about="_O programu"
  3718.             menu_check="_Provjeri mail"
  3719.             menu_compose="Napiši poruku"
  3720.             menu_prefs="_Postavke"
  3721.             menu_undo="_Poništi zadnju akciju"
  3722.             notify_and="i"
  3723.             notify_check="Provjera Gmaila ..."
  3724.             notify_from="Od:"
  3725.             notify_login="Prijava na Gmail ..."
  3726.             notify_multiple1="Broj novih poruka: "
  3727.             notify_multiple2=" ..."
  3728.             notify_new_mail="Nova poruka: šalje "
  3729.             notify_no_mail="Nema novih poruka"
  3730.             notify_no_subject="(nema predmeta)"
  3731.             notify_no_text="(nema teksta)"
  3732.             notify_single1="Broj novih poruka: "
  3733.             notify_single2=" "
  3734.             notify_undoing="Poništavanje zadnje akcije ..."
  3735.             prefs="Postavke CheckGmaila"
  3736.             prefs_check="Provjera maila"
  3737.             prefs_check_24_hour="24-satni oblik"
  3738.             prefs_check_archive="Označi arhiv pročitanim"
  3739.             prefs_check_atom="Adresa feeda"
  3740.             prefs_check_delay="Provjeri dolaznu poštu svakih "
  3741.             prefs_check_delay2=" sekundi"
  3742.             prefs_check_labels="Provjeri i ove etikete:"
  3743.             prefs_check_labels_add="Dodaj etiketu"
  3744.             prefs_check_labels_delay="Provjeri svake (sekunde)"
  3745.             prefs_check_labels_label="Etiketa"
  3746.             prefs_check_labels_new="[nova etiketa]"
  3747.             prefs_check_labels_remove="Makni etiketu"
  3748.             prefs_external="Vanjske naredbe"
  3749.             prefs_external_browser="Web preglednik"
  3750.             prefs_external_browser2="(upotrijebi %u za prikaz web adrese Gmaila)"
  3751.             prefs_external_mail_command="Naredba za izvršenje ako ima novih poruka:"
  3752.             prefs_external_nomail_command="Naredba za izvršenje ako nema novih poruka:"
  3753.             prefs_lang="Jezik"
  3754.             prefs_login="Podaci za prijavu"
  3755.             prefs_login_pass="_Lozinka"
  3756.             prefs_login_save="Spremi lozinku"
  3757.             prefs_login_save_kwallet="u KDE wallet"
  3758.             prefs_login_save_plain="kao običan tekst"
  3759.             prefs_login_user="_Korisnik"
  3760.             prefs_tray="Sistemska traka"
  3761.             prefs_tray_bg="Postavi pozadinu sistemske trake ..."
  3762.             prefs_tray_error_icon="Odaberi vlastitu ikonu za pogrešku"
  3763.             prefs_tray_mail_icon="Odaberi vlastitu ikonu za novu poruku"
  3764.             prefs_tray_no_mail_icon="Odaberi vlastitu ikonu kada nema poruka"
  3765.             prefs_tray_pdelay="Prikaz prozora za novi mail: "
  3766.             prefs_tray_pdelay2=" sekundi" />
  3767.   <Language name="Italiano"
  3768.             login_err="Errore: Utente o password errato"
  3769.             login_title="Login a Gmail ..."
  3770.             mail_archive="Archivia"
  3771.             mail_archiving="Archiviazione ..."
  3772.             mail_delete="Cancella"
  3773.             mail_deleting="Cancellazione ..."
  3774.             mail_mark="Segna come letta"
  3775.             mail_mark_all="Segna tutti come letti"
  3776.             mail_marking="Segnalazione come letta ..."
  3777.             mail_marking_all="Marcatura tutti come letti ..."
  3778.             mail_open="Apri"
  3779.             mail_report_spam="Segnala come spam"
  3780.             mail_reporting_spam="Segnalazione come spam ..."
  3781.             menu_about="_Info"
  3782.             menu_check="_Controlla le mail"
  3783.             menu_compose="Componi un messaggio"
  3784.             menu_prefs="_Preferenze"
  3785.             menu_undo="_Annulla l'ultima azione"
  3786.             notify_and="e"
  3787.             notify_check="Controllo di Gmail ..."
  3788.             notify_from="Da:"
  3789.             notify_login="Login a Gmail ..."
  3790.             notify_multiple1="Ci sono "
  3791.             notify_multiple2=" nuovi messaggi ..."
  3792.             notify_new_mail="Nuova mail da "
  3793.             notify_no_mail="Nessuna nuova mail"
  3794.             notify_no_subject="(nessun soggetto)"
  3795.             notify_no_text="(nessun testo)"
  3796.             notify_single1="Ci sono "
  3797.             notify_single2=" nuovi messaggi ..."
  3798.             notify_undoing="Undoing last action ..."
  3799.             prefs="Preferenze di CheckGmail"
  3800.             prefs_check="Controllo delle mail"
  3801.             prefs_check_24_hour="Orologio a 24 ore"
  3802.             prefs_check_archive="Archivia marca anche come letto"
  3803.             prefs_check_atom="Indirizzo dei feed"
  3804.             prefs_check_delay="Controlla la Inbox per tutte le mail "
  3805.             prefs_check_delay2=" secondi"
  3806.             prefs_check_labels="Controlla anche le seguenti etichette:"
  3807.             prefs_check_labels_add="Aggiungi etichetta"
  3808.             prefs_check_labels_delay="Controlla ogni (sec)"
  3809.             prefs_check_labels_label="Etichetta"
  3810.             prefs_check_labels_new="[nuova etichetta]"
  3811.             prefs_check_labels_remove="Rimuovi etichetta"
  3812.             prefs_external="Comandi esterni"
  3813.             prefs_external_browser="Comando da eseguire clickando sulla icona tray"
  3814.             prefs_external_browser2="(usa %u per rappresentare l'indirizzo web di Gmail)"
  3815.             prefs_external_mail_command="Comando da seguire per le nuove mail:"
  3816.             prefs_external_nomail_command="Comando da eseguire quando non ci sono mail:"
  3817.             prefs_lang="Linguaggio"
  3818.             prefs_login="Dettagli di login"
  3819.             prefs_login_pass="_Password"
  3820.             prefs_login_save="Salva la password"
  3821.             prefs_login_save_kwallet="nel wallet KDE"
  3822.             prefs_login_save_plain="come testo in chiaro"
  3823.             prefs_login_user="_Username"
  3824.             prefs_tray="System tray"
  3825.             prefs_tray_bg="Imposta lo sfondo della tray ..."
  3826.             prefs_tray_error_icon="Utilizza un icona custom per gli errori"
  3827.             prefs_tray_mail_icon="Utilizza un icona custom per le mail"
  3828.             prefs_tray_no_mail_icon="Utilizza un icona custom per nessuna mail"
  3829.             prefs_tray_pdelay="Mostra il popup di nuove mail per "
  3830.             prefs_tray_pdelay2=" secondi" />
  3831.   <Language name="Magyar"
  3832.             login_err="HIBA!: Helytelen felhasználónév, vagy jelszó"
  3833.             login_title="Bejelentkezés a Gmail-be ..."
  3834.             mail_archive="Archívum"
  3835.             mail_archiving="Archiválás ..."
  3836.             mail_delete="Törlés"
  3837.             mail_deleting="Törlés ..."
  3838.             mail_mark="Jelöld olvasottnak"
  3839.             mail_mark_all="Jelöld mindet olvasottnak"
  3840.             mail_marking="Olvasottnak jelölés ..."
  3841.             mail_marking_all="Mindet olvasottnak jelölés ..."
  3842.             mail_open="Megnyitás"
  3843.             mail_report_spam="Ez spam"
  3844.             mail_reporting_spam="Spam bejelentése ..."
  3845.             menu_about="_Névjegy"
  3846.             menu_check="_Levelek ellenőrzése"
  3847.             menu_compose="Levélírás"
  3848.             menu_prefs="_Beállítások"
  3849.             menu_undo="_Visszavonás"
  3850.             notify_and="és"
  3851.             notify_check="Gmail ellenőrzése ..."
  3852.             notify_from="Küldő:"
  3853.             notify_login="Bejelentkezés a Gmail-be ..."
  3854.             notify_multiple1="Önnek "
  3855.             notify_multiple2=" új levele érkezett ..."
  3856.             notify_new_mail="Új levél. Küldő: "
  3857.             notify_no_mail="Nincs új levél"
  3858.             notify_no_subject="(nincs cím)"
  3859.             notify_no_text="(nincs szöveg)"
  3860.             notify_single1="Önnek "
  3861.             notify_single2=" új levele érkezett ..."
  3862.             notify_undoing="Utolsó művelet visszavonása ..."
  3863.             prefs="CheckGmail beállításai"
  3864.             prefs_check="Levelek ellenőrzése"
  3865.             prefs_check_24_hour="24 órás formátum"
  3866.             prefs_check_archive="Archiválás olvasottként is jelöl"
  3867.             prefs_check_atom="Feed cím"
  3868.             prefs_check_delay="Postaláda ellenőrzése minden "
  3869.             prefs_check_delay2=" másodpercben"
  3870.             prefs_check_labels="Az alábbi címkék ellenőrzése:"
  3871.             prefs_check_labels_add="Címke hozzáadása"
  3872.             prefs_check_labels_delay="Ellenőrzés gyakorisága (s)"
  3873.             prefs_check_labels_label="Címke"
  3874.             prefs_check_labels_new="[Új címke]"
  3875.             prefs_check_labels_remove="Címke eltávolítása"
  3876.             prefs_external="Külső parancsok"
  3877.             prefs_external_browser="Parancs végrehajtása a tálcán lévő ikonra való kattintáskor"
  3878.             prefs_external_browser2="(%u a Gmail-t jelenti )"
  3879.             prefs_external_mail_command="Parancs végrehajtása új levél esetén:"
  3880.             prefs_external_nomail_command="Parancs végrehajtása, ha nincs új levél:"
  3881.             prefs_lang="Nyelv"
  3882.             prefs_login="Bejelentkezési adatok"
  3883.             prefs_login_pass="_Jelszó"
  3884.             prefs_login_save="Jelszó mentése"
  3885.             prefs_login_save_kwallet="KDE wallet-be"
  3886.             prefs_login_save_plain="sima szövegként - nincs titkosítás"
  3887.             prefs_login_user="_Felhasználónév"
  3888.             prefs_tray="Tálca"
  3889.             prefs_tray_bg="Tálca háttérszínének beállítása ..."
  3890.             prefs_tray_error_icon="Saját hiba ikon"
  3891.             prefs_tray_mail_icon="Saját új levél ikon"
  3892.             prefs_tray_no_mail_icon="Saját nincs új levél ikon"
  3893.             prefs_tray_pdelay="Felugró ablak mutatása új levél esetén "
  3894.             prefs_tray_pdelay2=" másodpercig" />
  3895.   <Language name="Nederlands"
  3896.             login_err="Fout: Onjuiste gebruikersnaam of wachtwoord"
  3897.             login_title="inloggen in Gmail ..."
  3898.             mail_archive="Archief"
  3899.             mail_archiving="Archieveren ..."
  3900.             mail_delete="Verwijder"
  3901.             mail_deleting="Verwijderen ..."
  3902.             mail_mark="Markeren als gelezen"
  3903.             mail_mark_all="Markeer alles als gelezen"
  3904.             mail_marking="Markeer gelezen ..."
  3905.             mail_marking_all="Alles als gelezen markeren ..."
  3906.             mail_open="Openen"
  3907.             mail_report_spam="Aanmelden spam"
  3908.             mail_reporting_spam="Aanmelden als spam ..."
  3909.             menu_about="_Info"
  3910.             menu_check="_Controleer Post"
  3911.             menu_compose="Een nieuw e-mail opstellen"
  3912.             menu_prefs="_Voorkeuren"
  3913.             menu_undo="_Ongedaan maken laatste bewerking"
  3914.             notify_and="en"
  3915.             notify_check="Controle Gmail ..."
  3916.             notify_from="Van:"
  3917.             notify_login="Aanmelden Gmail account"
  3918.             notify_multiple1="Er zijn "
  3919.             notify_multiple2=" nieuwe berichten ..."
  3920.             notify_new_mail="Nieuw bericht van "
  3921.             notify_no_mail="Geen nieuwe berichten"
  3922.             notify_no_subject="(geen onderwerp)"
  3923.             notify_no_text="(geen tekst)"
  3924.             notify_single1="Er zijn "
  3925.             notify_single2=" nieuwe berichten ..."
  3926.             notify_undoing="Ongedaan maken ..."
  3927.             prefs="CheckGmail instellingen"
  3928.             prefs_check="Controle Post"
  3929.             prefs_check_24_hour="24 klok type"
  3930.             prefs_check_archive="Archief ook als gelezen markeren"
  3931.             prefs_check_atom="Feed adres"
  3932.             prefs_check_delay="Controleer postvak elke "
  3933.             prefs_check_delay2=" seconden"
  3934.             prefs_check_labels="Controleer de volgende accounts:"
  3935.             prefs_check_labels_add="Toevoegen account"
  3936.             prefs_check_labels_delay="Controleer elke (secs)"
  3937.             prefs_check_labels_label="Account"
  3938.             prefs_check_labels_new="[nieuw account]"
  3939.             prefs_check_labels_remove="Verwijder account"
  3940.             prefs_external="Externe Commando's"
  3941.             prefs_external_browser="Commando uitvoeren na klikken op tray icoon"
  3942.             prefs_external_browser2="gebruik %u om het Gmail web adres te vertegenwoordigen"
  3943.             prefs_external_mail_command="Commando uitvoeren bij nieuwe berichten:"
  3944.             prefs_external_nomail_command="Commando uitvoeren bij geen berichten:"
  3945.             prefs_lang="Taal"
  3946.             prefs_login="Account informatie"
  3947.             prefs_login_pass="_Wachtwoord"
  3948.             prefs_login_save="Wegschrijven wachtwoord"
  3949.             prefs_login_save_kwallet="in KDE portefeuille"
  3950.             prefs_login_save_plain="als normale tekst"
  3951.             prefs_login_user="_Gebruikersnaam"
  3952.             prefs_tray="Mededelingengebied"
  3953.             prefs_tray_bg="Instelling mededelingengebied achtergrond ..."
  3954.             prefs_tray_error_icon="Gebruik voorkeurs fout icoon"
  3955.             prefs_tray_mail_icon="Gebruik standaard bericht icoon"
  3956.             prefs_tray_no_mail_icon="Gebruik standaard geen bericht icoon"
  3957.             prefs_tray_pdelay="Laat nieuwe berichten popup zien voor "
  3958.             prefs_tray_pdelay2=" seconden" />
  3959.   <Language name="Norsk"
  3960.             login_err="Feil:: Feil brukernavn eller passord"
  3961.             login_title="Gmail login"
  3962.             mail_archive="Arkivér"
  3963.             mail_archiving="Arkiverer ..."
  3964.             mail_delete="Slett"
  3965.             mail_deleting="Sletter ..."
  3966.             mail_mark="Marker lest"
  3967.             mail_mark_all="Marker alle som lest"
  3968.             mail_marking="Markerer lest ..."
  3969.             mail_marking_all="Markerer alle lest ..."
  3970.             mail_open="Åpne"
  3971.             mail_report_spam="Rapporter spam"
  3972.             mail_reporting_spam="Rapporterer spam ..."
  3973.             menu_about="_Om Checkgmail"
  3974.             menu_check="_Se etter ny e-post på Gmail"
  3975.             menu_compose="Skriv e-post"
  3976.             menu_prefs="_Instillinger"
  3977.             menu_undo="_angre sidste handling ..."
  3978.             notify_and="og"
  3979.             notify_check="Ser etter ny e-post på Gmail ..."
  3980.             notify_from="Fra:"
  3981.             notify_login="Logger inn på Gmail ..."
  3982.             notify_multiple1="Det er "
  3983.             notify_multiple2=" ny e-post ..."
  3984.             notify_new_mail="Ny e-post fra "
  3985.             notify_no_mail="Ingen ny e-post"
  3986.             notify_no_subject="(intet emne)"
  3987.             notify_no_text="(ingen tekst)"
  3988.             notify_single1="Det er "
  3989.             notify_single2=" ny e-post ..."
  3990.             notify_undoing="Avbryt siste handling ..."
  3991.             prefs="CheckGmail innstillinger"
  3992.             prefs_check="Se etter ny e-post"
  3993.             prefs_check_24_hour="24 timers ur"
  3994.             prefs_check_archive="Arkivér markerer også lest"
  3995.             prefs_check_atom="Feed adresse"
  3996.             prefs_check_delay="Se etter ny e-post hver "
  3997.             prefs_check_delay2=" sekunder"
  3998.             prefs_check_labels="Sjekk også følgende merker:"
  3999.             prefs_check_labels_add="Legg til merke"
  4000.             prefs_check_labels_delay="Sjekk hvert (sekn)"
  4001.             prefs_check_labels_label="Merke"
  4002.             prefs_check_labels_new="[Nytt merke]"
  4003.             prefs_check_labels_remove="Fjern merke"
  4004.             prefs_external="Eksterne programmer"
  4005.             prefs_external_browser="Nettleser"
  4006.             prefs_external_browser2="(%u representerer Gmail adressen)"
  4007.             prefs_external_mail_command="Kommando ved ny e-post:"
  4008.             prefs_external_nomail_command="Kommando ved ingen nye e-poster:"
  4009.             prefs_lang="Språk"
  4010.             prefs_login="Logindetaljer"
  4011.             prefs_login_pass="_passord"
  4012.             prefs_login_save="Lagre passord"
  4013.             prefs_login_save_kwallet="i KDE tegnebok"
  4014.             prefs_login_save_plain="som tekst"
  4015.             prefs_login_user="_Brukernavn"
  4016.             prefs_tray="Statusfelt"
  4017.             prefs_tray_bg="Sett statusfelt bakgrund ..."
  4018.             prefs_tray_error_icon="Bruk selvvalgt 'feil' ikon"
  4019.             prefs_tray_mail_icon="Bruk selvvalgt 'ny e-post' ikon"
  4020.             prefs_tray_no_mail_icon="Brug selvvalgt 'ingen e-post' ikon"
  4021.             prefs_tray_pdelay="Vis ny e-post popup i "
  4022.             prefs_tray_pdelay2=" sekunder" />
  4023.   <Language name="Polski"
  4024.             login_err="Błąd: Zły login lub hasło"
  4025.             login_title="Logowanie do Gmail ..."
  4026.             mail_archive="Archiwizuj"
  4027.             mail_archiving="Archiwizuje ..."
  4028.             mail_delete="Usuń"
  4029.             mail_deleting="Usuwam ..."
  4030.             mail_mark="Zaznacz jako przeczytane"
  4031.             mail_mark_all="Zaznacz wszystko jako przeczytane"
  4032.             mail_marking="Zaznaczam jako przeczytane ..."
  4033.             mail_marking_all="Zaznaczam wszystko jako przeczytane ..."
  4034.             mail_open="Otwórz"
  4035.             mail_report_spam="Raportuj spam"
  4036.             mail_reporting_spam="Raportuje spam ..."
  4037.             menu_about="_O programie"
  4038.             menu_check="_Sprawdź pocztę"
  4039.             menu_compose="Napisz list"
  4040.             menu_prefs="_Preferencje"
  4041.             menu_undo="_Cofnij ostatnią operacje"
  4042.             notify_and="i"
  4043.             notify_check="Sprawdzam Gmail ..."
  4044.             notify_from="Od:"
  4045.             notify_login="Logowanie do Gmail ..."
  4046.             notify_multiple1="Są "
  4047.             notify_multiple2=" nowe wiadomości ..."
  4048.             notify_new_mail="Nowa poczta od "
  4049.             notify_no_mail="Brak nowych wiadomości"
  4050.             notify_no_subject="(brak tematu)"
  4051.             notify_no_text="(brak treści)"
  4052.             notify_single1="Jest "
  4053.             notify_single2=" nowa wiadomość ..."
  4054.             notify_undoing="Cofam ostatnią operację ..."
  4055.             prefs="CheckGmail - preferencje"
  4056.             prefs_check="Sprawdzanie poczty"
  4057.             prefs_check_24_hour="zegar 24-o godzinny"
  4058.             prefs_check_archive="Archiwizując oznacz również jako przeczytane"
  4059.             prefs_check_atom="Adres "
  4060.             prefs_check_delay="Sprawdzaj pocztę co "
  4061.             prefs_check_delay2=" sekund"
  4062.             prefs_check_labels="Sprawdź też etykiety:"
  4063.             prefs_check_labels_add="Dodaj etykietę"
  4064.             prefs_check_labels_delay="Sprawdź co: (sekund)"
  4065.             prefs_check_labels_label="Etykieta"
  4066.             prefs_check_labels_new="[nowa etykieta]"
  4067.             prefs_check_labels_remove="Usuń etykietę"
  4068.             prefs_external="Zewnętrzne polecenia"
  4069.             prefs_external_browser="Polecenie do wykonania po kliknięciu w ikonkę"
  4070.             prefs_external_browser2="(w miejscu %u zostanie wstawiony adres Gmail)"
  4071.             prefs_external_mail_command="Polecenie do wykonania gdy przyjdzie nowa wiadomość:"
  4072.             prefs_external_nomail_command="Polecenie do wykonania gdy nie ma nowych wiadomości:"
  4073.             prefs_lang="Język"
  4074.             prefs_login="Informacje o koncie"
  4075.             prefs_login_pass="_Hasło"
  4076.             prefs_login_save="Zapisz hasło"
  4077.             prefs_login_save_kwallet="w portfelu KDE"
  4078.             prefs_login_save_plain="jako zwykły text"
  4079.             prefs_login_user="_Użytkownik"
  4080.             prefs_tray="Ikonka"
  4081.             prefs_tray_bg="Tło pod ikoną ..."
  4082.             prefs_tray_error_icon="Własna ikona błędu"
  4083.             prefs_tray_mail_icon="Własna ikona informująca o poczcie"
  4084.             prefs_tray_no_mail_icon="Własna ikona informująca o braku poczty"
  4085.             prefs_tray_pdelay="Pokazuj popup przez "
  4086.             prefs_tray_pdelay2=" sekund" />
  4087.   <Language name="Português"
  4088.             login_err="Erro: Nome de utilizador e palavra passe incorrecta"
  4089.             login_title="A autenticar no Gmail..."
  4090.             mail_archive="Arquivar"
  4091.             mail_archiving="A arquivar..."
  4092.             mail_delete="Apagar"
  4093.             mail_deleting="A apagar ..."
  4094.             mail_mark="Marcar como lido"
  4095.             mail_mark_all="Marcar todas como lidas"
  4096.             mail_marking="A marcar como lida ..."
  4097.             mail_marking_all="A marcar todas como lidas..."
  4098.             mail_open="Abrir"
  4099.             mail_report_spam="Reportar spam"
  4100.             mail_reporting_spam="A reportar spam ..."
  4101.             menu_about="_Sobre"
  4102.             menu_check="_Verificar mensagens"
  4103.             menu_compose="Criar nova mensagem"
  4104.             menu_prefs="_Preferências"
  4105.             menu_undo="_Desfazer última acção"
  4106.             notify_and="e"
  4107.             notify_check="A verificar Gmail ..."
  4108.             notify_from="De:"
  4109.             notify_login="A autenticar no Gmail ..."
  4110.             notify_multiple1="Existem "
  4111.             notify_multiple2=" mensagens novas..."
  4112.             notify_new_mail="Nova mensagem de "
  4113.             notify_no_mail="Nenhuma mensagem nova"
  4114.             notify_no_subject="(sem assunto)"
  4115.             notify_no_text="(sem texto)"
  4116.             notify_single1="Existe "
  4117.             notify_single2=" mensagem nova ..."
  4118.             notify_undoing="A desfazer ultíma acção ..."
  4119.             prefs="Preferências do CheckGmail"
  4120.             prefs_check="Verificação do Correio"
  4121.             prefs_check_24_hour="24"
  4122.             prefs_check_archive="Arquivo também marca como lido"
  4123.             prefs_check_atom="Endereço feed"
  4124.             prefs_check_delay="Verificar Caixa de Entrada por mensagens a cada "
  4125.             prefs_check_delay2=" segs"
  4126.             prefs_check_labels="Verificar também as seguintes etiquetas:"
  4127.             prefs_check_labels_add="Adicionar etiqueta"
  4128.             prefs_check_labels_delay="Verificar a cada (segs)"
  4129.             prefs_check_labels_label="Etiqueta"
  4130.             prefs_check_labels_new="[nova etiqueta]"
  4131.             prefs_check_labels_remove="Remover etiqueta"
  4132.             prefs_external="Comandos Externos"
  4133.             prefs_external_browser="Comando a executar ao clicar no ícone"
  4134.             prefs_external_browser2="(use %u para representar o endereço web do Gmail)"
  4135.             prefs_external_mail_command="Comando a executar com novas mensagens:"
  4136.             prefs_external_nomail_command="Comando a executar quando não houver mensagens:"
  4137.             prefs_lang="Ídioma"
  4138.             prefs_login="Dados da conta"
  4139.             prefs_login_pass="_Senha"
  4140.             prefs_login_save="Guardar senha"
  4141.             prefs_login_save_kwallet="na carteira do KDE"
  4142.             prefs_login_save_plain="como texto"
  4143.             prefs_login_user="_Nome do utilizador"
  4144.             prefs_tray="Área de notificação"
  4145.             prefs_tray_bg="Definir côr de fundo ..."
  4146.             prefs_tray_error_icon="Personalizar ícone de erro"
  4147.             prefs_tray_mail_icon="Personalizar ícone de mensagem recebida"
  4148.             prefs_tray_no_mail_icon="Personalizar ícone de nenhuma mensagem"
  4149.             prefs_tray_pdelay="Mostrar popup de nova mensagem durante "
  4150.             prefs_tray_pdelay2=" segs" />
  4151.   <Language name="Português (Brasil)"
  4152.             login_err="Erro: Nome de usuário e senha incorreta"
  4153.             login_title="Autenticando no Gmail..."
  4154.             mail_archive="Arquivar"
  4155.             mail_archiving="Arquivando..."
  4156.             mail_delete="Apagar"
  4157.             mail_deleting="Apagando ..."
  4158.             mail_mark="Marcar como lido"
  4159.             mail_mark_all="Marcar todas como lidas"
  4160.             mail_marking="Marcando como lida ..."
  4161.             mail_marking_all="Marcando todas como lidas..."
  4162.             mail_open="Abrir"
  4163.             mail_report_spam="Reportar spam"
  4164.             mail_reporting_spam="Reportando spam ..."
  4165.             menu_about="_Sobre"
  4166.             menu_check="_Verificar mensagens"
  4167.             menu_compose="Criar nova mensagem"
  4168.             menu_prefs="_Preferências"
  4169.             menu_undo="_Desfazer última ação"
  4170.             notify_and="e"
  4171.             notify_check="Verificando Gmail ..."
  4172.             notify_from="De:"
  4173.             notify_login="Autenticando no Gmail ..."
  4174.             notify_multiple1="Existem "
  4175.             notify_multiple2=" mensagens novas..."
  4176.             notify_new_mail="Nova mensagem de "
  4177.             notify_no_mail="Nenhuma mensagem nova"
  4178.             notify_no_subject="(sem assunto)"
  4179.             notify_no_text="(sem texto)"
  4180.             notify_single1="Existe "
  4181.             notify_single2=" mensagem nova ..."
  4182.             notify_undoing="Desfazendo-se da última ação ..."
  4183.             prefs="Preferências do CheckGmail"
  4184.             prefs_check="Verificação do Correio"
  4185.             prefs_check_24_hour="Utilizar padrão de relógio 24h"
  4186.             prefs_check_archive="Quando arquivar, também marcar como lido"
  4187.             prefs_check_atom="Endereço feed"
  4188.             prefs_check_delay="Verificar por novas mensagens a cada "
  4189.             prefs_check_delay2=" segs"
  4190.             prefs_check_labels="Selecione também as seguintes etiquetas:"
  4191.             prefs_check_labels_add="Nova etiqueta"
  4192.             prefs_check_labels_delay="Verificar a cada (segs)"
  4193.             prefs_check_labels_label="Etiqueta"
  4194.             prefs_check_labels_new="[nova etiqueta]"
  4195.             prefs_check_labels_remove="Remover etiqueta"
  4196.             prefs_external="Comandos Externos"
  4197.             prefs_external_browser="Comando a executar ao clicar no ícone"
  4198.             prefs_external_browser2="(use %u para representar o endereço web do Gmail)"
  4199.             prefs_external_mail_command="Comando a executar com novas mensagens:"
  4200.             prefs_external_nomail_command="Comando a executar quando não houver mensagens:"
  4201.             prefs_lang="Idioma"
  4202.             prefs_login="Dados da conta"
  4203.             prefs_login_pass="_Senha"
  4204.             prefs_login_save="Salvar senha"
  4205.             prefs_login_save_kwallet="na carteira do KDE"
  4206.             prefs_login_save_plain="como texto"
  4207.             prefs_login_user="_Nome do usuário"
  4208.             prefs_tray="Área de notificação"
  4209.             prefs_tray_bg="Definir côr de fundo ..."
  4210.             prefs_tray_error_icon="Personalizar ícone de erro"
  4211.             prefs_tray_mail_icon="Personalizar ícone de mensagem recebida"
  4212.             prefs_tray_no_mail_icon="Personalizar ícone de nenhuma mensagem"
  4213.             prefs_tray_pdelay="Mostrar popup de nova mensagem durante "
  4214.             prefs_tray_pdelay2=" segs" />
  4215.   <Language name="Romană"
  4216.             login_err="Eroare: Utilizator sau parolă incorecte"
  4217.             login_title="Autentificare la Gmail ..."
  4218.             mail_archive="Arhivă"
  4219.             mail_archiving="Arhivez ..."
  4220.             mail_delete="Şterge"
  4221.             mail_deleting="Şterg ..."
  4222.             mail_mark="Marcaţi ca citită"
  4223.             mail_mark_all="Marcheaza toate ca citite"
  4224.             mail_marking="Marchez ca citită ..."
  4225.             mail_marking_all="Marchez toate ca citite ..."
  4226.             mail_open="Deschide"
  4227.             mail_report_spam="Raportează ca spam"
  4228.             mail_reporting_spam="Raportez ca spam ..."
  4229.             menu_about="_Despre"
  4230.             menu_check="_Verificare mail"
  4231.             menu_compose="Compune mail nou"
  4232.             menu_prefs="_Preferinţe"
  4233.             menu_undo="_Anulează ultima acţiune"
  4234.             notify_and="şi"
  4235.             notify_check="Verific Gmail ..."
  4236.             notify_from="De la:"
  4237.             notify_login="Autentificare la Gmail ..."
  4238.             notify_multiple1="Sunt disponibile "
  4239.             notify_multiple2=" mesaje noi ..."
  4240.             notify_new_mail="Mail nou de la "
  4241.             notify_no_mail="Nici un mail nou"
  4242.             notify_no_subject="(fară subiect)"
  4243.             notify_no_text="(fară text)"
  4244.             notify_single1="Este disponibil "
  4245.             notify_single2=" mesaj nou ..."
  4246.             notify_undoing="Anulez ultima acţiune ..."
  4247.             prefs="Preferinţe CheckGmail"
  4248.             prefs_check="Verific mailul"
  4249.             prefs_check_24_hour="Afişare ceas în format 24 ore"
  4250.             prefs_check_archive="Marchează şi Arhiva ca citită"
  4251.             prefs_check_atom="Adresă feed "
  4252.             prefs_check_delay="Verifică Căsuţa Poştală la fiecare "
  4253.             prefs_check_delay2=" secunde"
  4254.             prefs_check_labels="Deasemenea verifică şi următoarele etichete:"
  4255.             prefs_check_labels_add="Adaugă etichetă"
  4256.             prefs_check_labels_delay="Verifică la fiecare (secunde)"
  4257.             prefs_check_labels_label="Etichetă"
  4258.             prefs_check_labels_new="[etichetă nouă]"
  4259.             prefs_check_labels_remove="Şterge eticheta"
  4260.             prefs_external="Comenzi Externe"
  4261.             prefs_external_browser="Comandă de executat la apăsarea icon-ului:"
  4262.             prefs_external_browser2="(foloseşte %u pentru a reprezenta adresa web Gmail)"
  4263.             prefs_external_mail_command="Comandă de executat la mail nou:"
  4264.             prefs_external_nomail_command="Comandă de executat când nu este mail:"
  4265.             prefs_lang="Limba"
  4266.             prefs_login="Detalii autentificare"
  4267.             prefs_login_pass="_Parolă"
  4268.             prefs_login_save="Salvează parola"
  4269.             prefs_login_save_kwallet="în KDE wallet"
  4270.             prefs_login_save_plain="ca text simplu"
  4271.             prefs_login_user="_Utilizator"
  4272.             prefs_tray="Zona de notificare"
  4273.             prefs_tray_bg="Selectează fundal zonă de notificare ..."
  4274.             prefs_tray_error_icon="Foloseşte iconiţă de eroare diferită"
  4275.             prefs_tray_mail_icon="Foloseşte iconiţă de mail diferită"
  4276.             prefs_tray_no_mail_icon="Foloseşte iconiţă fară mail diferită"
  4277.             prefs_tray_pdelay="Arată fereastra de notificare mail nou pentru "
  4278.             prefs_tray_pdelay2=" secunde" />
  4279.   <Language name="Slovenčina"
  4280.             login_err="Chyba: Nesprávne prihlasovacie meno alebo heslo"
  4281.             login_title="Prihlasuje sa na Gmail ..."
  4282.             mail_archive="Archivovať"
  4283.             mail_archiving="Archivuje sa ..."
  4284.             mail_delete="Odstrániť"
  4285.             mail_deleting="Odstraňuje sa ..."
  4286.             mail_mark="Označiť ako prečítané"
  4287.             mail_mark_all="Označiť všetko ako prečítané"
  4288.             mail_marking="Označuje sa ako prečítané ..."
  4289.             mail_marking_all="Označuje sa všetko ako prečítané ..."
  4290.             mail_open="Otvoriť"
  4291.             mail_report_spam="Nahlásiť spam"
  4292.             mail_reporting_spam="Nahlasuje sa spam ..."
  4293.             menu_about="_O programe..."
  4294.             menu_check="_Skontrolovať poštu"
  4295.             menu_compose="Zostaviť správu"
  4296.             menu_prefs="_Nastavenia"
  4297.             menu_undo="_Odvolať poslednú operáciu"
  4298.             notify_and="a"
  4299.             notify_check="Kontroluje sa Gmail ..."
  4300.             notify_from="Od:"
  4301.             notify_login="Prihlasuje sa na Gmail ..."
  4302.             notify_multiple1="Máte nových správ: "
  4303.             notify_multiple2=" ..."
  4304.             notify_new_mail="Nová správa od: "
  4305.             notify_no_mail="Žiadna nová pošta"
  4306.             notify_no_subject="(bez predmetu)"
  4307.             notify_no_text="(bez textu)"
  4308.             notify_single1="Máte "
  4309.             notify_single2=" novú správu ..."
  4310.             notify_undoing="Odvoláva sa posledná operácia ..."
  4311.             prefs="Nastavenia CheckGmail"
  4312.             prefs_check="Kontrola pošty"
  4313.             prefs_check_24_hour="24-hodinový čas"
  4314.             prefs_check_archive="Archivovanie označí ako prečítané"
  4315.             prefs_check_atom="Adresa zdroja"
  4316.             prefs_check_delay="Kontrola schránky každých "
  4317.             prefs_check_delay2=" s"
  4318.             prefs_check_labels="Skontrolovať aj tieto zdroje:"
  4319.             prefs_check_labels_add="Pridať zdroj"
  4320.             prefs_check_labels_delay="Interval (v sekundách)"
  4321.             prefs_check_labels_label="Zdroj"
  4322.             prefs_check_labels_new="[nový zdroj]"
  4323.             prefs_check_labels_remove="Zmazať zdroj"
  4324.             prefs_external="Externé príkazy"
  4325.             prefs_external_browser="Príkazy pri kliknutí na ikonu v systémovej lište:"
  4326.             prefs_external_browser2="(použite %u namiesto web-adresy Gmail-u)"
  4327.             prefs_external_mail_command="Príkaz pri zistení novej pošty:"
  4328.             prefs_external_nomail_command="Príkaz pri žiadnej novej pošte:"
  4329.             prefs_lang="Jazyk"
  4330.             prefs_login="Podrobnosti prihlásenia"
  4331.             prefs_login_pass="_Heslo"
  4332.             prefs_login_save="Uložiť heslo"
  4333.             prefs_login_save_kwallet="do KDE wallet"
  4334.             prefs_login_save_plain="ako prostý text"
  4335.             prefs_login_user="_Meno"
  4336.             prefs_tray="Systémová lišta"
  4337.             prefs_tray_bg="Nastaviť pozadie lišty ..."
  4338.             prefs_tray_error_icon="Vlastnú ikonu - chyba"
  4339.             prefs_tray_mail_icon="Vlastnú ikonu - pošta"
  4340.             prefs_tray_no_mail_icon="Vlastnú ikonu - žiadna pošta"
  4341.             prefs_tray_pdelay="Zobraziť okno novej pošty počas "
  4342.             prefs_tray_pdelay2=" s" />
  4343.   <Language name="Slovenščina"
  4344.             login_err="Napaka: Napačno uporabniško ime ali geslo"
  4345.             login_title="Prijavi se v Gmail ..."
  4346.             mail_archive="Arhiviraj"
  4347.             mail_archiving="Arhiviram ..."
  4348.             mail_delete="Izbriši"
  4349.             mail_deleting="Brišem ..."
  4350.             mail_mark="Označi kot prebrano"
  4351.             mail_mark_all="Označi vse kot prebrano"
  4352.             mail_marking="Označujem kot prebrano ..."
  4353.             mail_marking_all="Označujem vse kot prebrano ..."
  4354.             mail_open="Odpri"
  4355.             mail_report_spam="Prijavi vslijeno pošto"
  4356.             mail_reporting_spam="Poročam vsiljeno pošto ..."
  4357.             menu_about="_O CheckGmail"
  4358.             menu_check="_Preglej pošto"
  4359.             menu_compose="Novo sporočilo"
  4360.             menu_prefs="_Nastavitve"
  4361.             menu_undo="_Razveljavi zadnjo akcijo"
  4362.             notify_and="in"
  4363.             notify_check="Pregledujem Gmail ..."
  4364.             notify_from="Od:"
  4365.             notify_login="Prijavljanje v Gmail ..."
  4366.             notify_multiple1="V predalu je "
  4367.             notify_multiple2=" sporočil ..."
  4368.             notify_new_mail="Nova pošta od "
  4369.             notify_no_mail="Ni nove pošte"
  4370.             notify_no_subject="(brez zadeve)"
  4371.             notify_no_text="(ni besedila)"
  4372.             notify_single1="V predalu je "
  4373.             notify_single2=" novo sporočilo ..."
  4374.             notify_undoing="Razveljavljam zadnjo akcijo ..."
  4375.             prefs="CheckGmail nastavitve"
  4376.             prefs_check="Preverjanje pošte"
  4377.             prefs_check_24_hour="24 urni čas"
  4378.             prefs_check_archive="Arhiviraj označi kot prebrano"
  4379.             prefs_check_atom="Naslov informacij"
  4380.             prefs_check_delay="Preveri pošto vsakih "
  4381.             prefs_check_delay2=" sekund"
  4382.             prefs_check_labels="Also check the following labels:"
  4383.             prefs_check_labels_add="Add label"
  4384.             prefs_check_labels_delay="Check every (secs)"
  4385.             prefs_check_labels_label="Label"
  4386.             prefs_check_labels_new="[new label]"
  4387.             prefs_check_labels_remove="Remove label"
  4388.             prefs_external="Znanji ukazi"
  4389.             prefs_external_browser="Ukaz, ki se bo izvršil ob kliku na ikono na pultu"
  4390.             prefs_external_browser2="(uporabi %u da predstaviš Gmail domačo stran)"
  4391.             prefs_external_mail_command="Ukaz za izvršitev ob novem sporočilu:"
  4392.             prefs_external_nomail_command="Ukaz, ki se izvrši če ni nobene pošte:"
  4393.             prefs_lang="Jezik"
  4394.             prefs_login="Podrobnosti prijave"
  4395.             prefs_login_pass="_Geslo"
  4396.             prefs_login_save="Shrani geslo"
  4397.             prefs_login_save_kwallet="v KDE denarnico"
  4398.             prefs_login_save_plain="kot navaden tekst"
  4399.             prefs_login_user="_Uporabniško ime"
  4400.             prefs_tray="Sistemski pult"
  4401.             prefs_tray_bg="Izberi odzadje pulta ..."
  4402.             prefs_tray_error_icon="Uporabi ikono po meri za napako"
  4403.             prefs_tray_mail_icon="Uporabi ikono po meri za sporočila"
  4404.             prefs_tray_no_mail_icon="Uporabi ikono po meri za brez sporočil"
  4405.             prefs_tray_pdelay="Ob novem sporočilu prikaži okno za "
  4406.             prefs_tray_pdelay2=" sek." />
  4407.   <Language name="Suomi"
  4408.             login_err="Virhe: Väärä käyttäjätunnus tai salasana"
  4409.             login_title="Kirjaudutaan Gmailiin ..."
  4410.             mail_archive="Arkistoi"
  4411.             mail_archiving="Arkistoidaan ..."
  4412.             mail_delete="Poista"
  4413.             mail_deleting="Poistetaan ..."
  4414.             mail_mark="Merkitse luetuksi"
  4415.             mail_mark_all="Merkitse kaikki luetuiksi"
  4416.             mail_marking="Merkitään luetuksi ..."
  4417.             mail_marking_all="Merkitään kaikki luetuiksi ..."
  4418.             mail_open="Avaa"
  4419.             mail_report_spam="Ilmoita roskapostista"
  4420.             mail_reporting_spam="Ilmoitetaan roskapostista ..."
  4421.             menu_about="_Tietoja"
  4422.             menu_check="_Tarkista posti"
  4423.             menu_compose="Luo uusi viesti"
  4424.             menu_prefs="_Asetukset"
  4425.             menu_undo="_Peru viime toiminto"
  4426.             notify_and="ja"
  4427.             notify_check="Tarkistetaan postia ..."
  4428.             notify_from="Lähettäjä:"
  4429.             notify_login="Kirjaudutaan Gmailiin ..."
  4430.             notify_multiple1="Sinulle on "
  4431.             notify_multiple2=" uutta viestiä ..."
  4432.             notify_new_mail="Uutta postia, lähettäjä "
  4433.             notify_no_mail="Ei uusia viestejä"
  4434.             notify_no_subject="(ei aihetta)"
  4435.             notify_no_text="(ei tekstiä)"
  4436.             notify_single1="Sinulle on "
  4437.             notify_single2=" uusi viesti ..."
  4438.             notify_undoing="Perutaan viime toimintoa ..."
  4439.             prefs="CheckGmail asetukset"
  4440.             prefs_check="Postin tarkistus"
  4441.             prefs_check_24_hour="24-tuntinen kello"
  4442.             prefs_check_archive="Arkistoiminen merkitsee luetuksi"
  4443.             prefs_check_atom="Syötteen osoite"
  4444.             prefs_check_delay="Tarkista posti "
  4445.             prefs_check_delay2=" sekunnin välein"
  4446.             prefs_check_labels="Also check the following labels:"
  4447.             prefs_check_labels_add="Add label"
  4448.             prefs_check_labels_delay="Check every (secs)"
  4449.             prefs_check_labels_label="Label"
  4450.             prefs_check_labels_new="[new label]"
  4451.             prefs_check_labels_remove="Remove label"
  4452.             prefs_external="Ulkoiset komennot"
  4453.             prefs_external_browser="Kun ilmoitusalueen kuvaketta painetaan, suorita komento:"
  4454.             prefs_external_browser2="(%u kuvastaa Gmailin web osoitetta)"
  4455.             prefs_external_mail_command="Kun uutta postia saapuu, suorita komento:"
  4456.             prefs_external_nomail_command="Kun uutta postia ei ole saapunut, suorita komento:"
  4457.             prefs_lang="Kieli"
  4458.             prefs_login="Kirjautumisasetukset"
  4459.             prefs_login_pass="_Salasana"
  4460.             prefs_login_save="Tallenna salasana"
  4461.             prefs_login_save_kwallet="KDE lompakkoon"
  4462.             prefs_login_save_plain="pelkkäteksti muodossa"
  4463.             prefs_login_user="_Käyttäjätunnus"
  4464.             prefs_tray="Ilmoitusalue"
  4465.             prefs_tray_bg="Aseta ilmoitusalueen tausta ..."
  4466.             prefs_tray_error_icon="Käytä omaa virhekuvaketta"
  4467.             prefs_tray_mail_icon="Käytä omaa uutta postia -kuvaketta"
  4468.             prefs_tray_no_mail_icon="Käytä omaa ei postia -kuvaketta"
  4469.             prefs_tray_pdelay="Näytä ilmoitus saapuneesta postista "
  4470.             prefs_tray_pdelay2=" sekuntia" />
  4471.   <Language name="Svenska"
  4472.             login_err="Fel: Felaktigt användarnamn eller lösenord"
  4473.             login_title="Gmail Login ..."
  4474.             mail_archive="Arkiv"
  4475.             mail_archiving="Arkiverar ..."
  4476.             mail_delete="Radera"
  4477.             mail_deleting="Raderar ..."
  4478.             mail_mark="Markera läst"
  4479.             mail_mark_all="Markera alla som lästa"
  4480.             mail_marking="Markerar läst ..."
  4481.             mail_marking_all="Markerar alla lästa ..."
  4482.             mail_open="Öppna"
  4483.             mail_report_spam="Rapportera skräppost"
  4484.             mail_reporting_spam="Rapporterar skräppost ..."
  4485.             menu_about="_Om"
  4486.             menu_check="_Kolla mail"
  4487.             menu_compose="Skriv ett mail"
  4488.             menu_prefs="_Inställningar"
  4489.             menu_undo="_Ångra senast handling"
  4490.             notify_and="och"
  4491.             notify_check="Kollar Gmail ..."
  4492.             notify_from="Från:"
  4493.             notify_login="Loggar in till Gmail ..."
  4494.             notify_multiple1="Det finns"
  4495.             notify_multiple2="nya meddelanden ..."
  4496.             notify_new_mail="Nytt mail från"
  4497.             notify_no_mail="Inga nya mail"
  4498.             notify_no_subject="(inget ämne)"
  4499.             notify_no_text="(ingen text)"
  4500.             notify_single1="Det finns"
  4501.             notify_single2="nytt meddelande ..."
  4502.             notify_undoing="Ångrar senaste handlingen ..."
  4503.             prefs="CheckGmail inställningar"
  4504.             prefs_check="Se efter nya mail"
  4505.             prefs_check_24_hour="24-timmars klocka"
  4506.             prefs_check_archive="Arkivering markerar också som läst"
  4507.             prefs_check_atom="Feed adress"
  4508.             prefs_check_delay="Kolla mail varje"
  4509.             prefs_check_delay2="sekund"
  4510.             prefs_check_labels="Also check the following labels:"
  4511.             prefs_check_labels_add="Add label"
  4512.             prefs_check_labels_delay="Check every (secs)"
  4513.             prefs_check_labels_label="Label"
  4514.             prefs_check_labels_new="[new label]"
  4515.             prefs_check_labels_remove="Remove label"
  4516.             prefs_external="Externa kommandon"
  4517.             prefs_external_browser="Kommando att exekvera vid klick på fältikonen"
  4518.             prefs_external_browser2="(använd %u för att representera Gmail webadressen)"
  4519.             prefs_external_mail_command="Kommando att exekvera vid nytt mail:"
  4520.             prefs_external_nomail_command="Kommando att exekvera vid inget mail:"
  4521.             prefs_lang="Språk"
  4522.             prefs_login="Logindetaljer"
  4523.             prefs_login_pass="_Lösenord"
  4524.             prefs_login_save="Spara lösenord"
  4525.             prefs_login_save_kwallet="i KDE plånbok"
  4526.             prefs_login_save_plain="som klartext"
  4527.             prefs_login_user="_Användarnamn"
  4528.             prefs_tray="Systemfält"
  4529.             prefs_tray_bg="Välj fältbakgrund ..."
  4530.             prefs_tray_error_icon="Använd annan fel-ikon"
  4531.             prefs_tray_mail_icon="Använd annan mail-ikon"
  4532.             prefs_tray_no_mail_icon="Använd annan ingen mail-ikon"
  4533.             prefs_tray_pdelay="Visa nytt mail popup i"
  4534.             prefs_tray_pdelay2="sekunder" />
  4535.   <Language name="hrvatski"
  4536.             login_err="Greška: pogrešno korisničko ime ili zaporka"
  4537.             login_title="Prijava na Gmail ..."
  4538.             mail_archive="Arhiviraj"
  4539.             mail_archiving="Arhiviranje ..."
  4540.             mail_delete="Obriši"
  4541.             mail_deleting="Brisanje ..."
  4542.             mail_mark="Označi kao pročitano"
  4543.             mail_mark_all="Sve označi kao pročitano"
  4544.             mail_marking="Označavanje kao pročitanog ..."
  4545.             mail_marking_all="Označavanje svega kao pročitanog ..."
  4546.             mail_open="Otvori"
  4547.             mail_report_spam="Prijavi neželjenu poruku"
  4548.             mail_reporting_spam="Prijava neželjene poruke ..."
  4549.             menu_about="_O programu"
  4550.             menu_check="_Provjeri poštu"
  4551.             menu_compose="Napiši poruku"
  4552.             menu_prefs="_Postavke"
  4553.             menu_undo="_Poništi zadnji potez"
  4554.             notify_and="i"
  4555.             notify_check="Provjera Gmaila ..."
  4556.             notify_from="Šalje:"
  4557.             notify_login="Prijava na Gmail ..."
  4558.             notify_multiple1="Broj novih poruka: "
  4559.             notify_multiple2=" new messages ..."
  4560.             notify_new_mail="Novu poruku šalje "
  4561.             notify_no_mail="Nema novih poruka"
  4562.             notify_no_subject="(nema predmeta)"
  4563.             notify_no_text="(nema teksta)"
  4564.             notify_single1="Stigla je "
  4565.             notify_single2=" nova poruka ..."
  4566.             notify_undoing="Poništavanje zadnjeg postupka ..."
  4567.             prefs="Postavke CheckGmaila"
  4568.             prefs_check="Provjera pošte"
  4569.             prefs_check_24_hour="24-satni oblik"
  4570.             prefs_check_archive="Označi i arhiv pročitanim"
  4571.             prefs_check_atom="Adresa feeda"
  4572.             prefs_check_delay="Provjeri pristiglu poštu svakih "
  4573.             prefs_check_delay2=" sek"
  4574.             prefs_check_labels="Provjeri i sljedeće oznake:"
  4575.             prefs_check_labels_add="Dodaj oznaku"
  4576.             prefs_check_labels_delay="Provjeri svakih (sek)"
  4577.             prefs_check_labels_label="Oznaka"
  4578.             prefs_check_labels_new="[nova oznaka]"
  4579.             prefs_check_labels_remove="Ukloni oznaku"
  4580.             prefs_external="Vanjske naredbe"
  4581.             prefs_external_browser="Naredba za izvršenje prilikom klikanja ikonice na sistemskoj traci"
  4582.             prefs_external_browser2="(koristi %u za prikaz web adrese Gmaila)"
  4583.             prefs_external_mail_command="Naredba za izvršenje ako ima novih poruka:"
  4584.             prefs_external_nomail_command="Naredba za izvršenje ako nema novih poruka:"
  4585.             prefs_lang="Jezik"
  4586.             prefs_login="Podaci za prijavu"
  4587.             prefs_login_pass="_Zaporka"
  4588.             prefs_login_save="Spremi zaporku"
  4589.             prefs_login_save_kwallet="u KDE wallet"
  4590.             prefs_login_save_plain="kao običan text"
  4591.             prefs_login_user="_Korisničko ime"
  4592.             prefs_tray="Sistemska traka"
  4593.             prefs_tray_bg="Postavi pozadinu sistemske trake..."
  4594.             prefs_tray_error_icon="Odaberi vlastitu ikonu za pogrešku"
  4595.             prefs_tray_mail_icon="Odaberi vlastitu ikonu za novu poruku"
  4596.             prefs_tray_no_mail_icon="Odaberi vlastitu ikonu kada nema poruka"
  4597.             prefs_tray_pdelay="Prikaži prozorčić s novom porukom na "
  4598.             prefs_tray_pdelay2=" sekundi" />
  4599.   <Language name="Čeština"
  4600.             login_err="Chyba: Špatné jméno nebo heslo"
  4601.             login_title="Přihlašuji se na Gmail ..."
  4602.             mail_archive="Archivuj"
  4603.             mail_archiving="Archivuji ..."
  4604.             mail_delete="Odstraň"
  4605.             mail_deleting="Odstraňuji ..."
  4606.             mail_mark="Označ jako přečtené"
  4607.             mail_mark_all="Označ vše jako přečtené"
  4608.             mail_marking="Označuji jako přečtené ..."
  4609.             mail_marking_all="Označuji vše jako přečtené ..."
  4610.             mail_open="Otevřít"
  4611.             mail_report_spam="Nahlaš spam"
  4612.             mail_reporting_spam="Nahlašuji spam ..."
  4613.             menu_about="_O programu"
  4614.             menu_check="_Zkontroluj poštu"
  4615.             menu_compose="Napiš email"
  4616.             menu_prefs="_Nastavení"
  4617.             menu_undo="_Vrať poslední akci"
  4618.             notify_and="a"
  4619.             notify_check="Kontroluji Gmail ..."
  4620.             notify_from="Od:"
  4621.             notify_login="Přihlašuji se do Gmail ..."
  4622.             notify_multiple1="Jsou "
  4623.             notify_multiple2=" nové zprávy ..."
  4624.             notify_new_mail="Nová zpráva od "
  4625.             notify_no_mail="Žádné nové zprávy"
  4626.             notify_no_subject="(bez předmětu)"
  4627.             notify_no_text="(bez obsahu)"
  4628.             notify_single1="Je "
  4629.             notify_single2=" nová zpráva ..."
  4630.             notify_undoing="Vracím poslední akci ..."
  4631.             prefs="CheckGmail - Nastavení"
  4632.             prefs_check="Kontrolování pošty"
  4633.             prefs_check_24_hour="24-hodinový formát"
  4634.             prefs_check_archive="Při archivaci označ jako přečtené"
  4635.             prefs_check_atom="Adresa zdroje"
  4636.             prefs_check_delay="Kontroluj poštu každých "
  4637.             prefs_check_delay2=" vteřin"
  4638.             prefs_check_labels="Kontroluj také štítky:"
  4639.             prefs_check_labels_add="Přidej štítek"
  4640.             prefs_check_labels_delay="Kontroluj každých: (vteřin)"
  4641.             prefs_check_labels_label="Štítek"
  4642.             prefs_check_labels_new="[nový štítek]"
  4643.             prefs_check_labels_remove="Odstraň štítek"
  4644.             prefs_external="Příkazy"
  4645.             prefs_external_browser="Kliknutím na ikonu se provede"
  4646.             prefs_external_browser2="(řetězec %u se nahradí adresou Gmailu)"
  4647.             prefs_external_mail_command="Když přijde nová zpráva:"
  4648.             prefs_external_nomail_command="Když žádná nová zpráva nepřišla:"
  4649.             prefs_lang="Jazyk"
  4650.             prefs_login="Informace o účtu"
  4651.             prefs_login_pass="_Heslo"
  4652.             prefs_login_save="Ulož heslo"
  4653.             prefs_login_save_kwallet="w KDE peněžence"
  4654.             prefs_login_save_plain="jako běžný text"
  4655.             prefs_login_user="_Uživatel"
  4656.             prefs_tray="Tray lišta"
  4657.             prefs_tray_bg="Pozadí ikony ..."
  4658.             prefs_tray_error_icon="Použít vlastní ikonu pro chybu"
  4659.             prefs_tray_mail_icon="Použít vlastní ikonu pro novou zprávu"
  4660.             prefs_tray_no_mail_icon="Použít vlastní ikonu pro žádnou zprávu"
  4661.             prefs_tray_pdelay="Zobraz popup s novou zprávou "
  4662.             prefs_tray_pdelay2=" vteřin" />
  4663.   <Language name="Русский"
  4664.             login_err="Ошибка: Неверный логин или пароль"
  4665.             login_title="Логин в Google-Mail ..."
  4666.             mail_archive="Архивировать"
  4667.             mail_archiving="Архивирую ..."
  4668.             mail_delete="Удалить"
  4669.             mail_deleting="Удаляю ..."
  4670.             mail_mark="Пометить как прочитанное"
  4671.             mail_mark_all="Пометить все как прочитанные"
  4672.             mail_marking="Помечаю как прочитаное ..."
  4673.             mail_marking_all="Помечаю все как прочитанные ..."
  4674.             mail_open="Открыть"
  4675.             mail_report_spam="Пометить как спам"
  4676.             mail_reporting_spam="Помечаю как спам ..."
  4677.             menu_about="_О программе"
  4678.             menu_check="_Проверить почту"
  4679.             menu_compose="Новое сообщение"
  4680.             menu_prefs="_Настройки"
  4681.             menu_undo="От_менить"
  4682.             notify_and="и"
  4683.             notify_check="Проверяю Google-Mail ..."
  4684.             notify_from="От:"
  4685.             notify_login="Соединение с Google-Mail ..."
  4686.             notify_multiple1="У вас "
  4687.             notify_multiple2=" новых сообщений ..."
  4688.             notify_new_mail="Новое сообщение от "
  4689.             notify_no_mail="Нет новых сообщений"
  4690.             notify_no_subject="(без темы)"
  4691.             notify_no_text="(без сообщения)"
  4692.             notify_single1="У вас "
  4693.             notify_single2=" новое сообщение ..."
  4694.             notify_undoing="Отменить последнее изменение ..."
  4695.             prefs="Настройки CheckGmail"
  4696.             prefs_check="Проверка сообщений"
  4697.             prefs_check_24_hour="24-х часовой формат"
  4698.             prefs_check_archive="При архивировании пометить как прочитанное"
  4699.             prefs_check_atom="Feed адрес:"
  4700.             prefs_check_delay="Проверять сообщения каждые "
  4701.             prefs_check_delay2=" секунд"
  4702.             prefs_check_labels="Также проверять следующие ярлыки:"
  4703.             prefs_check_labels_add="Добавить ярлык"
  4704.             prefs_check_labels_delay="Проверять каждые (сек)"
  4705.             prefs_check_labels_label="Ярлык"
  4706.             prefs_check_labels_new="[новый ярлык]"
  4707.             prefs_check_labels_remove="Удалить ярлык"
  4708.             prefs_external="Внешние программы"
  4709.             prefs_external_browser="Web-браузер"
  4710.             prefs_external_browser2="(Вместо %u будет установлен адрес)"
  4711.             prefs_external_mail_command="Выполнять при новых сообщениях:"
  4712.             prefs_external_nomail_command="Выполнять, когда новых сообщений нет:"
  4713.             prefs_lang="Язык"
  4714.             prefs_login="Login-настройки"
  4715.             prefs_login_pass="_Пароль"
  4716.             prefs_login_save="Сохранить пароль"
  4717.             prefs_login_save_kwallet="в KDE-Wallet"
  4718.             prefs_login_save_plain="незашифрованным"
  4719.             prefs_login_user="_Логин"
  4720.             prefs_tray="Системный трей"
  4721.             prefs_tray_bg="Цвет заднего фона ..."
  4722.             prefs_tray_error_icon="Использовать свою иконку для ошибок"
  4723.             prefs_tray_mail_icon="Использовать свою иконку для новых сообщений"
  4724.             prefs_tray_no_mail_icon="Использовать свою иконку для отсутствия новых сообщений"
  4725.             prefs_tray_pdelay="Показывать оповещение "
  4726.             prefs_tray_pdelay2=" секунд" />
  4727.   <Language name="தமிழ்"
  4728.             login_err="பிழை: பயனர் பெயரில் அல்லது கடவுச்சொல்லில்"
  4729.             login_title="ஜிமெயிலினுள் நுழை ..."
  4730.             mail_archive="பேழையிலிடு"
  4731.             mail_archiving="பேழையினுள் இடுகிறது..."
  4732.             mail_delete="அழி"
  4733.             mail_deleting="அழிக்கப்படுகிறது ..."
  4734.             mail_mark="படித்ததாகக் குறி"
  4735.             mail_mark_all="அனைத்து மடல்களும் படித்ததாகக் குறி"
  4736.             mail_marking="படித்ததாகக் குறிக்கப்படுகிறது ..."
  4737.             mail_marking_all="அனைத்து மடல்களும் படித்ததாகக் குறிக்கப்படுகிறது ..."
  4738.             mail_open="மடலினைத் திற"
  4739.             mail_report_spam="ஒவ்வாத/விளம்பர மடல்"
  4740.             mail_reporting_spam="ஒவ்வாத/விளம்பர மடலெனத் தெரிவி ..."
  4741.             menu_about="_அறிவிப்பான் குறித்து"
  4742.             menu_check="_மடல் உள்ளதாவெனப் பார்"
  4743.             menu_compose="மடல் எழுத"
  4744.             menu_prefs="_அமைவு விருப்பங்கள்"
  4745.             menu_undo="_முந்தைய செயலை மாற்று"
  4746.             notify_and="மற்றும்"
  4747.             notify_check="மடல் வரவைப் பார் ..."
  4748.             notify_from="அனுப்புனர்:"
  4749.             notify_login="ஜிமெயிலுனுள் நுழைகிறது ..."
  4750.             notify_multiple1="அஞ்சல் பெட்டியில் "
  4751.             notify_multiple2=" புதிய மடல்கள் வந்துள்ளன ..."
  4752.             notify_new_mail="புதிய மடலினை  அனுப்பியவர் "
  4753.             notify_no_mail="புதிய மடல் ஏதும் இல்லை"
  4754.             notify_no_subject="(பொருள் இல்லை)"
  4755.             notify_no_text="(எழுத்து எதுவும் இல்லை)"
  4756.             notify_single1="அஞ்சல் பெட்டியில் "
  4757.             notify_single2=" புதிய மடல் உள்ளது ..."
  4758.             notify_undoing="முந்தைய செயலை  நிராகரிக்கிறது ..."
  4759.             prefs="ஜிமெயில் புதுமடல் வரத்தில் உங்களின் விருப்பங்கள்"
  4760.             prefs_check="மடலின் வரவு பார்க்கப்படுகிறது"
  4761.             prefs_check_24_hour="24 மணிநேரக் கடிகாரம்"
  4762.             prefs_check_archive="பேழையிலிட்டுப் படித்ததாகக் குறி"
  4763.             prefs_check_atom="ஆட்டோம் அல்லது ஈட்டு முகவரி"
  4764.             prefs_check_delay="அஞ்சல் பெட்டியை "
  4765.             prefs_check_delay2=" நொடிகளுக்கொருமுறை பார்"
  4766.             prefs_check_labels="கீழ்க்கண்டக் குறிகளிடப்பட்ட மடல்கள் உள்ளனவா எனப் பார்:"
  4767.             prefs_check_labels_add="புதிதாகக் குறியீட்டை  இணை"
  4768.             prefs_check_labels_delay="இவற்றை பார்ப்பதற்கான இடைவெளி (நொடிகளில்)"
  4769.             prefs_check_labels_label="குறியீடு"
  4770.             prefs_check_labels_new="[புதியக் குறியீடு]"
  4771.             prefs_check_labels_remove="குறியீட்டை  நீக்கு"
  4772.             prefs_external="வெளி ஆணை"
  4773.             prefs_external_browser="குறிப்படத்தை  சொடுக்கும் பொழுது, இயற்றப்படும் ஆணை"
  4774.             prefs_external_browser2="(ஜிமெயில் தளத்தைத் திறக்கவேண்டியத் தள உலாவி:)"
  4775.             prefs_external_mail_command="புதிய மடல் எழுதுவதற்குத் தேவையான ஆணை:"
  4776.             prefs_external_nomail_command="மடல் இல்லை  எனில் இடப்படவேண்டிய ஆணை:"
  4777.             prefs_lang="மொழி"
  4778.             prefs_login="பயனாளர் விவரங்கள்"
  4779.             prefs_login_pass="_கடவுச் சொல்"
  4780.             prefs_login_save="கடவுச் சொல்லை சேமிக்க"
  4781.             prefs_login_save_kwallet="KDE பையினுள் சேமிக்க"
  4782.             prefs_login_save_plain="வெறும் எழுத்துக்களாக சேமிக்க"
  4783.             prefs_login_user="_பயனர்"
  4784.             prefs_tray="அறிவிப்பானின் பலகை"
  4785.             prefs_tray_bg="அறிவிப்பானின் பலகையின் நிறத்தைத் தேர்ந்தெடுக்க ..."
  4786.             prefs_tray_error_icon="வழக்கமான பிழை குறிப்படத்தைப் பயன்படுத்த"
  4787.             prefs_tray_mail_icon="வழக்கமான மடல் குறிப்படத்தைப் பயன்படுத்த"
  4788.             prefs_tray_no_mail_icon="வழக்கமான மடல்-இல்லை குறிப்படத்தைப் பயன்படுத்த"
  4789.             prefs_tray_pdelay="புதிய மடலின் வருகை  அறிவிப்பை"
  4790.             prefs_tray_pdelay2="நொடிகளுக்குக் காட்டுக" />
  4791.   <Language name="Македонски"
  4792.             login_err="Грешка: Погрешно корисничко име или лозинка"
  4793.             login_title="Се логирам на Gmail ..."
  4794.             mail_archive="Архива"
  4795.             mail_archiving="Архивирам ..."
  4796.             mail_delete="Бриши"
  4797.             mail_deleting="Бришам ..."
  4798.             mail_mark="Обележи како прочитано"
  4799.             mail_mark_all="Обележи сѐ како прочитано"
  4800.             mail_marking="Обележувам како прочитано ..."
  4801.             mail_marking_all="Обележувам сѐ како прочитано ..."
  4802.             mail_open="Отвори"
  4803.             mail_report_spam="Пријави спам"
  4804.             mail_reporting_spam="Пријавувам спам ..."
  4805.             menu_about="_За"
  4806.             menu_check="_Провери пошта"
  4807.             menu_compose="Пиши пошта"
  4808.             menu_prefs="_Поставување"
  4809.             menu_undo="_Врати ја претходната акција"
  4810.             notify_and="и"
  4811.             notify_check="Проверувам на Gmail ..."
  4812.             notify_from="Од:"
  4813.             notify_login="Се логирам на Gmail ..."
  4814.             notify_multiple1="Има "
  4815.             notify_multiple2=" нови пораки ..."
  4816.             notify_new_mail="Нова пошта од "
  4817.             notify_no_mail="Нема нови пораки"
  4818.             notify_no_subject="(без наслов)"
  4819.             notify_no_text="(без текст)"
  4820.             notify_single1="Има "
  4821.             notify_single2=" нова порака ..."
  4822.             notify_undoing="Ја враќам претходната акција ..."
  4823.             prefs="CheckGmail поставувања"
  4824.             prefs_check="Проверување пошта"
  4825.             prefs_check_24_hour="24 часа"
  4826.             prefs_check_archive="Архивирај, исто така обележи како прочитано"
  4827.             prefs_check_atom="Адреса на каналот"
  4828.             prefs_check_delay="Провери го сандачето за пошта секои "
  4829.             prefs_check_delay2=" секунди"
  4830.             prefs_check_labels="Исто така провери ги следниве ознаки:"
  4831.             prefs_check_labels_add="Додај ознака"
  4832.             prefs_check_labels_delay="Провери секои (секунди)"
  4833.             prefs_check_labels_label="Ознака"
  4834.             prefs_check_labels_new="[нова ознака]"
  4835.             prefs_check_labels_remove="Тргни ознака"
  4836.             prefs_external="Надворешни команди"
  4837.             prefs_external_browser="Команда која ќе се изврши на кликање на иконата "
  4838.             prefs_external_browser2="(користи %u да ја преставиш Gmail веб адресата)"
  4839.             prefs_external_mail_command="Команда која ќе се изврши кога има нова пошта:"
  4840.             prefs_external_nomail_command="Команда која ќе се изврши кога нема нова пошта:"
  4841.             prefs_lang="Јазик"
  4842.             prefs_login="Детали за логирањето"
  4843.             prefs_login_pass="_Лозинка"
  4844.             prefs_login_save="Сними лозинка"
  4845.             prefs_login_save_kwallet="во KDE паричникот"
  4846.             prefs_login_save_plain="како обичен текст"
  4847.             prefs_login_user="_Корисничко име"
  4848.             prefs_tray="Системско ќоше"
  4849.             prefs_tray_bg="Подеси боја на ќошето"
  4850.             prefs_tray_error_icon="Користи посебна икона за грешка"
  4851.             prefs_tray_mail_icon="Користи посебна икона за нова пошта"
  4852.             prefs_tray_no_mail_icon="Користи посебна икона за немање нова пошта"
  4853.             prefs_tray_pdelay="Покажи го скокачкото прозорче за нова пошта "
  4854.             prefs_tray_pdelay2=" секунди" />
  4855.   <Language name="Biełaruskaja łacinka"
  4856.             login_err="Pamyłka: Drenny login albo parol"
  4857.             login_title="Aŭtaryzacyja ŭ Gmail ..."
  4858.             mail_archive="Archivizuj"
  4859.             mail_archiving="Archivizuje ..."
  4860.             mail_delete="Vydal"
  4861.             mail_deleting="Vydalaje ..."
  4862.             mail_mark="Paznač jak pračytanaje"
  4863.             mail_mark_all="Paznač usio jak pračytanaje"
  4864.             mail_marking="Zaznačaje jak pračytanaje ..."
  4865.             mail_marking_all="Zaznačaje usio jak pračytanaje ..."
  4866.             mail_open="Adčyni"
  4867.             mail_report_spam="Rapartuj spam"
  4868.             mail_reporting_spam="Rapartuje spam ..."
  4869.             menu_about="_Pra prahramu"
  4870.             menu_check="_Pravier poštu"
  4871.             menu_compose="Napišy list"
  4872.             menu_prefs="_Nałady"
  4873.             menu_undo="_Anuluj apošniuju aperacyju"
  4874.             notify_and="i"
  4875.             notify_check="Spraŭdžvaju Gmail ..."
  4876.             notify_from="Ad:"
  4877.             notify_login="Aŭtaryzacyja ŭ Gmail ..."
  4878.             notify_multiple1="Jość "
  4879.             notify_multiple2=" novyja listy ..."
  4880.             notify_new_mail="Novaja pošta ad "
  4881.             notify_no_mail="Niama novych listoŭ"
  4882.             notify_no_subject="(biaz temy)"
  4883.             notify_no_text="(biaz źmiestu)"
  4884.             notify_single1="Jość "
  4885.             notify_single2=" novy list ..."
  4886.             notify_undoing="Anuloŭvajecca apošniaja aperacyja ..."
  4887.             prefs="CheckGmail - nałady"
  4888.             prefs_check="Pravierka pošty"
  4889.             prefs_check_24_hour="24-hadzinny hadzińnik"
  4890.             prefs_check_archive="Aarchivizujučy paznač taksama jak pračytanaje"
  4891.             prefs_check_atom="Adras "
  4892.             prefs_check_delay="Praviaraj poštu kožnyja "
  4893.             prefs_check_delay2=" sekund"
  4894.             prefs_check_labels="Pravier taksama etykety:"
  4895.             prefs_check_labels_add="Dadaj etykietu"
  4896.             prefs_check_labels_delay="Pravier kožnyja: (sekund)"
  4897.             prefs_check_labels_label="Etykieta"
  4898.             prefs_check_labels_new="[novaja etykieta]"
  4899.             prefs_check_labels_remove="Vydal etykietu"
  4900.             prefs_external="Unutranyja zahady"
  4901.             prefs_external_browser="Zahad kab vykanać paśla kliku ŭ ikonu"
  4902.             prefs_external_browser2="(u miescy %u budzie ŭstaŭleny adras Gmail)"
  4903.             prefs_external_mail_command="Zahad kab vykanać kali pryjdzie novy list:"
  4904.             prefs_external_nomail_command="Zahad kab vykanać kali niama novych listoŭ:"
  4905.             prefs_lang="Mova"
  4906.             prefs_login="Infarmacyja pra kont"
  4907.             prefs_login_pass="_Parol"
  4908.             prefs_login_save="Zapišy parol"
  4909.             prefs_login_save_kwallet="u hametcy KDE"
  4910.             prefs_login_save_plain="jak zvyčajny tekst"
  4911.             prefs_login_user="_Karystalnik"
  4912.             prefs_tray="Ikona"
  4913.             prefs_tray_bg="Fon pad ikonaj ..."
  4914.             prefs_tray_error_icon="Ułasnaja ikona pamyłki"
  4915.             prefs_tray_mail_icon="Ułasnaja ikona novaj pošty"
  4916.             prefs_tray_no_mail_icon="Ułasnaja ikona adsutnaści pošty"
  4917.             prefs_tray_pdelay="Pakazvaj vypłyŭnoje vakno ciaham "
  4918.             prefs_tray_pdelay2=" sekund" />
  4919.   <Language name="日本語"
  4920.             login_err="エラー: ユーザーネームまたはパスワードが違います"
  4921.             login_title="Gmail にログインしています ..."
  4922.             mail_archive="アーカイブ"
  4923.             mail_archiving="アーカイブしています ..."
  4924.             mail_delete="削除"
  4925.             mail_deleting="削除しています ..."
  4926.             mail_mark="既読にする"
  4927.             mail_mark_all="すべて既読にする"
  4928.             mail_marking="既読にしています ..."
  4929.             mail_marking_all="すべてを既読にしています ..."
  4930.             mail_open="開く"
  4931.             mail_report_spam="迷惑メールを報告"
  4932.             mail_reporting_spam="迷惑メールを報告しています ..."
  4933.             menu_about="CheckGmail について"
  4934.             menu_check="メールをチェック"
  4935.             menu_compose="メールを作成"
  4936.             menu_prefs="設定"
  4937.             menu_undo="やり直し"
  4938.             notify_and="と"
  4939.             notify_check="Gmail をチェックしています ..."
  4940.             notify_from="From:"
  4941.             notify_login="Gmail にログインしています ..."
  4942.             notify_multiple1="新着メール: "
  4943.             notify_multiple2=" 通のメッセージ ..."
  4944.             notify_new_mail="新着メール from "
  4945.             notify_no_mail="新しいメールはありません"
  4946.             notify_no_subject="(件名なし)"
  4947.             notify_no_text="(テキストなし)"
  4948.             notify_single1="新着メール: "
  4949.             notify_single2=" 通のメッセージ ..."
  4950.             notify_undoing="やり直しを行っています ..."
  4951.             prefs="CheckGmail の設定"
  4952.             prefs_check="メールのチェック"
  4953.             prefs_check_24_hour="24 時間時計"
  4954.             prefs_check_archive="既読もアーカイブに入れる"
  4955.             prefs_check_atom="フィードのアドレス"
  4956.             prefs_check_delay="受信トレイをチェックする周期: "
  4957.             prefs_check_delay2=" 秒"
  4958.             prefs_check_labels="以下のラベルもチェックします:"
  4959.             prefs_check_labels_add="ラベルの追加"
  4960.             prefs_check_labels_delay="チェックの周期 (秒)"
  4961.             prefs_check_labels_label="ラベル"
  4962.             prefs_check_labels_new="[新しいラベル]"
  4963.             prefs_check_labels_remove="ラベルの削除"
  4964.             prefs_external="外部コマンド"
  4965.             prefs_external_browser="トレイのアイコンをクリック時に実行するコマンド"
  4966.             prefs_external_browser2="(%u は Gmail のウェブアドレスを指します)"
  4967.             prefs_external_mail_command="新着メールに対して実行するコマンド:"
  4968.             prefs_external_nomail_command="新着メールがない場合に実行するコマンド:"
  4969.             prefs_lang="言語"
  4970.             prefs_login="ログインの詳細"
  4971.             prefs_login_pass="パスワード"
  4972.             prefs_login_save="パスワードを保存"
  4973.             prefs_login_save_kwallet="KDE ウォレットに保存"
  4974.             prefs_login_save_plain="プレインテキストとして保存"
  4975.             prefs_login_user="ユーザーネーム"
  4976.             prefs_tray="システムトレイ"
  4977.             prefs_tray_bg="トレイの背景を設定 ..."
  4978.             prefs_tray_error_icon="カスタムのエラー・アイコンを使用"
  4979.             prefs_tray_mail_icon="カスタムのメール・アイコンを使用"
  4980.             prefs_tray_no_mail_icon="カスタムのメールなし・アイコンを使用"
  4981.             prefs_tray_pdelay="新着メール時のポップアップ表示時間: "
  4982.             prefs_tray_pdelay2=" 秒" />
  4983.   <Language name="简体中文"
  4984.             login_err="错误: 错误的用户名或密码"
  4985.             login_title="登录到Gmail ..."
  4986.             mail_archive="归档"
  4987.             mail_archiving="正在归档 ..."
  4988.             mail_delete="删除"
  4989.             mail_deleting="正在删除 ..."
  4990.             mail_mark="标记邮件为已读"
  4991.             mail_mark_all="标记邮件所有为已读"
  4992.             mail_marking="正在标记邮件为已读 ..."
  4993.             mail_marking_all="正在标记所有邮件为已读 ..."
  4994.             mail_open="打开"
  4995.             mail_report_spam="报告垃圾邮件"
  4996.             mail_reporting_spam="正在报告垃圾邮件 ..."
  4997.             menu_about="关于(_A)"
  4998.             menu_check="立即检查邮件(_C)"
  4999.             menu_compose="写邮件"
  5000.             menu_prefs="首选项(_P)"
  5001.             menu_undo="撤消前一操作(_U)"
  5002.             notify_and="和"
  5003.             notify_check="正在检查Gmail ..."
  5004.             notify_from="From:"
  5005.             notify_login="正在登录到Gmail ..."
  5006.             notify_multiple1="您有 "
  5007.             notify_multiple2=" 封新邮件 ..."
  5008.             notify_new_mail="新邮件 "
  5009.             notify_no_mail="没有新邮件"
  5010.             notify_no_subject="(无标题)"
  5011.             notify_no_text="(无正文)"
  5012.             notify_single1="您有 "
  5013.             notify_single2=" 新邮件 ..."
  5014.             notify_undoing="正在撤销前一操作 ..."
  5015.             prefs="CheckGmail首选项"
  5016.             prefs_check="检查设置"
  5017.             prefs_check_24_hour="时钟类型为24小时"
  5018.             prefs_check_archive="归档并标记为已读"
  5019.             prefs_check_atom="Feed地址"
  5020.             prefs_check_delay="检查收件箱频率 "
  5021.             prefs_check_delay2=" 秒"
  5022.             prefs_check_labels="同时检查一下标签:"
  5023.             prefs_check_labels_add="添加标签"
  5024.             prefs_check_labels_delay="检查频率(秒)"
  5025.             prefs_check_labels_label="标签"
  5026.             prefs_check_labels_new="[新标签]"
  5027.             prefs_check_labels_remove="删除标签"
  5028.             prefs_external="扩展设置"
  5029.             prefs_external_browser="点击通知栏图标启动程序"
  5030.             prefs_external_browser2="(使用 %u 表示Gmail地址)"
  5031.             prefs_external_mail_command="写邮件时启动程序:"
  5032.             prefs_external_nomail_command="无邮件时启动程序:"
  5033.             prefs_lang="界面语言"
  5034.             prefs_login="登录设置"
  5035.             prefs_login_pass="密码(_P)"
  5036.             prefs_login_save="保存密码"
  5037.             prefs_login_save_kwallet="到KDE钱包"
  5038.             prefs_login_save_plain="不加密"
  5039.             prefs_login_user="用户名(_U)"
  5040.             prefs_tray="通知栏设置"
  5041.             prefs_tray_bg="通知栏背景颜色 ..."
  5042.             prefs_tray_error_icon="个性化错误图标"
  5043.             prefs_tray_mail_icon="个性化邮件图标"
  5044.             prefs_tray_no_mail_icon="个性化无邮件图标"
  5045.             prefs_tray_pdelay="通知显示延迟 "
  5046.             prefs_tray_pdelay2=" 秒" />
  5047. </opt>
  5048.  
  5049. EOF
  5050.         my $def_xml = XMLin($default_translations, ForceArray => 1);
  5051.                
  5052.         unless (-e "$prefs_dir/lang.xml") {
  5053.                 print "Creating translations file at $prefs_dir/lang.xml ...\n";
  5054.                 # If there isn't a translation file, we create a default one
  5055.                 $translations = $default_translations;
  5056.                 open(LANG, ">$prefs_dir/lang.xml") || die("Could not open lang.xml file for writing: $!");
  5057.                 print LANG $translations;
  5058.                 close LANG;    
  5059.         } else {
  5060.                 # read translations file if it exists
  5061.                 open(LANG, "<$prefs_dir/lang.xml") || die("Could not open lang.xml file for reading: $!");
  5062.                 $translations = join("",<LANG>);
  5063.                 close LANG;
  5064.         }
  5065.                                
  5066.         my $xmlin = XMLin($translations, ForceArray => 1);
  5067.        
  5068.         my $user_trans_v = $xmlin->{Version};
  5069.                                
  5070.         my $trans_mod;
  5071.         foreach my $lang (keys(%{$def_xml->{Language}})) {
  5072.                 # print "checking $lang\n";
  5073.                
  5074.                 # Check that all translation keys exist, and add in those that don't from defaults ...
  5075.                 if ($def_xml->{Language}->{$lang}) {
  5076.                         # user language exists in defaults
  5077.                         # next if $lang eq 'English';
  5078.                         foreach (keys(%{$def_xml->{Language}->{English}})) {
  5079.                                
  5080.                                 if ($lang eq 'English') {
  5081.                                         next if ($xmlin->{Language}->{$lang}->{$_} && ($xmlin->{Language}->{$lang}->{$_} eq $def_xml->{Language}->{$lang}->{$_}));
  5082.                                         $xmlin->{Language}->{$lang}->{$_} = $def_xml->{Language}->{$lang}->{$_};
  5083.                                 } elsif ($def_xml->{Language}->{$lang}->{$_}) {
  5084.                                         # Don't overwrite if the key exists in the user trans file and the version is current
  5085.                                         next if ($xmlin->{Language}->{$lang}->{$_} && $user_trans_v eq $version);
  5086.                                         # Don't overwrite if the key is the same
  5087.                                         next if ($xmlin->{Language}->{$lang}->{$_} && ($xmlin->{Language}->{$lang}->{$_} eq $def_xml->{Language}->{$lang}->{$_}));
  5088.                                         # Don't overwrite if the key exists in the user trans and the key in the default trans is the same as the English one
  5089.                                         next if ($xmlin->{Language}->{$lang}->{$_} && ($def_xml->{Language}->{$lang}->{$_} eq $def_xml->{Language}->{English}->{$_}));
  5090.                                         $xmlin->{Language}->{$lang}->{$_} = $def_xml->{Language}->{$lang}->{$_};
  5091.                                 } else {
  5092.                                         next if $xmlin->{Language}->{$lang}->{$_};
  5093.                                         $xmlin->{Language}->{$lang}->{$_} = $def_xml->{Language}->{English}->{$_};
  5094.                                 }
  5095.                                 print "[$lang] updating key $_ ...\n" unless $silent;
  5096.                                 $trans_mod = 1;
  5097.                         }
  5098.                 } else {
  5099.                         # user language does not exist - use English
  5100.                         foreach (keys(%{$def_xml->{Language}->{English}})) {
  5101.                                 next if $xmlin->{Language}->{$lang}->{$_};
  5102.                                 $xmlin->{Language}->{$lang}->{$_} = $def_xml->{Language}->{English}->{$_};
  5103.                                 $trans_mod = 1;
  5104.                         }
  5105.                 }
  5106.         }
  5107.        
  5108.         foreach (keys(%{$def_xml->{Language}})) {
  5109.                 # Check that all translation languages are present, and add in those that don't from defaults ...
  5110.                 my $lang = $_;
  5111.                 unless ($xmlin->{Language}->{$lang}) {
  5112.                         $xmlin->{Language}->{$lang} = $def_xml->{Language}->{$lang};
  5113.                         $trans_mod = 1;
  5114.                 }                              
  5115.         }
  5116.        
  5117.        
  5118.         if ($trans_mod) {
  5119.                 $xmlin->{Version} = $version;
  5120.                 $translations = XMLout($xmlin, AttrIndent=>1);
  5121.                 print "Updating translations file ...\n";
  5122.                 open(LANG, ">$prefs_dir/lang.xml") || die("Could not open lang.xml file for writing: $!");
  5123.                 print LANG $translations;
  5124.                 close LANG;
  5125.                 print " ... done!\n";
  5126.         }
  5127.  
  5128.         set_language();
  5129. }
  5130.  
  5131. sub set_language {
  5132.         my $xmlin = XMLin($translations, ForceArray => 1);
  5133.        
  5134.         ## For debugging ...
  5135.         # use Data::Dumper;
  5136.         # print Dumper $xmlin;
  5137.        
  5138.         %trans = %{$xmlin->{Language}->{$language}};
  5139. }
clone this paste RAW Paste Data