#!/usr/bin/perl
# -*- coding: utf-8 -*-
#
# Copyright (C) 2003-2007 Mandriva
#
# Till Kamppeter <till at mandriva.com>
# Daouda Lo <daouda at mandriva.com>
# Marcelo Ricardo Leitner <mrl at mandriva.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

use utf8;


# i18n: IMPORTANT: to get correct namespace (printerdrake instead of 
# libDrakX)
BEGIN { unshift @::textdomains, 'printerdrake' }

use lib qw(/usr/lib/libDrakX);
use standalone;

use common;
use any;

use mygtk2 qw(gtknew); #- do not import gtkadd which conflicts with ugtk2 version
use ugtk2 qw(:all);
use run_program;
use interactive;
use POSIX qw(mktime ceil);
use printer::printerdrake;
use printer::main;
#Only for Debugging 
#use Devel::Peek;
use Gtk2::Gdk::Keysyms;
use modules;
use c;

my %sysh = distrib();
my $distroname = $sysh{system};

my $domainname = "mandriva.com";

add_icon_path(my $pixdir = '/usr/share/printerdrake/pixmaps/');

my $refreshinterval = 5;

my $printer;

$ugtk2::wm_icon = "printerdrake";
my $in = 'interactive'->vnew('su', if_(!$::isEmbedded, 'printer-mdk'));

my $commandline = join('', @ARGV);

# Suppress some wait messages to avoid windows popping up if no new print 
# queue has to be set up
$commandline =~ /-onlyautoqueue/ and $::autoqueue = 1;

my $mainw;
my $release = eval { mandrake_release_info() } || { "version" => "2007.1", "product" => "Mandriva"};
{
    local $::noborderWhenEmbedded = 1;
    $mainw = ugtk2->new(N("%s Printer Management Tool", $distroname) . " " . $release->{version} . " (" . $release->{product} . ")" );
    $::main_window = $mainw->{real_window};
}

# Check whether Foomatic is installed and install it if necessary
#printer::printerdrake::install_foomatic($in);

my $w = $::autoqueue ||
    $in->wait_message(N("Printerdrake"),
		      N("Reading data of installed printers..."));

# Get what was installed before
eval { $printer = printer::main::getinfo('') };

undef $w;

exit 0 unless printer::printerdrake::first_time_dialog($printer, $in, undef);

# Were we in expert mode last time?
$printer->{expert} = printer::main::get_usermode();

# Choose the spooler by command line options
$::expert and $printer->{expert} = 1;
$commandline =~ /-cups/ and
    $printer->{SPOOLER} = 'cups' and printer::main::read_configured_queues($printer);
$commandline =~ /-rcups/ and
    $printer->{SPOOLER} = 'rcups' and printer::main::read_configured_queues($printer);
$commandline =~ /-lpr/ and 
    $printer->{SPOOLER} = 'lpd'  and printer::main::read_configured_queues($printer);
$commandline =~ /-lpd/ and 
    $printer->{SPOOLER} = 'lpd'  and printer::main::read_configured_queues($printer);
$commandline =~ /-lprng/ and 
    $printer->{SPOOLER} = 'lprng' and printer::main::read_configured_queues($printer);
$commandline =~ /-pdq/ and 
    $printer->{SPOOLER} = 'pdq'  and printer::main::read_configured_queues($printer);

if ($::isInstall) {
    # Interactive main window for installation
    printer::printerdrake::main($printer, $::o->{security}, $in, 1, undef);
    exit();
}

require security::level;
my $security = security::level::get();

# Do not let printerdrake ask for the spooler
$printer->{SPOOLER} ||= 'cups';

# Initialization
printer::printerdrake::init($printer, $security, $in, undef);

# Stop here when we are supposed to only automatically set up print queues
$commandline =~ /-onlyautoqueue/ and exit 0;


my $stringsearch = '';

sub HelpSystem() { run_program::raw({ detach => 1 }, 'drakhelp', '--id', 'printerdrake') }

$::noborderWhenEmbedded = 1;
gtkset_size_request($mainw->{rwindow}, 660, 460);

