#!/usr/bin/perl -w ################################################################################ # # # # # Copyright (C) 2003 MandrakeSoft # # # Daouda Lo # # # # 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 strict; use lib qw(/usr/lib/libDrakX); use standalone; use common; use any; use ugtk2 qw(:all); use interactive; use USER; my $conffile = '/etc/sysconfig/userdrake'; my $secfile = '/etc/sysconfig/msec'; my $pixdir = '/usr/share/userdrake/pixmaps/'; my $in = interactive->vnew('su', 'default'); my $us = {} ; $us->{VERSION} = 0.91; my $error = 0; my $GetValue = -65533; my %prefs = getVarsFromSh($conffile); my $sysfilter = text2bool($prefs{FILTER}); sub HelpSystem { system("drakhelp Drakxtools-Guide.html/userdrake.html &") }; $us->{wnd} = ugtk2->new(N("Mandrake Linux Users Management Tool") . " " . $us->{VERSION}, center => 1); gtkset_size_request($us->{wnd}{window}, 660, 460); $us->{wnd}{rwindow}->signal_connect(delete_event => \&quit_global); my $utree_model = Gtk2::ListStore->new(Gtk2::GType->STRING, Gtk2::GType->INT, Gtk2::GType->STRING, Gtk2::GType->STRING, Gtk2::GType->STRING, Gtk2::GType->STRING ); my $gtree_model = Gtk2::ListStore->new(Gtk2::GType->STRING, Gtk2::GType->INT, Gtk2::GType->STRING ); my ($usertree, $grouptree); $usertree = CreateTree($utree_model); $grouptree = CreateTree($gtree_model); my ($checkedit, $checkdel, $checkall); my ($menu, $factory) = create_factory_menu($us->{wnd}{rwindow}, ({ path => N("/_File"), type => '' }, { path => N("/_File") . N("/_Refresh"), callback => sub { Refresh($sysfilter)} }, { path => N("/_File") . N("/_Quit"), callback => \&quit_global }, { path => N("/_Actions"), type => '' }, { path => N("/_Actions") . N("/_Add User"), callback => \&AddUser }, { path => N("/_Actions") . N("/Add _Group"), callback => \&AddGroup }, { path => N("/_Actions") . N("/_Edit"), callback => \&Edit }, { path => N("/_Actions") . N("/_Delete"), callback => \&Delete }, { path => N("/_Options"), type => '' }, { path => N("/_Options") . N("/_Filter system users"), type => '', callback => sub { $sysfilter = $checkall->active; Refresh($sysfilter) } }, { path => N("/_Help"), type => '' }, { path => N("/_Help").N("/_Help"), callback => \&HelpSystem }, { path => N("/_Help").N("/_Report Bug"), callback => sub { system("drakhelp https://qa.mandrakesoft.com &") } }, { path => N("/_Help").N("/_About..."), callback => \&about_mdk_userdrake } ) ); $checkall = $factory->get_widget("
" . N("/Options") . N("/Filter system users")); $checkedit = $factory->get_widget("
" . N("/Actions") . N("/Edit")); $checkdel = $factory->get_widget("
" . N("/Actions") . N("/Delete")); $checkall->set_active($sysfilter); my $toolb = Gtk2::Toolbar->new; my $searchBox = Gtk2::HBox->new(0,5); $searchBox->pack_end(my $fbut = Gtk2::Button->new("Apply filter"), 0, 0, 4); $searchBox->pack_end(my $filter = Gtk2::Entry->new, 0, 0, 4); gtkappend_page(my $nb = Gtk2::Notebook->new, gtkpack(create_scrolled_window($usertree)), gtkshow(Gtk2::Label->new(N("Users")))); gtkappend_page($nb, gtkpack(create_scrolled_window($grouptree)), gtkshow(Gtk2::Label->new(N("Group Users")))); $nb->set_show_border(0); gtkadd($us->{wnd}{window}, gtkpack_(Gtk2::VBox->new(0, 0), 0, $menu, 0, $toolb, 0, $searchBox, 1, $nb )); my @ucolsize = (80, 50, 50, 120, 80, 80, -1); my @gcolsize =(100, 80, 160, -1) ; each_index { my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i); $col->set_min_width($ucolsize[$::i]); $usertree->append_column($col); } (N("User Name"), N("User ID"), N("Primary Group"), N("Full Name"), N("Login Shell"), N("Home Directory")); each_index { my $col = Gtk2::TreeViewColumn->new_with_attributes($_, Gtk2::CellRendererText->new, 'text' => $::i); $col->set_min_width($gcolsize[$::i]); $grouptree->append_column($col); } (N("Group Name"), N("Group ID"), N("Group Members")); my @toolbwg; map { my $t = $toolb->append_item($_->[0], $_->[1], $_->[2], Gtk2::Image->new_from_file($pixdir . $_->[2] . '.png'), $_->[3], $toolb); push(@toolbwg, $t); $toolb->append_space; } ( [ N("Add User"), N("Add a user to the system"), 'user_add', \&AddUser ], [ N("Add Group"), N("Add a group to the system"), 'group_add', \&AddGroup ], [ N("Edit"), N("Edit selected row"), 'user_conf', \&Edit ], [ N("Delete"), N("Delete selected row"), 'user_del', \&Delete ], [ N("Refresh"), N("Refresh the list"), 'refresh', \&Refresh ], [ N("Help"), N("Generic help on userdrake"), 'help', \&HelpSystem ] ); my ($tbuser, $tbgroup, $tbedit, $tbdel, $tbref, $tbhelp) = @toolbwg; foreach (($tbedit, $tbdel, $checkedit, $checkdel)) { $_->set_sensitive(0) }; my $ctx = USER::ADMIN->new; Refresh($sysfilter); $nb->signal_connect('switch-page' => sub { NotebookSwitch() }); $us->{wnd}{rwindow}->show_all; Gtk2->main; ugtk2->exit; sub TreeUnselect { my $treev = shift; $treev->get_selection->unselect_all; foreach (($tbedit, $tbdel, $checkedit, $checkdel)) { $_->set_sensitive(0) }; } sub NotebookSwitch { my $page = $nb->get_current_page(); $page and TreeUnselect($usertree) or TreeUnselect($grouptree); } sub Refresh_Users_Full { my $filterusers = shift; my $users = $ctx->UsersEnumerateFull(); $utree_model->clear(); my @UserReal; LOOP: foreach my $l (@$users) { next LOOP if ($filterusers && $l->Uid($GetValue) <= 499 || $l->Uid($GetValue) == 65534) ; push(@UserReal, $l) }; foreach my $l (@UserReal) { my $a = $l->Gid($GetValue); my $group = $ctx->LookupGroupById($a); $utree_model->append_set([ 0 => $l->UserName($GetValue), 1 => $l->Uid($GetValue), 2 => $group->GroupName($GetValue), 3 => $l->Gecos($GetValue), 4 => $l->LoginShell($GetValue), 5 => $l->HomeDir($GetValue) ]); } } sub Refresh_Groups_Full { my $filtergroups = shift; my $groups = $ctx->GroupsEnumerateFull(); $gtree_model->clear(); my @GroupReal; LOOP:foreach my $g (@$groups) { next LOOP if ($filtergroups && $g->Gid($GetValue) <= 499 || $g->Gid($GetValue) == 65534); push(@GroupReal, $g) }; foreach my $g (@GroupReal) { my $a = $g->Gid($GetValue); my $group = $ctx->LookupGroupById($a); my $u_b_g = $ctx->EnumerateUsersByGroup($g->GroupName($GetValue)); my $listUbyG = join(',', @$u_b_g); $gtree_model->append_set([ 0 => $g->GroupName($GetValue), 1 => $g->Gid($GetValue), 2 => $listUbyG ]); } } sub Refresh { my $filt = shift; Refresh_Users_Full($filt); Refresh_Groups_Full($filt); } sub AddUser { my $w = ugtk2->new(N("Create New User"), grab => 1); my $dontcreatehomedir = 0; my $is_system = 0; my %u; my %sec = getVarsFromSh($secfile); gtkadd($w->{window}, gtkpack_(Gtk2::VBox->new(0, 2), 0, BuildUui(), 0, Gtk2::HSeparator->new, 0, $us->{o}->{createhomedir} = Gtk2::CheckButton->new(N("Create home Directory")), 0, gtkpack_(Gtk2::HBox->new(0, 4), 0, Gtk2::Label->new(N("Home Directory: ")), 0, $us->{o}->{homedir} = Gtk2::Entry->new() ), 0, $us->{o}->{privategroup} = Gtk2::CheckButton->new(N("Create a private group for the user")), 0, $us->{o}->{userid} = Gtk2::CheckButton->new(N("Specify user ID manually")), 0, gtkset_sensitive(my $h = Gtk2::HBox->new(0, 4), 0), 0, Gtk2::HSeparator->new, 0, gtkpack(Gtk2::HBox->new(1, 20), map { my $r = $_->[1]; gtksignal_connect(Gtk2::Button->new($_->[0]), clicked => sub { if (!$r) { $u{username} = $us->{o}->{login}->get_text(); $error = 0; if (!valid($u{username})) { raiseerror($us->{error}); $error = 1 }; my $nm = $ctx->LookupUserByName($u{username}); if ($nm) { raiseerror(N("User already exists, please choose another User Name")); $error = 1 ; $us->{o}->{login}->set_text('') }; $u{passwd} = $us->{o}->{passwd}->get_text(); if ($u{passwd} ne $us->{o}->{confpasswd}->get_text()) { raiseerror(N("Password Mismatch")); $error = 1 }; if ($sec{SECURE_LEVEL} > 3 && length($u{passwd}) < 6) { raiseerror(N("This password is too simple. \n Good passwords should be > 6 caracters")); $error = 1 }; my $userEnt = $ctx->InitUser($u{username}, $is_system); if ($us->{o}->{createhomedir}->get_active) { $dontcreatehomedir = 0; $u{homedir} = $us->{o}->{homedir}->get_text(); $userEnt->HomeDir($u{homedir}); } else { $dontcreatehomedir = 1 } if ($us->{o}->{userid}->get_active) { if (($u{uid} = $us->{o}->{uid}->get_value) < 500) { my $uidchoice = GimmeChoice(N("User Uid is < 500"), N("Creating a user with a UID less than 500 is not recommended.\n Are you sure you want to do this?\n\n")); $uidchoice and $userEnt->Uid($u{uid}); } else { $userEnt->Uid($u{uid}) } }; if ($us->{o}{privategroup}->get_active) { if (!$error) { #Check if group exist my $gr = $ctx->LookupGroupByName($u{username}); if ($gr) { my $groupchoice = ChooseGroup(); if ($groupchoice == 0 && !$error) { #You choose to put it in the existing group $u{gid} = $gr->Gid($GetValue); } elsif ($groupchoice == 1) { # Put it in 'users' group $u{gid} = Add2UsersGroup($u{username}); } } else { #it's a new group: Add it my $newgroup = $ctx->InitGroup($u{username},$is_system); $u{gid} = $newgroup->Gid($GetValue); $ctx->GroupAdd($newgroup); } } } else { $u{gid} = Add2UsersGroup($u{username}); #debug Info (to be removed before final) printf("le Gid du group sera %d", $u{gid}); } if(!$error) { $u{gecos} = $us->{o}->{fullname}->get_text(); $u{loginshell} = $us->{o}->{shells}->entry->get_text(); $userEnt->Gecos($u{gecos}); $userEnt->LoginShell($u{loginshell}); $userEnt->Gid($u{gid}); $ctx->UserAdd($userEnt, $is_system, $dontcreatehomedir); $ctx->UserSetPass($userEnt, $u{passwd}); Refresh($sysfilter); } } !$error and Gtk2->main_quit; $error = 0 }) } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ])), ) ); map { $us->{o}->{$_}->set_active } (qw(privategroup createhomedir)); $us->{o}->{login}->signal_connect('focus_out_event' => sub { my $fullname = $us->{o}->{fullname}->get_text(); $us->{o}->{homedir}->set_text("/home/".$us->{o}->{login}->get_text()); $fullname or $us->{o}->{fullname}->set_text($us->{o}->{login}->get_text()) }); $us->{o}->{uid} = Gtk2::SpinButton->new(Gtk2::Adjustment->new(500, 1, 65000, 1, 10, 10), 1, 0); $h->pack_end($us->{o}->{uid}, 0, 0, 4); $h->pack_end(Gtk2::Label->new(N("UID: ")), 0, 0, 4); GrayBox($us->{o}->{userid}, $h, 0); $w->{rwindow}->show_all; $w->main; } sub Add2UsersGroup { my $name = shift; my $usersgroup = $ctx->LookupGroupByName('users'); $usersgroup->MemberName($name, 1); return $usersgroup->Gid($GetValue); } sub ChooseGroup() { my $w = ugtk2->new(N("Choose Group"), grab => 1, center => 1); my $choice; my @radio = gtkradio(N("Add to the existing group"), (N("Add to the existing group"), N("Add to the 'users' group"))); gtkadd($w->{window}, gtkpack__(Gtk2::VBox->new(0,5), Gtk2::Label->new(N("A group with this name already exists. What would you like to do?")), gtkpack(Gtk2::VBox->new(0,0), @radio), Gtk2::HSeparator->new, gtkpack(create_hbox(), gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { each_index { $_->get_active and $choice = $::i } @radio; Gtk2->main_quit; }), gtksignal_connect(Gtk2::Button->new(N("Cancel")), clicked => sub { $w->{retval} = 0; $error = 1; Gtk2->main_quit })))); $w->main; $choice; } sub GimmeChoice { my ($title, $text) = @_; my $w = ugtk2->new($title, grab => 1, center => 1); my $choice; gtkadd($w->{window}, gtkpack__(Gtk2::VBox->new(0,5), Gtk2::Label->new($text), Gtk2::HSeparator->new, gtkpack(create_hbox(), gtksignal_connect(Gtk2::Button->new(N("Yes")), clicked => sub { $choice = 1; Gtk2->main_quit; }), gtksignal_connect(Gtk2::Button->new(N("No")), clicked => sub { $choice = $w->{retval} = 0; $error = 1; Gtk2->main_quit })))); $w->main; $choice; } sub AddGroup { my $w = ugtk2->new(N("Create New User"), grab => 1); my $mode = 0; my %g; my $is_system = 0; gtkadd($w->{window}, gtkpack_(Gtk2::VBox->new(0, 2), 0, BuildGui(), 0, Gtk2::HSeparator->new, 0, $us->{o}->{groupid} = Gtk2::CheckButton->new(N("Specify group ID manually")), 0, gtkset_sensitive(my $h = Gtk2::HBox->new(0, 4), 0), 0, Gtk2::HSeparator->new, 0, gtkpack(Gtk2::HBox->new(1, 20), map { my $r = $_->[1]; gtksignal_connect(Gtk2::Button->new($_->[0]), clicked => sub { if (!$r) { $g{groupname} = $us->{o}->{groupname}->get_text(); $error = 0; if (!valid($g{groupname})) { raiseerror($us->{error}); $error = 1 }; my $nm = $ctx->LookupUserByName($g{groupname}); if ($nm) { raiseerror(N("Group already exists, please choose another Group Name")); $error = 1 ; $us->{o}->{groupname}->set_text('') }; my $groupEnt = $ctx->InitGroup($g{groupname}, $is_system); if ($us->{o}->{groupid}->get_active) { if (($g{gid} = $us->{o}->{gid}->get_value) < 500) { my $gidchoice = GimmeChoice(N(" Group Gid is < 500"), N("Creating a group with a GID less than 500 is not recommended.\n Are you sure you want to do this?\n\n")); $gidchoice and $groupEnt->Gid($g{gid}); } else { $groupEnt->Gid($g{gid}) } }; if(!$error) { $ctx->GroupAdd($groupEnt); Refresh($sysfilter); } } !$error and Gtk2->main_quit; $error = 0; }) } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ])), ) ); $us->{o}->{gid} = Gtk2::SpinButton->new(Gtk2::Adjustment->new(500, 1, 65000, 1, 10, 10), 1, 0); $h->pack_end($us->{o}->{gid}, 0, 0, 4); $h->pack_end(Gtk2::Label->new(N("GID: ")), 0, 0, 4); $us->{o}->{groupid}->signal_connect('clicked' => sub { $mode = !$mode; $h->set_sensitive($mode) }); $w->{rwindow}->show_all; $w->main; } sub UpdateOrDelUsersInGroup { my ($name, $action) = @_; my $groups = $ctx->GroupsEnumerateFull(); if ($action) { foreach my $g (@$groups) { my $members = $g->MemberName(1, 0); any { $_ eq $name } @$members and $g->MemberName($name, 2); $ctx->GroupModify($g); } } else { print ("Updating MemberName \n"); } } sub Delete { my $page = $nb->get_current_page(); if ($page == 0) { my (undef, $iter) = $usertree->get_selection->get_selected; my $username = $utree_model->get($iter, 0); $iter->free; my $userEnt = $ctx->LookupUserByName($username); $ctx->UserDel($userEnt); UpdateOrDelUsersInGroup($username, 1); #Let's check out the user's primary group my $usergid = $userEnt->Gid($GetValue); my $groupEnt = $ctx->LookupGroupById($usergid); my $member = $groupEnt->MemberName(1, 0); if (!$groupEnt && @$member) { $groupEnt->Gid($GetValue) > 500 and $ctx->GroupDel($groupEnt) }; my $removehome = GimmeChoice(N(" Remove Home Directory"), N("Do you want to delete the user's home directory?")); $removehome and $ctx->Clean($userEnt); Refresh($sysfilter) } elsif ($page == 1) { my (undef, $iter) = $grouptree->get_selection->get_selected; my $groupname = $gtree_model->get($iter,0); my $groupEnt = $ctx->LookupGroupByName($groupname); $iter->free } } # Gtk Facilities 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 { foreach (($tbedit, $tbdel, $checkedit, $checkdel)) { $_->set_sensitive(1);} }); $tree->signal_connect(button_press_event => sub { my (undef, $event) = @_; my (undef, $iter) = $tree->get_selection->get_selected; return unless $iter; foreach (($tbedit, $tbdel, $checkedit, $checkdel)) { $_->set_sensitive(1) }; Edit($iter) if $event->type eq '2button-press'; $iter->free; }); $tree->signal_connect(key_press_event => sub { my (undef, $event) = @_; my (undef, $iter) = $tree->get_selection->get_selected; return unless $iter; Edit($iter) if ($event->keyval == Gtk2::Gdk::Event::Key->Sym_Return); $iter->free; }); $tree } sub gtkentry_hidepass { my ($text) = @_; my $e = Gtk2::Entry->new(); $text and $e->set_text($text); $e->set_visibility(0); $e } sub gtkentry_sized { my $i = shift; my $e = Gtk2::Entry->new_with_max_length($i); $e->set_size_request(30, 20); $e } sub BuildUui { gtkpack_(my $vbox = Gtk2::VBox->new(0, 2), 1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings => 5 }, [ N("Login") . " :", $us->{o}->{login} = Gtk2::Entry->new() ], [ N("Full Name") . " :", $us->{o}->{fullname} = Gtk2::Entry->new() ], [ N("Password") . " :", $us->{o}->{passwd} = gtkentry_hidepass() ], [ N("Confirm Password:") . " :", $us->{o}->{confpasswd} = gtkentry_hidepass() ], [ N("Login Shell") . " :", $us->{o}->{shells} = Gtk2::Combo->new ] ) ); $us->{o}->{shells}->set_popdown_strings(@{$ctx->GetUserShells()}); $us->{o}->{shells}->entry->set_text("/bin/bash"); $vbox } sub BuildGui { gtkpack_(my $vbox = Gtk2::VBox->new(0, 2), 1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings =>5 }, [ N("Group Name") . " :", $us->{o}->{groupname} = Gtk2::Entry->new() ] ) ); $vbox } sub Edit { my $iter = shift; my $w = ugtk2->new('userdrake', grab => 1); map { my $tr = $_->[0]; my $ch = $_->[1]; my $co = $_->[2]; my $tree_model = Gtk2::ListStore->new(Gtk2::GType->BOOLEAN, Gtk2::GType->STRING); $us->{$tr} = Gtk2::TreeView->new_with_model($tree_model); $us->{$tr}->get_selection->set_mode('browse'); $us->{$ch} = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererToggle->new, 'active' => 0); $us->{$co} = Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => 0); $us->{$tr}->append_column($us->{$ch}); $us->{$tr}->append_column($us->{$co}); $us->{$tr}->set_headers_visible(0); } (["utree", "ucheck", "ucol"], ["gtree", "gcheck", "gcol"]); my $p = $nb->get_current_page(); print " Page = $p"; my $nbU = Gtk2::Notebook->new; my $nbG = Gtk2::Notebook->new; if ($p == 0) { gtkappend_page($nbU, gtkpack_(Gtk2::VBox->new(0, 2), 1, BuildUui(), 1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings => 5 }, [ N("Home") . " :", $us->{o}->{homedir} = Gtk2::Entry->new() ] ) ), gtkshow(Gtk2::Label->new(N("User Data")))); my $m = 0; my $s = 0; gtkappend_page($nbU, gtkpack_(Gtk2::VBox->new(0, 2), 0, $us->{o}->{acheckexpire} = Gtk2::CheckButton->new(N("Enable account expiration")), 0, gtkpack__(my $h = Gtk2::HBox->new(0, 10), 0, Gtk2::Label->new(N("Account expires") . " MM/DD/YYYY :"), 1, map { my $s = $_->[0]; my $t = $_->[1]; $us->{o}->{$s} = gtkentry_sized($t), } (['expm', 2], ['expd', 2], ['expy', 4]), ), 0, Gtk2::HSeparator->new, 0, $us->{o}->{lockuser} = Gtk2::CheckButton->new(N("Lock User Account")) ), gtkshow(Gtk2::Label->new(N("Account Info")))); GrayBox($us->{o}->{acheckexpire}, $h, 0); gtkappend_page($nbU, gtkpack_(Gtk2::VBox->new(0, 2), 0, $us->{o}->{pcheckexpire} = Gtk2::CheckButton->new(N("Enable Password Expiration")), 1, gtkpack_(my $v = Gtk2::VBox->new(0,1), 1, create_packtable({ homogeneous => 1, col_spacings => 5, row_spacings => 5 }, [ N("Days before change allowed :"), $us->{o}->{dbca} = Gtk2::Entry->new(0) ], [ N("Days before change required :"), $us->{o}->{dbcr} = Gtk2::Entry->new(0) ], [ N("Days warning before change :"), $us->{o}->{bwbc} = Gtk2::Entry->new(0) ], [ N("Days before account inactive :"), $us->{o}->{dbai} = Gtk2::Entry->new(0) ] ) )), gtkshow(Gtk2::Label->new(N("Password Info")))); GrayBox($us->{o}->{pcheckexpire}, $v, 0); gtkappend_page($nbU, gtkpack_(Gtk2::VBox->new(0, 2), 0, Gtk2::Label->new(N("Select the groups that the user will be a member of:")), 1, $us->{utree} ), gtkshow(Gtk2::Label->new(N("Account Info")))); } else { $nbG->set_size_request(300, 200); gtkappend_page($nbG, gtkpack_(Gtk2::VBox->new(0, 2), 1, BuildGui()), gtkshow(Gtk2::Label->new(N("Group Data")))); gtkappend_page($nbG, gtkpack_(Gtk2::VBox->new(0, 1), 0, Gtk2::Label->new(N("Select the users to join this group :")), 1, $us->{gtree}), gtkshow(Gtk2::Label->new(N("Group Users")))); } gtkadd($w->{window}, gtkpack_(Gtk2::VBox->new(0,5), 1, !$p ? $nbU : $nbG, 0, Gtk2::HSeparator->new, 0, gtkpack(Gtk2::HBox->new(1, 20), map { my $retv = $_->[1]; gtksignal_connect(Gtk2::Button->new($_->[0]), clicked => sub { if (!$retv) { #my ($model, $iter) = $tree->get_selection->get_selected; #$model and $w->{retval} = { sel => $model->get($iter, 0) }; #$iter and $iter->free; } Gtk2->main_quit }) } ([ N("Cancel"), 1 ], [ N("Ok"), 0 ])), )); my %roots; # $tree_model->append_set($roots{$_->{land}} ||= $tree_model->append_set(undef, [ 0 => $_->{land} ]), # [ 0 => $_->{url} ])->free foreach @mirrors; # $w->{window}->set_size_request(400, 300); $w->{rwindow}->show_all; $w->main } sub GrayBox { my ($o, $v, $m) = @_; $v->set_sensitive($m); $o->signal_connect('clicked' => sub { $m = !$m; $v->set_sensitive($m) }); } sub new_dialog { my ($title, $no_button) = @_; my $dialog = gtkset_border_width(Gtk2::Dialog->new(), 10); $dialog->set_transient_for($us->{wnd}{rwindow}); $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 $no_button; gtkset_modal($dialog, 1); } sub about_mdk_userdrake { my $window_about = new_dialog(N("Userdrake2")); my $tree_model = Gtk2::TreeStore->new(Gtk2::GType->STRING, Gtk2::GType->STRING, Gtk2::GType->STRING); my $list = Gtk2::TreeView->new_with_model($tree_model); $list->can_focus(0); each_index { $list->append_column(Gtk2::TreeViewColumn->new_with_attributes(undef, Gtk2::CellRendererText->new, 'text' => $::i)) } 0..2; $list->set_headers_visible(0); foreach my $row ([ N("Authors: "), '', '' ], [ '', 'Daouda Lo', '' ], ['', '', '']) { $tree_model->append_set(undef, [ map_index { $::i => $_ } @$row ])->free; } $list->get_selection()->set_mode('none'); gtkpack_($window_about->vbox, -r "$pixdir/userdrake.png" ? (0, Gtk2::Image->new_from_file("$pixdir/userdrake.png")) : (1, gtkmodify_font(Gtk2::Label->new(N("Users Management \n") . $us->{VERSION}), 'Bold 18'),), 0, Gtk2::Label->new("\n" . N("Copyright (C) 2003 Mandrakesoft SA") . "\n"), 1, $list, ); $window_about->show_all; } sub valid { $_[0] or $us->{error} = N("Name field is empty please provide a name"), return 0; $_[0] =~ /^[a-z]+?[a-z0-9_-]*?$/ or $us->{error} = N("The name must contain only lower cased letters, numbers, `-' and `_'"), return 0; length($_[0]) <= 32 or $us->{error} = N("Name is too long"), return 0; return 1; } sub raiseerror { my $w = ugtk2->new(N("Error"), grab => 1, center => 1, transient => $us->{wnd}->{rwindow}); gtkadd($w->{window}, gtkpack_(Gtk2::VBox->new, 1, Gtk2::Label->new($_[0]), 0, Gtk2::HSeparator->new, 0, gtksignal_connect(Gtk2::Button->new(N("Ok")), clicked => sub { Gtk2->main_quit }) ), ); $w->main } sub quit_global { setVarsInSh($conffile, { FILTER => bool2text($sysfilter), }); gtkset_mousecursor_normal(); Gtk2->main_quit; }