#!/usr/bin/perl -w # Control-center # Copyright (C) 1999 MandrakeSoft # Damien Krotkine (damien@mandrakesoft.com) # Daouda Lo (daouda@mandrakesoft.com) # # 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, or (at your option) # any later version. # # 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 Config; use Env; use POSIX; # for i18n use Locale::GetText; setlocale (LC_ALL, ""); Locale::GetText::textdomain ("DrakConf"); import Locale::GetText I_; #*_ = *I_; my $_xbindir = "/usr/X11R6/bin"; my $_bindir = "/usr/bin"; my $_sbindir = "/usr/sbin"; my $_iconsdir = "/usr/share/icons"; my $_docdir = "/usr/share/doc"; sub _ { my $s = shift @_; my $t = I_($s); $t && ref $t or return sprintf $t, @_; my ($T, @p) = @$t; sprintf $T, @_[@p]; } !$ENV{DISPLAY} and exec ("$_sbindir/drakxconf; reset"); require Gtk; require Gtk::Gdk::ImlibImage; init Gtk; Gtk::Gdk::ImlibImage->init; use Data::Dumper; my %pixmaps_global; my $xpm_path="$_iconsdir"; my $xpm_path_l="$_iconsdir"; my $tree_depth_max = 1; my @treeitem_sub; my $nb_pages=0; my $window_global = new Gtk::Window -toplevel; $window_global->signal_connect ( delete_event => sub { quit_global(); }); $window_global->set_position(1); $window_global->set_title(_("Mandrake Control Center")); $window_global->border_width(0); my $vbox_global = new Gtk::VBox(0, 0); $window_global->add($vbox_global); ######### menus my @item_factory_entries = ( [_("/_File"), undef, 0, ""], { 'path' => _("/File/_Quit"), 'accelerator' => _("Q"), 'action' => 1, 'type' => '' }, [_("/_Help"), undef, 0, ""], [_("/Help/_Mandrake Control Center"), undef, 2], [_("/Help/_Report Bug"), undef, 3 ], [_("/Help/_About..."), undef, 4 ], # [_("/_Extras"), undef, 0, ""], # [_("/_Extras/Mandrake Security _News"), undef, 5], # [_("/_Extras/Mandrake _Campus"), undef, 6], # [_("/_Extras/Mandrake _Expert"), undef, 7], ); my $accel_group = new Gtk::AccelGroup; my $item_factory = new Gtk::ItemFactory('Gtk::MenuBar', "
", $accel_group); $accel_group->attach($window_global); $item_factory->create_item($_, \&item_factory_cb) foreach (@item_factory_entries); $vbox_global->pack_start($item_factory->get_widget('
'), 0, 0, 0); $vbox_global->pack_start(new Gtk::HSeparator, 0, 1, 0); my $hpane_global = new Gtk::HPaned; $vbox_global->pack_start($hpane_global, 1, 1, 0); $hpane_global->border_width(5); my $scrolled_global = new Gtk::ScrolledWindow; $scrolled_global->set_policy('automatic','automatic'); $scrolled_global->set_usize(195, 0); $scrolled_global->set_name("icons_back"); $hpane_global->pack1($scrolled_global,0,1); my $notebook_global = new Gtk::Notebook; $notebook_global->set_show_border(0); $notebook_global->set_show_tabs(0); $hpane_global->pack2($notebook_global,0,1); #-------------------------------- splash screeen -------------------------------------------------------- my ($pix_splash_map, $pix_splash_mask) = gtkcreate_png("$xpm_path_l/splash.png"); my @anim; ($anim[$_]->[0], $anim[$_]->[1]) = gtkcreate_png("$xpm_path_l/anim_" . ($_ + 1) . ".png") foreach (0..7); my $vbox_about = new Gtk::VBox(0,0); my $darea1= new Gtk::DrawingArea(); $darea1->size(540,460); $darea1->set_usize(540,460); $vbox_about->pack_start($darea1,1,1,0); $notebook_global->append_page($vbox_about, undef); my $vbox_global_left = new Gtk::VBox(0,0); $scrolled_global->add_with_viewport($vbox_global_left); $window_global->realize; my $tree= new Gtk::Tree; $tree->set_selection_mode('browse'); $vbox_global_left->pack_start($tree,1,1,0); map { create_tree_item($tree, $_->[0] , "$xpm_path_l/$_->[1]",1); } ([_("Boot"), 'drakboot-mdk.png'] , [_("Hardware"), 'logo.png'] , [_("User and Groups"),'adduserdrake-mdk.png'], [_("Network & Internet"),'draknet-mdk.png'] , [_("System"),'menudrake-mdk.png'] , [_("Font Management"),'drakfont-mdk.png']); map { create_tree_item($treeitem_sub[int($_->[2])],$_->[0], "$xpm_path_l/$_->[1]",0); } ([_("Boot Config"),'drakboot-mdk.png',5] , [_("Boot Disk"), 'drakboot-mdk.png',5] , [_("Boot Logo"), 'drakboot-mdk.png',5], [_("Display"),'item.png',4] , [_("Hardware"),'item.png',4] , [_("Mouse"), 'item.png',4] , [_("Printer"),'printer-mdk.png',4] , [_("Keyboard"), 'keyboard-mdk.png',4], [_("Users Config"),'item.png',3] , [_("Internet & Network") , 'draknet-mdk.png',2] , [_("Gateway Config"),'drakgw-mdk.png',2], [_("Date & Time") , 'item.png',1], [_("System Menus") , 'item.png',1], [_("User Menus") , 'item.png',1] , [_("Fonts"), 'drakfont-mdk.png',0] ); my %tree_exec = (_("Boot Config") => "$_sbindir/drakboot", _("Boot Disk") => "$_xbindir/drakfloppy", _("Boot Logo") => "$_xbindir/DrakeLogo" , _("Display") => "$_sbindir/XFdrake" , _("Hardware") => "$_bindir/harddrake-auth" , _("Mouse") => "$_sbindir/mousedrake" , _("Printer") => "$_sbindir/printerdrake" , _("Keyboard") => "$_sbindir/keyboarddrake" , _("Users Config") => "$_bindir/userdrake" , _("Internet & Network") => "$_sbindir/draknet" , _("Gateway Config") => "$_sbindir/drakgw" , _("Date & Time") => "$_sbindir/clock.pm", _("User Menus") => "$_bindir/menudrake" , _("System Menus") => "$_bindir/menudrake", _("Fonts") => "$_xbindir/drakfont" ); my @pid_launched; my %tree_launched; $window_global->show_all; $SIG{USR1} = sub { ${$tree_launched{$_}->[1]}->deselect() foreach (keys %tree_launched); $notebook_global->set_page(0); }; # embedded applications will send me that signal in order to "hide" them $SIG{TERM} = sub { quit_global(); }; # embedded applications will send me that signal in order to quit the cc. my $global_vbox; my $global_time_tag; my $lock_time_tag; my $global_socket; $SIG{USR2} = sub { Gtk->timeout_remove($lock_time_tag); $$global_vbox->hide; Gtk->timeout_remove($global_time_tag); $$global_socket->show; ${$tree_launched{$_}->[1]} and ${$tree_launched{$_}->[1]}->set_sensitive(1) foreach (keys %tree_launched); }; my $pix_dbl = new Gtk::Gdk::Pixmap($darea1->window, 540,460); draw_exposed($pix_dbl); $darea1->signal_connect( expose_event => sub { $darea1->window->draw_pixmap ($darea1->style->white_gc, $pix_dbl, 0, 0, ($darea1->allocation->[2]-540)/2, ($darea1->allocation->[3]-460)/2, 540, 460); }); Gtk->main; sub draw_exposed { my ( $pix )=@_; $pix->draw_pixmap($darea1->style->white_gc, $pix_splash_map, 0, 0, 0, 0, 540, 460); my $style = new Gtk::Style; my $style_dflt = new Gtk::Style; $style->font(Gtk::Gdk::Font->fontset_load(_("-adobe-times-bold-r-normal--17-*-100-100-p-*-iso8859-*,*-r-*"))); $pix->draw_string($style->font, $darea1->style->black_gc, 73, 170, ("The place where you can configure your Mandrake Box") ); my @revtree; open VERS, "/etc/redhat-release" or die( sprintf _("cannot open this file for read: $!")); while () { push (@revtree,$_) } my @info_tree = split / /, $revtree[0]; my ($sysname, $nodename, $release, $version, $machine ) = POSIX::uname(); my $username= POSIX::cuserid(); my $style1 = new Gtk::Style; $style1->font(Gtk::Gdk::Font->fontset_load(_("-adobe-times-bold-r-normal--14-*-100-100-p-*-iso8859-*,*-r-*"))); my $i=0; foreach( [_("User:"), $username], [_("System:"), "$info_tree[0] $info_tree[1] $info_tree[3] $info_tree[4]"], [_("Hostname:"), $nodename], [_("Kernel Version:"), "$release $version"], [_("Machine:"), $machine] ) { $pix->draw_string($style1->font, $darea1->style->black_gc, 80, 250+$i, $_->[0]); $pix->draw_string($style_dflt->font, $darea1->style->black_gc, 200, 250+$i, $_->[1]); $i+=20; } } sub gtkcreate_png { my ($f) = @_; my $im = Gtk::Gdk::ImlibImage->load_image($f) or die "gtkcreate_png: missing png file $f"; $im->render($im->rgb_width, $im->rgb_height); ($im->move_image(), $im->move_mask); } sub quit_global { kill TERM, @pid_launched; Gtk->exit(0); } sub about_mdk_cc { my $window_about = new Gtk::Dialog(); $window_about->set_position(1); my $bbox1 = new Gtk::HButtonBox; $window_about->action_area->pack_start($bbox1,0,0,0); my $button = new Gtk::Button(_("Close")); $button->signal_connect_object("clicked",$window_about => 'destroy'); $bbox1->add($button); my $label = new Gtk::Label( _("Mandrake Control Center 0.61 \n Copyright (C) 2001 Mandrakesoft SA\n") ); my $style1 = new Gtk::Style; $style1->font(Gtk::Gdk::Font->fontset_load(_("-adobe-times-bold-r-normal--14-*-100-100-p-*-iso8859-*,*-r-*"))); $label->set_style($style1); $window_about->vbox->pack_start( $label, 1, 1, 0 ); $window_about->vbox->pack_start( new Gtk::Label( _("Authors: ") . "\n\n Daouda Lo \n \n Damien Krotkine \n"), 1, 1, 0 ); $window_about->show_all(); $window_about->set_modal(1); } sub splash_warning { my ($label) = @_; my $win_about = new Gtk::Dialog(); $win_about->set_position(1); my $bbox1 = new Gtk::HButtonBox; $win_about->action_area->pack_start($bbox1,0,0,0); my $button = new Gtk::Button(_("Close")); $button->signal_connect_object("clicked",$win_about => 'destroy'); $bbox1->add($button); my $lab = new Gtk::Label($label); my $style1 = new Gtk::Style; $win_about->vbox->pack_start( $lab, 1, 1, 0 ); $win_about->show_all(); $win_about->set_modal(1); } sub connect_to_site { my ($link,$help)=@_; if($help) { my $browser=$ENV{'BROWSER'}; system("$browser -geometry 600x800+10+10 $link&"); } else { splash_warning(_("\nIf you want to report bug please connect as normal user to \n \nhttps://qa.mandrakesoft.com and fill a bug report\n\n")); } } # my $left = sub { &$next_child($_[0]->parent, 0); }; # my $right = sub { # print "RRRRRRRRRR\n"; # my ($c) = @_; # if ($c->subtree) { # $c->expand; # ($c->subtree->children)[0]; # } else { # $c; # } # }; # my $down = sub { # my ($c) = @_; # return &$right($c) if ref $c eq "Gtk::TreeItem" && $c->subtree && $c->expanded; # if (my $n = &$next_child($c, 1)) { # $n; # } else { # return if ref $c->parent ne 'Gtk::Tree'; # &$down($c->parent); # } # }; # my $up = sub { # my ($c) = @_; # if (my $n = &$next_child($c, -1)) { # $n = ($n->subtree->children)[-1] while ref $n eq "Gtk::TreeItem" && $n->subtree && $n->expanded; # $n; # } else { # return if ref $c->parent ne 'Gtk::Tree'; # &$left($c); # } # }; my $treeitem_old; sub create_tree_item { my ($parent_tree, $label, $pixmap, $tree_depth_max) =@_; my ($treeitem, $treebox, $new_subtree); $treeitem = new Gtk::TreeItem(); $treebox = xpm_label_box($window_global,$pixmap,$label); $treeitem->add($treebox); $treebox->show(); if ($tree_depth_max == 0) { $tree_launched{$label}->[1]=\$treeitem; $treeitem->signal_connect('select', sub { exec_treeitem($label, $tree_exec{$label}, -e $tree_exec{$label} ) }); } else { $treeitem->signal_connect('select', sub { $treeitem_old and $$treeitem_old->collapse(); $treeitem->expand(); $treeitem_old=\$treeitem; #$treeitem->deselect(); }); } $parent_tree->append($treeitem); $treeitem->show(); if ($tree_depth_max) { $tree_depth_max-- ; $new_subtree= new Gtk::Tree(); $treeitem->set_subtree($new_subtree); $new_subtree->ref(); unshift(@treeitem_sub, $new_subtree); } # $treeitem->signal_connect(key_press_event => sub { # my (undef, $e) = @_; # local $_ = chr ($e->{keyval}); # if ($e->{keyval} > 0x100) { # my $n; # $n = &$left($treeitem) if /[Q´\x96]/; # print "RRRRRRRR\n"; # $n = &$right($treeitem) if /[S¶\x98]/; # print "RRRRRRRR\n"; # $n = &$up($treeitem) if /[R¸\x97]/; # $n = &$down($treeitem) if /[T²\x99]/; # if ($n) { # $n->focus('up'); # $treeitem->signal_emit_stop("key_press_event"); # } # $treeitem->expand if /[+«]/; # $treeitem->collapse if /[-\xad]/; # do { # $treeitem->expanded ? $treeitem->collapse : $treeitem->expand; # $treeitem->signal_emit_stop("key_press_event"); # } if /[\r\x8d]/; # } # 1; # }); } sub xpm_label_box { my ( $parent, $xpm_filename, $label_text ) = @_; # Create box for xpm and label my $box = new Gtk::HBox( 0, 0 ); # Get the style of the button to get the background color. my $style = $parent->get_style()->bg( 'normal' ); # Now on to the xpm stuff my ($pixmap, $mask) = gtkcreate_png($xpm_filename ); my $pixmapwid = new Gtk::Pixmap( $pixmap, $mask ); # Create a label for the button my $label = new Gtk::Label( $label_text ); # Pack the pixmap and label into the box $box->pack_start( $pixmapwid, 0, 0, 3 ); $box->pack_start( $label, 0, 0, 3 ); $box->border_width( 2 ); $pixmapwid->show(); $label->show(); return ( $box ); } sub exec_treeitem { my ($label, $exec_string, $available) = @_; if (!$available) { my $vbox = new Gtk::VBox(0, 0); $vbox->pack_start( new Gtk::Label (_(" The application cannot be loaded, the file '%s' has not be found. Try to reinstall DrakConf.", $exec_string)), 1, 0, 0); $vbox->show_all; $notebook_global->append_page($vbox, ""); $pid_launched[$nb_pages] = undef; $nb_pages++; $tree_launched{$label}->[0]=$nb_pages; $notebook_global->set_page($nb_pages); return; } if (!$tree_launched{$label}->[0]) { my $vbox = new Gtk::VBox(0, 0); $vbox->show; my $vbox2 = new Gtk::VBox(0, 0); $vbox2->show; $global_vbox=\$vbox2; $vbox->pack_start($vbox2,0,0,0); my $label_ = new Gtk::Label (_("Please be patient")); $vbox2->pack_start( $label_, 0, 0, 0); $label_->show; my $hbox = new Gtk::HBox(0, 0); $hbox->show; $vbox2->pack_start($hbox,0,0,0); my $darea1= new Gtk::DrawingArea(); $darea1->size(70,70); $darea1->set_usize(70,70); $hbox->pack_start($darea1,1,0,0); $darea1->show; my $socket = new Gtk::Socket; $global_socket = \$socket; $vbox->pack_start($socket, 1, 1, 0); $notebook_global->append_page($vbox, ""); $nb_pages++; $tree_launched{$label}->[0]=$nb_pages; $notebook_global->set_page($nb_pages); $tree_launched{$_}->[0] or ${$tree_launched{$_}->[1]} and ${$tree_launched{$_}->[1]}->set_sensitive(0) foreach (keys %tree_launched); my $anim_nb=0; $global_time_tag = Gtk->timeout_add(120, sub { $darea1->window->draw_pixmap ($darea1->style->white_gc, $anim[$anim_nb]->[0], 0, 0, ($darea1->allocation->[2]-70)/2, ($darea1->allocation->[3]-70)/2, 70, 70); $anim_nb++; $anim_nb > 7 and $anim_nb=0; 1; }); $lock_time_tag = Gtk->timeout_add(20000, sub { Gtk->timeout_remove($global_time_tag); ${$tree_launched{$_}->[1]} and ${$tree_launched{$_}->[1]}->set_sensitive(1) foreach (keys %tree_launched); $vbox->pack_start(new Gtk::Label (_("After 20 sec., this application didn't appear.\nIt's probably buggy")), 1, 1, 0); $label_->set(_("After 20 sec., this application didn't appear.\nIt's probably buggy")); $darea1->hide; }); $socket->realize; # $label->destroy; my $a = $exec_string . " --embedded " . $socket->window->XWINDOW . " " . $$; my $pid; #($pid = fork) ? $pid_launched[$nb_pages] = $pid : system($a) == 0 or splash_warning(_("couldn't exec $a: $!")); unless ($pid = fork) { splash_warning(_("cannot fork: $~")) unless defined $pid; exec("$a"); } $pid_launched[$nb_pages] = $pid; } else { $notebook_global->set_page($tree_launched{$label}->[0]); } } sub item_factory_cb { my ($widget, $action, @data) = @_; print "ItemFactory: activated ", $widget->item_factory_path(), " -> ", $action, "\n"; $action == 1 and quit_global(); $action == 4 and about_mdk_cc(); $action == 2 and connect_to_site("$_docdir/DrakConf/DrakeConf.html",1); $action == 3 and connect_to_site("https://qa.mandrakesoft.com",0); } sub create_item_factory { if (!defined $item_factory_window) { my ($accel_group, $item_factory, $box1, $label, $box2); my ($separator, $button, $dummy); $item_factory_window = new Gtk::Window('toplevel'); signal_connect $item_factory_window destroy => \&destroy_window, \$item_factory_window; signal_connect $item_factory_window "delete-event" => \&destroy_window, \$item_factory_window; $accel_group = new Gtk::AccelGroup; $item_factory = new Gtk::ItemFactory('Gtk::MenuBar', "
", $accel_group); #$item_factory_window->set_data('
', $item_factory); $accel_group->attach($item_factory_window); # $item_factory->create_items(); foreach (@item_factory_entries) { $item_factory->create_item($_, \&item_factory_cb); } $item_factory_window->set_title(_("Item Factory")); $item_factory_window->set_border_width(0); $box1 = new Gtk::VBox(0, 0); $item_factory_window->add($box1); $box1->pack_start($item_factory->get_widget('
'), 0, 0, 0); $label = new Gtk::Label( _("Type\n\nto start") ); $label->set_usize(200, 200); $label->set_alignment(0.5, 0.5); $box1->pack_start($label, 1, 1, 0); $separator = new Gtk::HSeparator; $box1->pack_start($separator, 0, 1, 0); $box2 = new Gtk::VBox(0, 10); $box2->set_border_width(10); $box1->pack_start($box2, 0, 1, 0); $button = new Gtk::Button(_("Close")); $button->signal_connect('clicked', sub {$item_factory_window->destroy;}); $box2->pack_start($button, 1, 1, 0); $button->can_default(1); $button->grab_default; } (!visible $item_factory_window) ? show_all $item_factory_window : destroy $item_factory_window; }