if (!$::isEmbedded) {
    $mainw->{rwindow}->set_position('center');
}
$mainw->{window}->signal_connect(delete_event => \&QuitGlobal);
$mainw->{window}->signal_connect(destroy => \&QuitGlobal);
my $ltree_model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String");
my $rtree_model = Gtk2::ListStore->new("Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String", "Glib::String");
my ($localtree, $remotetree);
$localtree = CreateTree($ltree_model);
$remotetree = CreateTree($rtree_model);
# slightly verbatimed from control-center
my %options = (
	       'add' => [ N("/_Actions"), N("/_Add Printer") ],
	       'default' => [ N("/_Actions"), N("/Set as _Default") ],
	       'edit' => [ N("/_Actions"), N("/_Edit") ],
	       'delete' => [ N("/_Actions"), N("/_Delete") ],
	       'expert' => [ N("/_Options"), N("/_Expert mode") ]
	      );
my %buttorcheck;
my ($menu, $factory) = create_factory_menu($::isEmbedded ? $::Plug : $mainw->{rwindow},
                                           ([ N("/_File"), undef, undef, undef, '<Branch>' ],
                                            [ N("/_File") . N("/_Refresh"), undef, sub { Refresh($stringsearch, 1) }, undef, '<StockItem>', 'gtk-refresh' ],
                                            [ N("/_File") . N("/_Quit"), N("<control>Q"), \&QuitGlobal, undef, '<StockItem>', 'gtk-quit' ],
                                            [ N("/_Actions"), undef, undef, undef, '<Branch>' ],
                                            [ N("/_Actions") . N("/_Add Printer"), undef, \&AddPrinter, undef, '<StockItem>', 'gtk-add' ],
                                            [ join('', @{$options{default}}), undef, \&SetAsDefault, undef, '<StockItem>', 'gtk-default' ],
                                            [ join('', @{$options{edit}}), undef, \&Edit, undef, '<StockItem>', 'gtk-properties' ],
                                            [ join('', @{$options{delete}}), undef, \&Delete, undef, '<StockItem>', 'gtk-delete' ],
                                            [ N("/_Actions") . N("/_Configure CUPS"), undef, \&ConfigCUPS, undef, '<StockItem>', 'gtk-config' ],
                                            [ N("/_Options"), undef, undef, undef, '<Branch>' ],
                                            [ join('', @{$options{expert}}), undef, sub {
                                                  $printer->{expert} = $buttorcheck{expert}->get_active;
						  # Remember state of expert
						  # mode for next
						  # printerdrake session
						  printer::main::set_usermode($printer->{expert});
						  # Read printer database
						  # for the new user mode
						  %printer::main::thedb = 
						      ();
                                              }, undef, '<CheckItem>' ],
                                            [ N("/_Options") . N("/Configure _Auto Administration"), undef, \&ConfigAutoAdmin, undef, '<StockItem>', 'gtk-autoadmin' ],
                                            [ N("/_Help"), undef, undef, undef, '<Branch>' ],
					    if_(-x "/usr/sbin/drakhelp_inst",
						[ N("/_Help") . N("/_Help"), undef, sub { HelpSystem() }, undef, '<StockItem>', 'gtk-help' ],
					       ),
					    if_(!-e "/etc/sysconfig/oem",
						[ N("/_Help") . N("/_Report Bug"), undef, sub { system("/usr/bin/xdg-open https://qa.$domainname &") }, undef, '<StockItem>', 'gtk-stop' ],
					       ),
                                            [ N("/_Help") . N("/_About..."), undef, \&About, undef, '<StockItem>', 'gtk-preferences' ]
					   )
					  );
%buttorcheck = map {  $_ => $factory->get_widget("<main>" . join '', map { s/_//; $_ } @{$options{$_}}) } ('add', 'default', 'edit', 'delete', 'expert');

if (defined $buttorcheck{expert}) {
    $buttorcheck{expert}->set_active($printer->{expert});
} else {
    print STDERR "BUG with LANGUAGE $ENV{LANGUAGE}\n";
}

my $toolb = Gtk2::Toolbar->new;
my $filter;
my $searchBox = gtkpack_(Gtk2::HBox->new(0,5),
                         1, Gtk2::Label->new(""),
                         0, Gtk2::Label->new(N("Search:")),
                         0, gtksignal_connect($filter = Gtk2::Entry->new,
				       key_press_event => sub { $_[1]->keyval == $Gtk2::Gdk::Keysyms{Return} and do { $stringsearch = $filter->get_text; Refresh($stringsearch) } }),
                         0, my $fbut = Gtk2::Button->new(N("Apply filter")),
                        );
gtkappend_page(my $nb = Gtk2::Notebook->new, gtkpack(create_scrolled_window($localtree)), gtkshow(Gtk2::Label->new(N("Configured on this machine"))));
gtkappend_page($nb, gtkpack(create_scrolled_window($remotetree)), gtkshow(Gtk2::Label->new(N("Configured on other machines"))));
$nb->set_show_border(0);

my @extra_widgets;
if ($::isEmbedded) {
	push @extra_widgets, 0, Gtk2::Banner->new("/usr/share/mcc/themes/default/printer-mcc-mdk.png",
		N("Printers"));
}	 

$mainw->{window}->add(gtkpack_(Gtk2::VBox->new(0, 0),
				  0, $menu,
				  @extra_widgets,
				  0, $toolb,
				  0, $searchBox,
				  0, Gtk2::HSeparator->new,
				  1, $nb));
my @lcolsize = (1, 1, 1, 1, 1, 1, 1, -1);
my @rcolsize = (1, 1, 1, 1, 1, 1, -1);
each_index {
    my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i);
    $col->set_sort_column_id($::i);
    $col->set_min_width($lcolsize[$::i]);
    $localtree->append_column($col);
} (N("Def."), N("Printer Name"), N("State"), N("Model"), N("Connection Type"), N("Description"), N("Location"));

each_index {
    my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i);
    $col->set_sort_column_id($::i);
    $col->set_min_width($rcolsize[$::i]);
    $remotetree->append_column($col);
} (N("Def."), N("Printer Name"), N("State"), N("Server Name"), N("Description"), N("Location"));
my @toolbwg = map {
    $toolb->append_item($_->[0], $_->[1], $_->[2],  
                        gtkcreate_img($_->[2]), $_->[3], $toolb);
#    $toolb->append_space;
} ([
     # FIXME: then "add printer" should be a simple verb as suggested in Human Guidelines!!!
     #-PO: "Add Printer" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Add Printer"), N("Add a new printer to the system"), 'printer_add', \&AddPrinter ], 
    [
     #-PO: "Set as default" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Set as default"), N("Set selected printer as the default printer"), 'printer_default', \&SetAsDefault ],
    [ 
     #-PO: "Edit" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Edit"), N("Edit selected printer"), 'printer_conf', \&Edit ],
    [ 
     #-PO: "Delete" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Delete"), N("Delete selected printer"), 'printer_del', \&Delete ],
    [ 
     #-PO: "Refresh" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Refresh"), N("Refresh the list"), 'refresh', sub { Refresh($stringsearch, 1) } ],
    [
     #-PO: "Configure CUPS" is a button text and the translation has to be AS SHORT AS POSSIBLE
     N("Configure CUPS"), N("Configure CUPS printing system"), 'cups_config', \&ConfigCUPS ]
  );
my ($tbadd, $tbdefault, $tbedit, $tbdel, $_tbref, $_tbconfig) = @toolbwg;
GrayDelEdit();
foreach ($tbadd, $buttorcheck{add}) { defined $_ and $_->set_sensitive($printer->{SPOOLER} ne "rcups") }
$localtree->parent->parent->set_sensitive($printer->{SPOOLER} ne "rcups");
$nb->set_current_page(1) if $printer->{SPOOLER} eq "rcups";

$fbut->signal_connect('clicked', sub { $stringsearch = $filter->get_text; Refresh($stringsearch) });
Refresh($stringsearch);
$nb->signal_connect('switch-page' => sub { NotebookSwitch() });
$mainw->{rwindow}->show_all;
set_selection($printer->{DEFAULT});
gtkset_mousecursor_normal();

# Prevent subwindows to embed themselves in the mcc which has already the
# main window embedded
my $isEmbedded = $::isEmbedded;
local $::isEmbedded = 0;

# Auto refresh
my $refreshing = 0;
my $timeout = Glib::Timeout->add($refreshinterval * 1000, 
		   sub { Refresh($stringsearch); 1 });

$mainw->main;
ugtk2->exit;

sub GrayDelEdit() {
    foreach ($tbdefault, $tbedit, $tbdel, $buttorcheck{default}, $buttorcheck{edit}, $buttorcheck{delete}) { defined $_ and $_->set_sensitive(0) }
}

sub TreeUnselect {
    my $treev = shift;
    $treev->get_selection->unselect_all;
    GrayDelEdit();
}
sub NotebookSwitch() { 
    TreeUnselect($localtree);
    TreeUnselect($remotetree);
    #set_selection_on_first();
}

sub RefreshLocalPrintersFull {
    my ($strfilt, @allprinters) = @_;
    my @printers;
    defined $printer and @printers = keys %{$printer->{configured}};
    $ltree_model->clear;
    return if $printer->{SPOOLER} eq "rcups";
    my @LocalReal;
    foreach my $p (@printers) {
	# Apply string search to all fields, not only the printer name
	my $state = ($printer->{SPOOLER} !~ /cups/ ? N("Unknown") :
		     ((any { 
			 $_->{queuename} eq $p &&
			     $_->{state} eq "enabled";  
		     } @allprinters) ? N("Enabled") : N("Disabled")));
	my $connect = printer::main::connectionstr($printer->{configured}{$p}{queuedata}{connect});
	my $model = $printer->{configured}{$p}{queuedata}{make} . ' ' .
	    $printer->{configured}{$p}{queuedata}{model};
	my $description = $printer->{configured}{$p}{queuedata}{desc};
	my $location = $printer->{configured}{$p}{queuedata}{loc};
	my $searchstr = "$p|$state|$model|$connect|$description|$location";
	push @LocalReal, $p if !$strfilt || $searchstr =~ /\Q$strfilt/i;
    }
    foreach my $p (sort { lc($a) cmp lc($b) } @LocalReal) {
	my $state = ($printer->{SPOOLER} !~ /cups/ ? N("Unknown") :
		     ((any { 
			 $_->{queuename} eq $p &&
			     $_->{state} eq "enabled";
		     } @allprinters) ? N("Enabled") : N("Disabled")));
	my $connect = printer::main::connectionstr($printer->{configured}{$p}{queuedata}{connect});
	my $description = $printer->{configured}{$p}{queuedata}{desc};
	my $location = $printer->{configured}{$p}{queuedata}{loc};
	my $model = $printer->{configured}{$p}{queuedata}{make} . ' ' .
	    $printer->{configured}{$p}{queuedata}{model};
	my $default = ($p eq $printer->{DEFAULT} ? "X" : "");
	$ltree_model->append_set([ 0 => $default, 1 => $p, 2 => $state, 
				   3 => $model, 
				   4 => $connect, 5 => $description,
				   6 => $location ]);
    }
}

sub RefreshRemotePrintersFull {
    my ($strfilt, @printers) = @_;
    $rtree_model->clear;
    my @RemoteReal;
    LOOP: foreach my $p (@printers) {
	# No locally defined queues
	next LOOP if defined($printer->{configured}{$p->{queuename}});
	# Apply string search to all fields, not only the printer name
	my $queue = $p->{queuename};
	my $state = ($p->{state} eq "enabled" ?
		     N("Enabled") : N("Disabled"));
	my $server = $p->{ipp} || $printer->{remote_cups_server};
	my $description = $p->{description};
	my $location = $p->{location};
	my $searchstr = "$queue|$state|$server|$description|$location";
	# All remaining to which the search term applies
	push @RemoteReal, $p if !$strfilt || $searchstr =~ /\Q$strfilt/i;
    }
    foreach my $p (sort { lc($a->{queuename}) cmp lc($b->{queuename}) } 
		   @RemoteReal) {
	my $queue = $p->{queuename};
	my $state = ($p->{state} eq "enabled" ?
		     N("Enabled") : N("Disabled"));
	my $server = $p->{ipp} || $printer->{remote_cups_server};
	my $description = $p->{description};
	my $location = $p->{location};
	my $default = ($queue eq $printer->{DEFAULT} ? "X" : "");
	$rtree_model->append_set([ 0 => $default, 1 => $queue, 
				   2 => $state, 3 => $server,
				   4 => $description,
				   5 => $location ]);
    }
}

sub Refresh {
    # Do not have ourselves recalled if we are already running
    return if $refreshing;
    $refreshing = 1;
    my ($strfilt, $rereadlocalqueues) = @_;
    my $selection = get_selection();
    if ($rereadlocalqueues) {
	my $w =
	    $in->wait_message(N("Printerdrake"),
			      N("Reading data of installed printers..."));
	delete($printer->{configured});
	delete($printer->{currentqueue});
	eval { printer::main::read_configured_queues($printer) };
    }
    printer::services::wait_for_cups() if $printer->{SPOOLER} eq "cups";
    my @printers;
    defined $printer and @printers = printer::cups::lpstat_lpv();
    RefreshLocalPrintersFull($strfilt, @printers); 
    RefreshRemotePrintersFull($strfilt, @printers);
    GrayDelEdit();
    set_selection($selection);
    $refreshing = 0;
}

sub AddPrinter() {
    deactivate_mainwindow();
    if (printer::printerdrake::add_printer($printer, $in, undef)) {
	Refresh($stringsearch);
	set_selection($printer->{QUEUE});
    } else {
	delete($printer->{QUEUE});
    }
    activate_mainwindow();
}

sub SetAsDefault() {
    deactivate_mainwindow();
    my $queue = get_selection();
    printer::printerdrake::default_printer($printer, $in, $queue);
    Refresh($stringsearch);
    activate_mainwindow();
}

sub Edit() {
    deactivate_mainwindow();
    my $queue = get_selection();
    printer::printerdrake::edit_printer($printer, $in, undef, $queue);
    Refresh($stringsearch);
    if ($printer->{QUEUE}) {
	set_selection($printer->{QUEUE});
#    } else {
#	set_selection_on_first();
    }
    activate_mainwindow();
}

sub Delete() {
    deactivate_mainwindow();
    my $queue = get_selection();
    if (printer::printerdrake::remove_printer($printer, $in, $queue)) {
	Refresh($stringsearch);
	set_selection_on_first();
    } else {
	delete($printer->{QUEUE});
    }
    activate_mainwindow();
}

sub ConfigCUPS() {
    deactivate_mainwindow();
    printer::printerdrake::config_cups($printer, $security, $in, undef);
    foreach ($tbadd, $buttorcheck{add}) { defined $_ and $_->set_sensitive($printer->{SPOOLER} ne "rcups") }
    $localtree->parent->parent->set_sensitive($printer->{SPOOLER} ne "rcups");
    $nb->set_current_page(1) if $printer->{SPOOLER} eq "rcups";
    Refresh($stringsearch);
    activate_mainwindow();
}

sub ConfigAutoAdmin() {
    deactivate_mainwindow();
    printer::printerdrake::config_auto_admin($printer, $in);
    Refresh($stringsearch);
    activate_mainwindow();
}

sub deactivate_mainwindow() {
    $mainw->{rwindow}->set_sensitive(0);
    gtkset_mousecursor_wait();
}

sub activate_mainwindow() {
    $mainw->{rwindow}->set_sensitive(1);
    gtkset_mousecursor_normal();
}

sub set_selection_on_first() {
    # On which page are we currently
    my $page = $nb->get_current_page;
    my ($tree, $model);
    if ($page <= 0) {
	# Locally defined printer: first page
	$tree = $localtree;
	$model = $ltree_model;
    } elsif ($page == 1) {
	# Remotely defined printer: second page
	$tree = $remotetree;
	$model = $rtree_model;
    }
    my $iter = $model->get_iter_first;
    $tree->get_selection->select_iter($iter) if $iter;
}

sub set_selection {
    my ($queue) = @_;
    return if !$queue;
    my ($tree, $model, $page);
    if (defined($printer->{configured}{$queue})) {
	# Locally defined printer: first page
	$tree = $localtree;
	$model = $ltree_model;
	$page = 0;
    } else {
	# Remotely defined printer: second page
	$tree = $remotetree;
	$model = $rtree_model;
	$page = 1;
    }
    # Search entry on page
    my $iter = $model->get_iter_first;
    while ($iter) {
	my $q = $model->get($iter, 1);
	if ($q eq $queue) {
	    $tree->get_selection->select_iter($iter);
	    $nb->set_current_page($page);
	    return;
	}
	$iter = $model->iter_next($iter);
    }
    # Requested entry does not exist, go to the first entry on the current
    # page.
    set_selection_on_first();
}

sub get_selection() {
    my $queue;
    my $page = $nb->get_current_page;
    if ($page <= 0) {
	$queue = GetNameEntFromIter($localtree, $ltree_model, 1);
    } elsif ($page == 1) {
	$queue = GetNameEntFromIter($remotetree, $rtree_model, 1);
    }
    return $queue;
}

sub GetNameEntFromIter {
    my ($tree, $model, $rank) = @_;
    my $sel = $tree->get_selection;
    return if !$sel;
    my (undef, $iter) = $sel->get_selected;
    return undef if !defined($iter);
    my $name = $model->get($iter, $rank);
    $name;
}

sub select_a_printer {
    my ($tree, $tree_model, undef, $_event) = @_;
    my (undef, $iter) = $tree->get_selection->get_selected;
    return unless $iter;
    foreach ($tbdefault, $tbedit, $tbdel, @buttorcheck{qw(default delete edit)}) { $_->set_sensitive(1) }
    my $queue = $tree_model->get($iter, 1);
    foreach (if_(!defined($printer->{configured}{$queue}), $tbdel, $buttorcheck{delete}),
             if_($queue eq $printer->{DEFAULT}, $tbdefault, $buttorcheck{default})
         ) {
        $_->set_sensitive(0);
    }
}

sub CreateTree {
    my ($tree_model) = @_;
    my $tree = Gtk2::TreeView->new_with_model($tree_model);
    $tree->get_selection->set_mode('browse');
    $tree->set_headers_visible(1);
    $tree->set_rules_hint(1);
    $tree->get_selection->signal_connect('changed' => sub { select_a_printer($tree, $tree_model, @_) });
    $tree->signal_connect(button_press_event => sub { select_a_printer($tree, $tree_model, @_) });
    $tree->signal_connect(key_press_event => sub {
			       my (undef, $event) = @_;
			       my (undef, $iter) = $tree->get_selection->get_selected;
			       return unless $iter;
			       Edit() if $event->keyval == $Gtk2::Gdk::Keysyms{Return};
			   });
    $tree;
}

sub NewDialog {
    my ($title, $o_no_button) = @_;
    my $dialog = gtkset_border_width(Gtk2::Dialog->new, 10);
    $dialog->set_transient_for($mainw->{real_window});
    $dialog->set_position('center-on-parent');
    $dialog->set_title($title);
    $dialog->action_area->pack_start(gtkadd(Gtk2::HButtonBox->new,
                                            gtksignal_connect(Gtk2::Button->new(N("Close")), clicked => sub { $dialog->destroy })
                                            ),
                                     0,0,0) unless $o_no_button;
    gtkset_modal($dialog, 1);
}

sub About() {
         my $license = formatAlaTeX(translate($::license));
         $license =~ s/\n/\n\n/sg; # nicer formatting
         my $w = gtknew('AboutDialog', name => N("Printerdrake"),
                        version => $release->{version}, icon => '/usr/share/icons/printer-mdk.png',
                        if_(-r "$pixdir/about-printerdrake.png", logo => "$pixdir/about-printerdrake.png"),
                        copyright => N("Copyright (C) %s by Mandriva", '2001-2007'),
                        license => $license, wrap_license => 1,
                        comments => N("Printer Management %s", $release->{version} . " (" . $release->{product} . ")"),
                        website => 'http://mandrivalinux.com',
                        website_label => N("Mandriva Linux"),
                        authors => "Till Kamppeter <till\@$domainname>",
                        artists => 'Hélène Durosini <ln@mandriva.com>',
                        translator_credits =>
                          #-PO: put here name(s) and email(s) of translator(s) (eg: "John Smith <jsmith@nowhere.com>")
                          N("_: Translator(s) name(s) & email(s)\n"),
                        transient_for => $mainw->{real_window}, modal => 1, position_policy => 'center-on-parent',
                    );
         $w->show_all;
         $w->run;
}

sub QuitGlobal() {
    Glib::Source->remove ($timeout);
    gtkset_mousecursor_normal();
    Gtk2->main_quit;
}
