#!/usr/bin/perl
#
# Copyright (C) 2005 by Mandriva aginies _ateuh_ mandriva.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.

my $version = "0.2";

use strict;
use lib qw(/usr/lib/libDrakX);
use standalone;
use common;
use network::network;
use interactive;
use ugtk2 qw(:ask :wrappers :create :dialogs);
use mygtk2 qw(gtknew);
use Gtk2::SimpleList;
use Gtk2::Gdk::Keysyms;

# use libconf
use Libconf::Templates;
use Libconf::Glueconf::Samba::Smb_conf;

my $in = 'interactive'->vnew('su');
$in->do_pkgs->ensure_is_installed('samba-server', '/usr/sbin/smbd') or return;

my $icon_path = "/usr/lib/libDrakX/icons";
my $fileshare_icon = "$icon_path/IC-winacces2-16.png";
my $printershare_icon = "$icon_path/IC-sambaprt-16.png";
my $sambauser_icon = "$icon_path/ic82-users-16.png";
my $pixbuf_file = Gtk2::Gdk::Pixbuf->new_from_file($fileshare_icon);
my $pixbuf_printer = Gtk2::Gdk::Pixbuf->new_from_file($printershare_icon);
my $pixbuf_user = Gtk2::Gdk::Pixbuf->new_from_file($sambauser_icon);

my $printer_list = create_printer_list();
my $share_list = create_share_list();
my $user_list = create_user_list();

sub create_user_list() {
  my $user_list = Gtk2::SimpleList->new('' => 'pixbuf',
					N("User name") => 'text',
				       );
  $user_list;
}

sub create_share_list() {
    my $share_list = Gtk2::SimpleList->new('' => 'pixbuf',
					 N("Share name") => 'text',
					 N("Share directory") => 'text',
					 N("Comment") => 'text',
					 N("Browseable") => 'text',
					 N("Public") => 'text',
					 N("Writable") => 'text',
					 N("Create mask") => 'text',
					 N("Directory mask") => 'text',
					 N("Read list") => 'text',
					 N("Write list") => 'text',
					 N("Admin users") => 'text',
					 N("Valid users") => 'text',
					 N("Inherit Permissions") => 'text',
					 N("Hide dot files") => 'text',
					 N("Hide files") => 'text',
					 N("Preserve case") => 'text',
					 N("Force create mode") => 'text',
					 N("Force group") => 'text',
					 N("Default case") => 'text',
					);
  $share_list->set_headers_clickable(1);
  foreach ($share_list->get_columns) {
    $_->set_resizable(1);
  }
  foreach (1, 2, 3) {
    $share_list->get_column($_)->signal_connect('clicked', \&sort_by_column, $share_list->get_model);
    $share_list->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2);
  }
  $share_list;
}

sub create_printer_list() {
   my $printer_list = Gtk2::SimpleList->new('' => 'pixbuf',
					    N("Printer name") => 'text',
					    N("Path") => 'text',
					    N("Comment") => 'text',
					    N("Browseable") => 'text',
					    N("Printable") => 'text',
					    N("Print Command") => 'text',
					    N("LPQ command") => 'text',
					    N("Guest ok") => 'text',
					    N("Writable") => 'text',
					    N("Write list") => 'text',
					    N("Inherit permissions") => 'text',
					    N("Printing") => 'text',
					    N("Create mode") => 'text',
					    N("Use client driver") => 'text',
					   );
  $printer_list->set_headers_clickable(1);
  foreach (1, 2, 3) {
    $printer_list->get_column($_)->signal_connect('clicked', \&sort_by_column, $printer_list->get_model);
    $printer_list->get_column($_)->set_sort_column_id($_ == 0 ? 1 : $_ + 2);
  }
  $printer_list;
}

sub sort_by_column {
    my ($column, $model) = @_;
    my $col_id = $column->get_sort_column_id;
    my ($old_id, $old_order) = $model->get_sort_column_id;
    $model->set_sort_column_id($col_id, $old_id == $col_id && $old_order ne 'descending' ? 'ascending' : 'descending');
}

#path comment browseable printable print command guest ok writable write list inherit permissions printing lpq command create mode use client driver


my $samba = new Libconf::Glueconf::Samba::Smb_conf({ filename => '/etc/samba/smb.conf', show_commented_info => 1 });
my (@listshare, @listprinters, @listusers);
my @yesno = qw(yes no); push @yesno, ""; 
my @default_case = qw(upper lower); push @default_case, "";

my %adv_options = (
		   read_list => N("Read List"),
		   write_list => N("Write List"),
		   admin_users => N("Admin users"),
		   valid_users => N("Valid users"),
		   hide_dot_files => N("Hide dot files"),
		   hide_files => N("Hide files"),
		   force_group => N("Force Group"),
		   force_create_mode => N("Force create group"),
		   default_case => N("Default case"),
		   preserve_case => N("Preserve case"),
		   create_mask => N("Create mask"),
		   directory_mask => N("Directory mask"),
		   inherit_permissions => N("Inherit permissions"),
		  );

sub get_items() {
    my @items = (
		 [ "/_File", undef, undef, undef, '<Branch>', ],
		 [ "/_File/_Write conf", undef, \&write_conf, 1, '<StockItem>', 'gtk-execute' ],
		 [ "/_File/_Exit", undef, \&quit_all, 1, '<StockItem>', 'gtk-quit' ],

		 [ "/_Samba Server", undef, undef, undef, '<Branch>', ],
		 [ "/_Samba Server/_Restart", undef, \&restart_dialog, 1, '<StockItem>', 'gtk-execute' ],
		 [ "/_Samba Server/R_eload", undef, \&reload_dialog, 1, '<StockItem>', 'gtk-refresh' ],

		 [ "/_About/Report a bug", undef, sub { unless (fork()) { exec("drakbug --report draksambashare &") } }, 1, '<StockItem>', 'gtk-stop' ],
		 [ "/_About/About...", undef, sub {
		     create_dialog(N("About Draksambashare"), N("Mandriva Linux \nRelease: %s\nAuthor: Antoine Ginies\n\nThis is a simple tool to easily manage Samba configuration.", $version));
		 }, 1, '<StockItem>', 'gtk-preferences' ],
		 );
    return @items;
}

sub quit_all() {
  ugtk2->exit;
}

sub restart_dialog() {
  wait_action("service smb restart");
}

sub reload_dialog() {
  wait_action("service smb reload");
}

sub wait_action {
    my ($cmd) = @_;
    my $w = $in->wait_message(N("Samba server"), N("Restarting/Reloading Samba server..."));
    run_program::get_stdout($cmd) !~ /unknown|error/ or err_dialog(N("Error!"), N("Error Restarting/Reloading Samba server")) and return;
    undef $w;
}

my %size_groups = map { $_ => Gtk2::SizeGroup->new('horizontal') } qw(label widget button);
my $label_and_widgets = sub {
  my ($label, $widget, $button) = @_;
  gtkpack_(Gtk2::HBox->new(0,1),
           0, gtkadd_widget($size_groups{label}, $label),
           0, gtkadd_widget($size_groups{widget}, $widget),
	   if_($button, 0, gtkadd_widget($size_groups{button}, $button)),
          );
};

my $fdwidget = sub {
  my ($data) = @_;
  my $fd = new Gtk2::FileSelection(N("Directory Selection"));
  $fd->set_modal(1);
  $fd->signal_connect("destroy", sub { $fd->hide });
  $fd->ok_button->signal_connect(clicked => sub {
				   my $file = $fd->get_filename;
				   -d $file or err_dialog(N("Error!"), N("Should be a directory.")) and return;
				   $data->set_text($file);
				   $fd->hide;
				 }, $fd);
  $fd->cancel_button->signal_connect(clicked => sub { $fd->hide });
  return $fd;
};

sub get_samba_share() {
  undef @listshare;
  foreach my $clef (keys %$samba) {
    if ($samba->{$clef}{printable} =~ /yes/i || $clef =~ /print\$/) {
      print "$clef is a printer\n";
    } elsif ($clef =~ /global/ || $clef =~ /cdrom$/ || $clef eq "Profiles") {
      print "unwanted (special shares)\n";
    } else {
      push @listshare, {
			share_name => $clef,
			path => $samba->{$clef}{path},
			comment => $samba->{$clef}{comment},
			browseable => $samba->{$clef}{browseable},
			public => $samba->{$clef}{public},
			writable => $samba->{$clef}{writable},
			create_mask => $samba->{$clef}{'create mask'},
			directory_mask => $samba->{$clef}{'directory mask'},
			read_list => $samba->{$clef}{'read list'},
			write_list => $samba->{$clef}{'write list'},
			admin_users => $samba->{$clef}{'admin users'},
			valid_users => $samba->{$clef}{'valid users'},
			hide_dot_files => $samba->{$clef}{'hide dot files'},
			hide_files => $samba->{$clef}{'hide files'},
			preserve_case => $samba->{$clef}{'preserve case'},
			force_create_mode => $samba->{$clef}{'force create mode'},
			force_group => $samba->{$clef}{'force group'},
			default_case => $samba->{$clef}{'default case'},
			inherit_permissions => $samba->{$clef}{'inherit permissions'},
		       };
    }
  }
  return @listshare;
}

sub get_samba_user() {
  undef @listusers;
  foreach (cat_("/etc/samba/smbpasswd")) {
    my ($user) = m!^(\w+):!;
    $user and push @listusers, {
				user_name => $user,
			       };
  }
  return @listusers;
}


sub get_samba_printers() {
  undef @listprinters;
  foreach my $clef (keys %$samba) {
    if ($samba->{$clef}{printable} =~ /yes/i || $clef =~ /print\$/) {
      push @listprinters, {
			   share_name => $clef,
			   path => $samba->{$clef}{path},
			   comment => $samba->{$clef}{comment},
			   browseable => $samba->{$clef}{browseable},
			   printable => $samba->{$clef}{printable},
			   print_command => $samba->{$clef}{'print command'},
			   lpq_command => $samba->{$clef}{'lpq command'},
			   guest_ok => $samba->{$clef}{'guest ok'},
			   writable => $samba->{$clef}{writable},
			   write_list => $samba->{$clef}{'write list'},
			   inherit_permissions => $samba->{$clef}{'inherit permissions'},
			   printing => $samba->{$clef}{printing},
			   create_mode => $samba->{$clef}{'create mode'},
			   use_client_driver => $samba->{$clef}{'use client driver'},
			  };
    }
  }
  return @listprinters;
}

sub write_conf() {
  $samba->write_conf("/etc/samba/smb.conf");
}

sub create_pango_help_box {
  # perl code from draksec
  my ($help) = @_;
  my $text = Gtk2::TextView->new;
  use Gtk2::Pango;
  my %common_opts = ('left-margin' => '10', 'right-margin' => '10');
  gtktext_insert($text, [ map  {
    if (s!^/span>!!) {
      [ $_, \%common_opts ];
    } elsif (s!span !!) {
      my %tags = %common_opts;
      while (s!(\w+?)="(\w+?)"!!) {
	$tags{weight} ||= Gtk2::Pango->PANGO_WEIGHT_BOLD if $1 eq 'foreground';
	$tags{$1} = $2 eq "bold" ? Gtk2::Pango->PANGO_WEIGHT_BOLD : $2;
      }
      s/^>//;
      [ $_, \%tags ];
    } else {
      [ $_, \%common_opts ];
    }
  } split("<", formatAlaTeX($help)) ]);
  gtkset_size_request(create_scrolled_window($text), 350, 300);
}

sub help_b {
  my ($help_data) = @_;
  gtksignal_connect(new Gtk2::Button->new_from_stock('gtk-dialog-info'), clicked => sub {
		      my $dialog = _create_dialog();
		      $dialog->set_transient_for($::main_window);
		      $dialog->set_title(N("Help"));
		      $dialog->set_modal(1);
		      gtkpack_($dialog->vbox,
			       1, create_pango_help_box($help_data),
			       0, gtksignal_connect(Gtk2::Button->new_from_stock('gtk-close'), clicked => sub {
				   $dialog->destroy;
						    }
						   ),
			      );
		      $dialog->show_all;
		    }
		    );
}

sub printdollar_section() {
  $samba->{'print$'};
  $samba->{'print$'}{browseable} = "yes";
  $samba->{'print$'}{path} = "/var/lib/samba/printers";
  $samba->{'print$'}{browseable} = "yes";
  $samba->{'print$'}{'write list'} = "\@adm root";
  $samba->{'print$'}{'guest ok'} = "yes";
  $samba->{'print$'}{'inherit permissions'} = "yes";
}

sub pdf_section() {
  $samba->{'pdf-gen'};
  $samba->{'pdf-gen'}{path} = "/var/tmp";
  $samba->{'pdf-gen'}{'guest ok'} = "no";
  $samba->{'pdf-gen'}{printable} = "yes";
  $samba->{'pdf-gen'}{comment} = "PDF Generator (only valid users)";
  $samba->{'pdf-gen'}{printing} = "bsd";
  $samba->{'pdf-gen'}{'print command'} = '/usr/share/samba/scripts/print-pdf %s %H \//%L/%u\ %m %I %J &';
  $samba->{'pdf-gen'}{'lpq command'} = "/bin/true";
}

sub printers_section() {
  $samba->{printers};
  $samba->{printers}{comment} = "All Printers";
  $samba->{printers}{browseable} = "no";
  $samba->{printers}{'guest ok'} = "yes";
  $samba->{printers}{'create mode'} = "0700";
  $samba->{printers}{path} = "/var/spool/samba";
  $samba->{printers}{writable} = "no";
  $samba->{printers}{printable} = "yes";
  $samba->{printers}{'print command'} = 'lpr-cups -P %p -o raw %s -r';
  $samba->{printers}{'use client driver'} = "yes";
}

sub add_entry() {
  use wizards;
  my ($wiz_addshare_name, $wiz_addshare_comment, $wiz_addshare_path);
  my $w = wizards->new;
  my $wiz = {
	     name => N("Add a Samba share"),
	     pages => {
		       welcome => {
				   name => N("Goal of this wizard is to easily create a new Samba share."),
				   data => [
					    { label => N("Name of the share:"), val => \$wiz_addshare_name },
					    { label => N("Comment:"), val => \$wiz_addshare_comment },
					    { label => N("Path:"), val => \$wiz_addshare_path },
					     ],
				   complete => sub {
				     foreach my $clef (keys %$samba) {
				       if ($clef =~ /$wiz_addshare_name/) {
					 err_dialog(N("Error"), N("Share with the same name already exist or share name empty, please choose another name.")) and return 'welcome';
				       }
				     }
				     if (!$wiz_addshare_path) {
				       err_dialog(N("Error"), N("Can't create the directory, please enter a correct path.")) and return 'welcome';
				     }
				     if (!$wiz_addshare_comment) {
				       err_dialog(N("Error"), N("Please enter a Comment for this share.")) and return 'welcome';
				     }
				     if (! -d $wiz_addshare_path) {
				       mkdir_p($wiz_addshare_path) or err_dialog(N("Error"), N("Can't create the directory, please enter a correct path.")) and return 'welcome';
				     }
				   },
				   post => sub {
				     push @{$share_list->{data}}, [
								     $pixbuf_file,
								     $wiz_addshare_name,
								     $wiz_addshare_path,
								     $wiz_addshare_comment,
								    ];
				     my $share = $wiz_addshare_name;
				     # update listshare
				     push @listshare, {
						       share_name => $share,
						       path => $wiz_addshare_path,
						       comment => $wiz_addshare_comment,
						      };
				     # update samba conf
				     $samba->{$share};
				     $samba->{$share}{path} = $wiz_addshare_path;
				     $samba->{$share}{comment} = $wiz_addshare_comment;
				     return;
				   },
				   no_back => 1,
				   next => 'end_add',
				  },
		       end_add => {
				   name => N("Congratulations"),
				   data => [ { label => N("The wizard successfully added the Samba share. Now just double click on it in treeview to modify it") } ],
				   no_back => 1,
				   end => 1,
				   next => 0,
				  },
		      }
	    };
  $w->process($wiz, $in);
  $::isWizard = 0;
  gtkset_mousecursor_normal();
}

sub add_printers_entry() {
  use wizards;
  my $w = wizards->new;
  my %print = (
	       1 => N("pdf-gen - a PDF generator"),
	       2 => N("printers - all printers available"),
	      );
  my $wiz_todo;
  my $wiz = {
	     name => N("Add Special Printer share"),
	     pages => {
		       welcome => {
				   name => N("Goal of this wizard is to easily create a new special printer Samba share."),
				   data => [
					    { label => "", type => 'list', val => \$wiz_todo, list => [ keys %print ], format => sub { $print{$_[0]} } }
					   ],
				   no_back => 1,
				   next => 'end_add',
				   post => sub {
				     if ($wiz_todo == 1) {
				       exists $samba->{'pdf-gen'} and err_dialog(N("Error"), N("A PDF generator already exists.")) and return 'welcome';
				       &pdf_section;
				       push @{$printer_list->{data}}, [
								       $pixbuf_printer,
								       'pdf-gen',
								       $samba->{'pdf-gen'}{path},
								       $samba->{'pdf-gen'}{comment}, "",
								       $samba->{'pdf-gen'}{printable},
								       $samba->{'pdf-gen'}{'print command'},
								       $samba->{'pdf-gen'}{'lpq command'},
								       $samba->{'pdf-gen'}{'guest ok'}, "", "", "",
								       $samba->{'pdf-gen'}{printing}, "", "",
								     ];
				       push @listprinters, {
							 share_name => $samba->{'pdf-gen'},
							 path => $samba->{'pdf-gen'}{path},
							 comment => $samba->{'pdf-gen'}{comment},
							 printebale => $samba->{'pdf-gen'}{printable},
							 printing => $samba->{'pdf-gen'}{printing},
							 print_command => $samba->{'pdf-gen'}{'print command'},
							 lpq_command => $samba->{'pdf-gen'}{'lpq command'},
							 guest_ok => $samba->{'pdf-gen'}{'guest ok'},
							};
				     } elsif ($wiz_todo == 2) {
				       exists $samba->{'print$'} || exists $samba->{printers} and err_dialog(N("Error"), N("Printers and print\$ already exist.")) and return 'welcome';
				       &printdollar_section;
				       &printers_section;
				       push @{$printer_list->{data}}, [
								       $pixbuf_printer,
								       'print$',
								       $samba->{'print$'}{path}, "",
								       $samba->{'print$'}{browseable}, "", "", "",
								       $samba->{'print$'}{'guest ok'}, "",
								       $samba->{'print$'}{'write list'},
								       $samba->{'print$'}{'inherit permissions'},
								       ];
				       push @{$printer_list->{data}}, [
								       $pixbuf_printer,
								       'printers',
								       $samba->{printers}{path},
								       $samba->{printers}{comment},
								       $samba->{printers}{browseable},
								       $samba->{printers}{printable},
								       $samba->{printers}{'print command'}, "",
								       $samba->{printers}{'guest ok'},
								       $samba->{printers}{writable}, "", "", "",
								       $samba->{printers}{'create mode'},
								       $samba->{printers}{'use client driver'},
								       ];
				       push @listprinters, {
					   share_name => 'print$',
					   path => $samba->{'print$'}{path},
					   browseable => $samba->{'print$'}{browseable},
					   write_list => $samba->{'print$'}{'write list'},
					   guest_ok => $samba->{'print$'}{'guest ok'},
					   inherit_permissions => $samba->{'print$'}{'inherit permissions'},
				       };
				       push @listprinters, {
					   share_name => "printers",
					   comment => $samba->{printers}{comment},
					   browseable => $samba->{printers}{browseable},
					   guest_ok => $samba->{printers}{'guest ok'},
					   create_mode => $samba->{printers}{'create mode'},
					   path => $samba->{printers}{path},
					   writable => $samba->{printers}{writable},
					   printable => $samba->{printers}{printable},
					   print_command => $samba->{printers}{'print command'},
					   use_client_driver => $samba->{printers}{'use client driver'},
				       };
				   }
				     return;
				   },
				  },
		       end_add => {
				   name => N("Congratulations"),
				   data => [ { label => N("The wizard successfully added the printer Samba share") } ],
				   no_back => 1,
				   end => 1,
				   next => 0,
				  },
		      }
	    };
  $w->process($wiz, $in);
  $::isWizard = 0;
  #  gtkset_mousecursor_normal()
}

sub modify_printers_entry {
  my ($selected) = @_;
  my ($dir, $comment, $print_command, $guest_ok, $share_name, $browseable, $printable, $write_list, $printing, $lpq_command, $create_mode, $writable, $use_client_driver, $inherit_permissions);

  $share_name = Gtk2::Label->new;
  $_ = Gtk2::Entry->new foreach $dir, $comment, $print_command, $write_list, $printing, $lpq_command, $create_mode;
  $_ = Gtk2::OptionMenu->new foreach $browseable, $printable, $guest_ok, $writable, $use_client_driver, $inherit_permissions;
  $_->set_popdown_strings(@yesno) foreach $browseable, $printable, $guest_ok, $writable, $use_client_driver, $inherit_permissions;


  my $s = $printer_list->{data}[$selected][1];
  $s or info_dialog(N("Error"), N("Please add or select a Samba printer share to be able to modify it.")) and return;  $share_name->set_text($s);
  $dir->set_text($printer_list->{data}[$selected][2]);
  $comment->set_text($printer_list->{data}[$selected][3]);
  $browseable->set_text($printer_list->{data}[$selected][4]);
  $printable->set_text($printer_list->{data}[$selected][5]);
  $print_command->set_text($printer_list->{data}[$selected][6]);
  $lpq_command->set_text($printer_list->{data}[$selected][7]);
  $guest_ok->set_text($printer_list->{data}[$selected][8]);
  $writable->set_text($printer_list->{data}[$selected][9]);
  $write_list->set_text($printer_list->{data}[$selected][10]);
  $inherit_permissions->set_text($printer_list->{data}[$selected][11]);
  $printing->set_text($printer_list->{data}[$selected][12]);
  $create_mode->set_text($printer_list->{data}[$selected][13]);
  $use_client_driver->set_text($printer_list->{data}[$selected][14]);

  my $file_dialog = $fdwidget->($dir, "");
  my $button = Gtk2::Button->new_from_stock('gtk-open');
  $button->signal_connect(clicked => sub { $file_dialog->show });

  my $dialog = _create_dialog();
  $dialog->set_transient_for($::main_window);
  local $::main_window = $dialog;
  $dialog->set_title("DrakSamba Printers entry");
  $dialog->set_position('center');
  $dialog->set_modal(1);
  $dialog->set_resizable(1);

  if ($s eq "printers") { $printable->set_text("yes");
			  $printing->set_text("");
			  $_->set_sensitive(0) foreach $printable, $printing;
		      }
  if ($s eq "pdf-gen") { $printing->set_text("bsd");
                          $printing->set_sensitive(0);
		     }

  gtkpack_($dialog->vbox,
	   0, gtkadd(Gtk2::Frame->new(N("Printer share")),
		  gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3),
			   0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
				       0, $label_and_widgets->(N("Printer name:"), $share_name, ""),
				       0, $label_and_widgets->(N("Comment:"), $comment, ""),
				       0, $label_and_widgets->(N("Directory:"), $dir, $button),
				      ),
			   0, Gtk2::VSeparator->new,
			   0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
				       0, $label_and_widgets->(N("Writable:"), $writable, ""),
				       0, $label_and_widgets->(N("Browseable:"), $browseable, ""),
				       0, $label_and_widgets->(N("Printable"), $printable, ""),
				      ),
			  ),
		 ),
	   0, gtkadd(Gtk2::Frame->new(N("Advanced options")),
		     gtkpack_(gtkset_border_width(Gtk2::HBox->new, 3),
			      0, gtkadd(Gtk2::Frame->new(N("Printer access")),
					gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
						 0, $label_and_widgets->(N("Write list"), $write_list, ""),
						 0, $label_and_widgets->(N("Inherit permissions"), $inherit_permissions, ""),
						 0, $label_and_widgets->(N("Guest ok:"), $guest_ok, ""),
						 0, $label_and_widgets->(N("Create mode:"), $create_mode, ""),
						),
				       ),
			      0, Gtk2::VSeparator->new,
			      0, gtkadd(Gtk2::Frame->new(N("Printer command")),
					gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
						 0, $label_and_widgets->(N("Print command:"), $print_command, ""),
						 0, $label_and_widgets->(N("LPQ command:"), $lpq_command, ""),
						 0, $label_and_widgets->(N("Printing:"), $printing, ""),
						),
				       ),
			     ),
		    ),
	   0, create_okcancel({
			       cancel_clicked => sub { $dialog->destroy },
			       ok_clicked => sub {
				   my $share = $share_name->get_text;
				   my $test_dir = $dir->get_text;
				   $comment->get_text or err_dialog(N("Information"), N("Please enter a Comment for this share.")) and return 1;
				   if (!-d $test_dir) {
				       err_dialog(N("Error!"), N("Please enter a directory to share.")) and return;
				   }
				   foreach ($create_mode->get_text) {
				       if ($_ && !/^\d+$/) {
					   err_dialog(N("Error"), N("create mode should be numeric. ie: 0755.")) and return 1;
				       }
				   }
				   # update gui SimpleList
				   remove_entry($selected, $printer_list);
				   push @{$printer_list->{data}}, [
								   $pixbuf_printer,
								   $share,
								   $dir->get_text,
								   $comment->get_text,
								   $browseable->get_text,
								   $printable->get_text,
								   $print_command->get_text,
								   $lpq_command->get_text,
								   $guest_ok->get_text,
								   $writable->get_text,
								   $write_list->get_text,
								   $inherit_permissions->get_text,
								   $printing->get_text,
								   $create_mode->get_text,
								   $use_client_driver->get_text,
								   ];
				   # update $samba
				   $samba->{$share}{path} = $dir->get_text;
				   $samba->{$share}{comment} = $comment->get_text;
				   $browseable->get_text and $samba->{$share}{browseable} = $browseable->get_text || delete $samba->{$share}{browseable};
				   $printable->get_text and $samba->{$share}{printable} = $printable->get_text || delete $samba->{$share}{printable};
				   $print_command->get_text and $samba->{$share}{'print command'} = $print_command->get_text || delete $samba->{$share}{'print command'};
				   $lpq_command->get_text and $samba->{$share}{'lpq command'} = $lpq_command->get_text || delete $samba->{$share}{'lpq command'};
				   $guest_ok->get_text and $samba->{$share}{'guest ok'} = $guest_ok->get_text || delete $samba->{$share}{'guest ok'};
				   $writable->get_text and $samba->{$share}{writable} = $writable->get_text || delete $samba->{$share}{writable};
				   $write_list->get_text and $samba->{$share}{'write list'} = $write_list->get_text || delete $samba->{$share}{'write list'};
				   $inherit_permissions->get_text and $samba->{$share}{'inherit permissions'} = $inherit_permissions->get_text || delete $samba->{$share}{'inherit permissions'};
				   $printing->get_text and $samba->{$share}{printing} = $printing->get_text || delete $samba->{$share}{printing};
				   $create_mode->get_text and $samba->{$share}{'create mode'} = $create_mode->get_text || delete $samba->{$share}{'create mode'};
				   $use_client_driver->get_text and $samba->{$share}{'use client driver'} = $use_client_driver->get_text || delete $samba->{$share}{'use client driver'};

				   # 
				   $dialog->destroy;
			       }
			      },
			     ),
	   );
  $dialog->show_all;
}

sub modify_entry {
  my ($selected) = @_;
  my ($dir, $comment, $create_mask, $directory_mask, $read_list, $write_list, $admin_users, $valid_users, $force_group, $browseable, $public, $writable, $hide_files, $hide_dot_files, $force_create_mode, $preserve_case, $default_case, $inherit_permissions, $share_name);

  $share_name = Gtk2::Label->new;
  $_ = Gtk2::Entry->new foreach $dir, $comment, $create_mask, $directory_mask, $hide_files;
  $_ = Gtk2::Entry->new foreach $read_list, $write_list, $admin_users, $valid_users, $force_group, $force_create_mode;
  $_ = Gtk2::OptionMenu->new foreach $browseable, $public, $writable, $default_case, $preserve_case, $hide_dot_files, $inherit_permissions;

  $default_case->set_popdown_strings(@default_case);
  $_->set_popdown_strings(@yesno) foreach $browseable, $public, $writable, $hide_dot_files, $preserve_case, $inherit_permissions;

  my $file_dialog = $fdwidget->($dir, "");
  my $button = Gtk2::Button->new_from_stock('gtk-open');
  $button->signal_connect(clicked => sub { $file_dialog->show });

  my $w = ugtk2->new(N("DrakSamba entry"));
  $w->{window}->set_modal(1);
  $w->{window}->set_position('center');

  my $s = $share_list->{data}[$selected][1];
  $s or info_dialog(N("Error"), N("Please add or select a Samba share to be able to modify it.")) and return;
  $share_name->set_text($s);
  $dir->set_text($share_list->{data}[$selected][2]);
  $comment->set_text($share_list->{data}[$selected][3]);
  $browseable->set_text($share_list->{data}[$selected][4]);
  $public->set_text($share_list->{data}[$selected][5]);
  $writable->set_text($share_list->{data}[$selected][6]);
  $create_mask->set_text($share_list->{data}[$selected][7]);
  $directory_mask->set_text($share_list->{data}[$selected][8]);
  $read_list->set_text($share_list->{data}[$selected][9]);
  $write_list->set_text($share_list->{data}[$selected][10]);
  $admin_users->set_text($share_list->{data}[$selected][11]);
  $valid_users->set_text($share_list->{data}[$selected][12]);
  $inherit_permissions->set_text($share_list->{data}[$selected][13]);
  $hide_dot_files->set_text($share_list->{data}[$selected][14]);
  $hide_files->set_text($share_list->{data}[$selected][15]);
  $preserve_case->set_text($share_list->{data}[$selected][16]);
  $force_create_mode->set_text($share_list->{data}[$selected][17]);
  $force_group->set_text($share_list->{data}[$selected][18]);
  $default_case->set_text($share_list->{data}[$selected][19]);

  my $expander_user = Gtk2::Expander->new('User options (user access, mask option, force mode)');
  $expander_user->add(gtkpack_(Gtk2::HBox->new,
			       0, gtkadd(Gtk2::Frame->new(N("Samba user access")),
					 gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
						  0, $label_and_widgets->($adv_options{read_list}, $read_list, ""),
						  0, $label_and_widgets->($adv_options{write_list}, $write_list, ""),
						  0, $label_and_widgets->($adv_options{admin_users}, $admin_users, ""),
						  0, $label_and_widgets->($adv_options{valid_users}, $valid_users, ""),
						  ),
					 ),
			       0, gtkadd(Gtk2::Frame->new(N("Mask options")),
					 gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
						  0, $label_and_widgets->($adv_options{create_mask}, $create_mask, ""),
						  0, $label_and_widgets->($adv_options{directory_mask}, $directory_mask, ""),
						  0, $label_and_widgets->($adv_options{force_group}, $force_group, ""),
						  0, $label_and_widgets->($adv_options{force_create_mode}, $force_create_mode, ""),
						  0, $label_and_widgets->($adv_options{inherit_permissions}, $inherit_permissions, ""),
						  ),
					 ),
			       ),
		      );
  
  my $expander_file = Gtk2::Expander->new('File options (hide files, case)');
  $expander_file->add(gtkpack_(Gtk2::VBox->new,
			       0, gtkadd(Gtk2::Frame->new(N("Display options")),
					 gtkpack_(gtkset_border_width(Gtk2::HBox->new, 1),
						  0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0),
							      0, $label_and_widgets->($adv_options{hide_dot_files}, $hide_dot_files, ""),
							      0, $label_and_widgets->($adv_options{hide_files}, $hide_files, ""),
							      ),
						  0, Gtk2::VSeparator->new,
						  0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0),
							      0, $label_and_widgets->($adv_options{default_case}, $default_case, ""),
							      0, $label_and_widgets->($adv_options{preserve_case}, $preserve_case, ""),
							      ),
						  ),
					 ),
			       ),
		      );

  $_->signal_connect(activate => sub {
		       $w->shrink_topwindow;
		     }) foreach $expander_file, $expander_user;

  gtkadd($w->{window},
	 gtknew('VBox', spacing => 0, children_loose => [
							 gtkadd(Gtk2::Frame->new(N("Samba share directory")),
								gtkpack_(gtkset_border_width(Gtk2::HBox->new, 1),
									 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0),
										     0, $label_and_widgets->(N("Share name:"), $share_name),
										     0, $label_and_widgets->(N("Directory:"), $dir, $button),
										     0, $label_and_widgets->(N("Comment:"), $comment, ""),
										     ),
									 0, Gtk2::VSeparator->new,
									 0, gtkpack_(gtkset_border_width(Gtk2::VBox->new, 0),
										     0, $label_and_widgets->(N("Public:"), $public, ""),
										     0, $label_and_widgets->(N("Writable:"), $writable, ""),
										     0, $label_and_widgets->(N("Browseable:"), $browseable, ""),
										    ),
									 ),
								),
							 gtkadd(Gtk2::Frame->new("Advanced options"),
								gtkpack_(gtkset_border_width(Gtk2::VBox->new, 1),
									 0, $expander_user,
									 0, Gtk2::HSeparator->new,
									 0, $expander_file,
									 ),
							       ),
							 create_okcancel({
							     cancel_clicked => sub { $w->destroy },
							     ok_clicked => sub {
 							       my $share = $share_name->get_text;
							       my $test_dir = $dir->get_text;
							       $comment->get_text or err_dialog(N("Information"), N("Please enter a Comment for this share.")) and return 1;
							       if ($share !~ /^homes$/ and !-d $test_dir) {
								   err_dialog(N("Error!"), N("Please enter a directory to share.")) and return;
							       }
							       foreach ($create_mask->get_text, $directory_mask->get_text) {
								   if ($_ && !/^\d+$/) {
								       err_dialog(N("Error"), N("Create mask, create mode and directory mask should be numeric. ie: 0755.")) and return 1;
								   }
							       }
							       foreach ($read_list->get_text, $write_list->get_text, $admin_users->get_text, $valid_users->get_text) {
								 my @users = split(" ", $_);
								 foreach my $user (@users) {
								   if (!any { /^$user:/ } cat_("/etc/samba/smbpasswd") and !/\@/) {
								     err_dialog(N("Error"), N("Please create this Samba user: %s", $user)) and return;
								   }
								 }
							       }
							       # update gui SimpleList
                                                               remove_entry($selected, $share_list);
							       push @{$share_list->{data}}, [
											     $pixbuf_file,
											     $share_name->get_text,
											     $dir->get_text,
											     $comment->get_text,
											     $browseable->get_text,
											     $public->get_text,
											     $writable->get_text,
											     $create_mask->get_text,
											     $directory_mask->get_text,
											     $read_list->get_text,
											     $write_list->get_text,
											     $admin_users->get_text,
											     $valid_users->get_text,
											     $hide_dot_files->get_text,
											     $hide_files->get_text,
											     $preserve_case->get_text,
											     $force_create_mode->get_text,
											     $force_group->get_text,
											     $default_case->get_text,
											     $inherit_permissions->get_text,
											    ];
							       # update $samba with the new value
							       # $samba->{$share};
							       $samba->{$share}{path} = $dir->get_text;
							       $samba->{$share}{comment} = $comment->get_text;
							       $browseable->get_text and $samba->{$share}{browseable} = $browseable->get_text || delete $samba->{$share}{browseable};
							       $public->get_text and $samba->{$share}{public} = $public->get_text || delete $samba->{$share}{public};
							       $writable->get_text and $samba->{$share}{writable} = $writable->get_text || delete $samba->{$share}{writable};
							       $create_mask->get_text and $samba->{$share}{'create mask'} = $create_mask->get_text || delete $samba->{$share}{'create mask'};
							       $directory_mask->get_text and $samba->{$share}{'directory mask'} = $directory_mask->get_text || delete $samba->{$share}{'directory mask'};
							       $read_list->get_text and $samba->{$share}{'read list'} = $read_list->get_text || delete $samba->{$share}{'read list'};
							       $write_list->get_text and $samba->{$share}{'write list'} = $write_list->get_text || delete $samba->{$share}{'write list'};
							       $admin_users->get_text and $samba->{$share}{'admin users'} = $admin_users->get_text || delete $samba->{$share}{'admin users'};
							       $valid_users->get_text and $samba->{$share}{'valid users'} = $valid_users->get_text || delete $samba->{$share}{'valid users'};
							       $hide_dot_files->get_text and $samba->{$share}{'hide dot files'} = $hide_dot_files->get_text || delete $samba->{$share}{'hide dot files'};
							       $hide_files->get_text and $samba->{$share}{'hide files'} = $hide_files->get_text || delete $samba->{$share}{'hide files'};
							       $preserve_case->get_text and $samba->{$share}{'preserve case'} = $preserve_case->get_text || delete $samba->{$share}{'preserve case'};
							       $force_create_mode->get_text and $samba->{$share}{'force create mode'} = $force_create_mode->get_text || delete $samba->{$share}{'force create mode'};
							       $force_group->get_text and $samba->{$share}{'force group'} = $force_group->get_text || delete $samba->{$share}{'force group'};
							       $default_case->get_text and $samba->{$share}{'default case'} = $default_case->get_text || delete $samba->{$share}{'default case'};
							       $inherit_permissions->get_text and $samba->{$share}{'inherit permissions'} = $inherit_permissions->get_text || delete $samba->{$share}{'inherit permissions'};

							       # update listshare
							       push @listshare, {
										 share_name => $share,
										 path => $samba->{$share}{path},
										 comment => $samba->{$share}{comment},
										 browseable => $samba->{$share}{browseable},
										 public => $samba->{$share}{public},
										 writable => $samba->{$share}{writable},
										 create_mask => $samba->{$share}{'create mask'},
										 directory_mask => $samba->{$share}{'directory mask'},
										 read_list => $samba->{$share}{'read list'},
										 write_list => $samba->{$share}{'write list'},
										 admin_users => $samba->{$share}{'admin users'},
										 valid_users => $samba->{$share}{'valid users'},
										 hide_dot_files => $samba->{$share}{'hide dot files'},
										 hide_files => $samba->{$share}{'hide files'},
										 preserve_case => $samba->{$share}{'preserve case'},
										 force_create_mode => $samba->{$share}{'force create mode'},
										 force_group => $samba->{$share}{'force group'},
										 default_case => $samba->{$share}{'default case'},
										 inherit_permissions => $samba->{$share}{'inherit permissions'},
										};
							       $w->destroy;
							     },
									 },
									),
							]
	       ),
	);
  $w->{window}->show_all;
}

sub remove_entry {
  my ($selected, $list) = @_;
  my $share_name = $list->{data}[$selected][1];
  splice @{$list->{data}}, $selected, 1;
  delete $samba->{$share_name};
}

sub remove_user {
  my ($user) = @_;
  system("smbpasswd -x $user");
}

sub get_user() {
  my $conf = "/etc/passwd";
  my @data; local $_;
  foreach (cat_($conf)) {
      push @data, $1 if m/^([^#:]+):[^:]+:([^:]+):/ and $2 > 499;
  }
  push @data, " ";
  return sort(@data);
}


sub modify_user_info {
  my ($user, $passwd, $todo) = @_;
  my ($buser, $bpasswd);
  my $dialog = new Gtk2::Dialog();
  $dialog->set_title("Add Samba user");
  $dialog->set_modal(1);
  $dialog->set_position('center');
  $dialog->set_resizable(0);
  if ($todo eq "add") {
    $buser = Gtk2::ComboBox->new_with_strings([ get_user() ]);
    $buser->set_wrap_width(3);
  } else {
    $buser = Gtk2::Label->new;
    $buser->set_text($user);
  }
  $bpasswd = Gtk2::Entry->new;
  $bpasswd->set_visibility(0);

  gtkpack_($dialog->vbox,
           0, gtkadd(Gtk2::Frame->new(N("User information")),
                     gtkpack_(gtkset_border_width(Gtk2::VBox->new, 5),
                              0, $label_and_widgets->(N("User name:"), $buser, ""),
                              0, $label_and_widgets->(N("Password:"), $bpasswd, ""),
                             ),
                    ),
	   0, create_okcancel({
			    cancel_clicked => sub { $dialog->destroy },
			       ok_clicked => sub {
				 my $user_selected = $buser->get_text;
				 if ($todo eq "add") {
				   if (any { /^$user_selected:/ } cat_("/etc/samba/smbpasswd")) {
				     err_dialog(N("Error"), ("Samba User already exist")) and return;
				   }
				   system("smbpasswd -a $user_selected -n");
				   push @{$user_list->{data}}, [
								$pixbuf_user,
								$user_selected,
							       ];
				   push @listusers, {
						     user_name => $user_selected,
						    };
				 }
				 my $passwd_e = $bpasswd->get_text;
				 set_user_passwd($user_selected, $passwd_e);
				 $dialog->destroy;
			       }
			      },
			     ),
	  );
  $dialog->show_all;
}

sub set_user_passwd {
  my ($user, $passwd) = @_;
  my $F;
  open($F, '|' . qq(smbpasswd $user -s));
  print $F "$passwd\n";
  print $F "$passwd\n";
  close $F;
}

sub add_data_share_list {
  my ($share_list) = @_;
  get_samba_share();

  foreach my $data (@listshare) {
    push @{$share_list->{data}}, [
				  $pixbuf_file,
				  $data->{share_name},
				  $data->{path},
				  $data->{comment},
				  $data->{browseable},
				  $data->{public},
				  $data->{writable},
				  $data->{create_mask},
				  $data->{directory_mask},
				  $data->{read_list},
				  $data->{write_list},
				  $data->{admin_users},
				  $data->{valid_users},
				  $data->{inherit_permissions},
				  $data->{hide_dot_files},
				  $data->{hide_files},
				  $data->{preserve_case},
				  $data->{force_create_mode},
				  $data->{force_group},
				  $data->{default_case},
				 ];
  }
}

sub add_data_user_list {
  my ($user_list) = @_;
  get_samba_user();
  foreach my $data (@listusers) {
    push @{$user_list->{data}}, [
				 $pixbuf_user,
				 $data->{user_name},
				];
  }
}

sub add_data_printer_list {
  my ($printer_list) = @_;
  get_samba_printers();
  foreach my $data (@listprinters) {
    push @{$printer_list->{data}}, [
				    $pixbuf_printer,
				    $data->{share_name},
				    $data->{path},
				    $data->{comment},
				    $data->{browseable},
				    $data->{printable},
				    $data->{print_command},
				    $data->{lpq_command},
				    $data->{guest_ok},
				    $data->{writable},
				    $data->{write_list},
				    $data->{inherit_permissions},
				    $data->{printing},
				    $data->{create_mode},
				    $data->{use_client_driver},
				   ];
  }
}

###############
# Main Program
###############
# create model
add_data_share_list($share_list);
add_data_printer_list($printer_list);
add_data_user_list($user_list);
$_->set_rules_hint(1) foreach $share_list, $printer_list, $user_list;

my $window = ugtk2->new("DrakSamba");
$::main_window = $window->{real_window};
$window->{rwindow}->set_size_request(600, 410) unless $::isEmbedded;
$window->{rwindow}->set_position('center') if !$::isEmbedded;
my $W = $window->{window};
$W->signal_connect(delete_event => sub { ugtk2->exit });

# double clic and popup modify window
$share_list->signal_connect(button_press_event => sub {
			      my (undef, $event) = @_;
			      my ($selected) = $share_list->get_selected_indices;
			      $share_list->{data}[$selected][1] and modify_entry($selected) if $event->type eq '2button-press';
			    });

$printer_list->signal_connect(button_press_event => sub {
				my (undef, $event) = @_;
				my ($selected) = $printer_list->get_selected_indices;
				$printer_list->{data}[$selected][1] and modify_printers_entry($selected) if $event->type eq '2button-press';
			      });

$user_list->signal_connect(button_press_event => sub {
				my (undef, $event) = @_;
				my ($selected) = $user_list->get_selected_indices;
				$user_list->{data}[$selected][1] and modify_user_info($user_list->{data}[$selected][1], "", "change") if $event->type eq '2button-press';
			      });

# dont know why "$event->type eq '2button-press'" when starting draksambashare so i can't use mapn :/
#mapn {
#    $_[0]->signal_connect(button_press_event => sub {
#	my (undef, $event) = @_;
#	my ($selected) = $_[0]->get_selected_indices;
#	return unless $event->type eq '2button-press';
#	$_[0]->{data}[$selected][1] and $_[1]($selected); # if $event->type eq '2button-press';
#    });
#} [ $share_list, $printer_list, $user_list ], [ modify_entry, modify_printers_entry, modify_user_info ];

# create popup menu
my $menupopup = Gtk2::Menu->new;
my $menuitem1 = Gtk2::MenuItem->new(N("Modify"));
my $menuitem2 = Gtk2::MenuItem->new(N("Remove"));
$menuitem1->signal_connect(activate => sub {
			     my ($selected) = $share_list->get_selected_indices;
			     modify_entry($selected, $share_list);
			   });
$menuitem2->signal_connect(activate => sub {
			     my ($selected) = $share_list->get_selected_indices;
			     ask_okcancel("Remove entry ?", "Remove $share_list->{data}[$selected][1]") or return;
			     remove_entry($selected, $share_list);
			   });
$_->show foreach $menuitem1, $menuitem2;
$menupopup->append($_) foreach $menuitem1, $menuitem2;
$share_list->signal_connect('button-press-event' => sub {
			      my ($widget, $event) = @_;
			      return unless $event->button == 3;
			      $menupopup->popup(undef, undef, undef, undef, $event->button, $event->time);
			    }
			   );

$share_list->signal_connect(key_press_event => sub {
    my ($widget, $event) = @_;
    return unless $event->keyval == $Gtk2::Gdk::Keysyms{Return};
    my ($selected) = $share_list->get_selected_indices;
    modify_entry($selected, $share_list);
    return 1;
});

# create menu
my @items = get_items();
my $factory = Gtk2::ItemFactory->new('Gtk2::MenuBar', '<main>', undef);
$factory->create_items('menu', @items);
my $menu = $factory->get_widget('<main>');

my $okcancel = create_okcancel({
				cancel_clicked => sub { ugtk2->exit },
				ok_clicked => sub { &write_conf; ugtk2->exit },
			       },
			      );

gtkappend_page(my $nb = Gtk2::Notebook->new, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0),
                                                      1, create_scrolled_window($share_list),
						      0, gtkpack_(create_vbox('start'),
								  0, gtksignal_connect(Gtk2::Button->new(N("Add")), clicked => sub {
											 eval { add_entry() };
											 my $err = $@;
											 $::WizardWindow->destroy if defined $::WizardWindow;
											 undef $::WizardWindow;
											 if ($err && $err !~ /wizcancel/) {
											   err_dialog(N("Error"), N("Failed to add Samba share.") . "\n\n" . $err);
											 }
										       }),
								  0, Gtk2::HSeparator->new,
								  0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub {
											 my ($selected) = $share_list->get_selected_indices;
											 eval { modify_entry($selected, $share_list) };
											 my $err = $@;
											 if ($err) {
											   err_dialog(N("Error"), N("Failed to Modify Samba share.") . "\n\n" . $err);
											 }
										       }),
								  0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub {
											 my ($selected) = $share_list->get_selected_indices;
											 ask_okcancel("Remove entry ?", "Remove $share_list->{data}[$selected][1]") or return;
											 eval { remove_entry($selected, $share_list) };
											 my $err = $@;
											 if ($err) {
											   err_dialog(N("Error"), N("Failed to remove a Samba share.") . "\n\n" . $err);
											 }
										       }),
								 ),
						     ),
               gtkshow(gtkpack_(Gtk2::HBox->new(0,0),
				0, Gtk2::Image->new_from_file($fileshare_icon),
				0, Gtk2::Label->new(N("File share")),
			       ),
		      ),
	      );

gtkappend_page($nb, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0),
			     1, create_scrolled_window($printer_list),
                             0, gtkpack_(create_vbox('start'),
					 0, gtksignal_connect(Gtk2::Button->new(N("Add printers")), clicked => sub {
                                                                eval { add_printers_entry() };
                                                                my $err = $@;
								$::WizardWindow->destroy if defined $::WizardWindow;
								undef $::WizardWindow;
								if ($err && $err !~ /wizcancel/) {
                                                                  err_dialog(N("Error"), N("Failed to add printers.") . "\n\n" . $err);
                                                                }
                                                              }),
                                         0, Gtk2::HSeparator->new,
                                         0, gtksignal_connect(Gtk2::Button->new(N("Modify")), clicked => sub {
								my ($selected) = $printer_list->get_selected_indices;
                                                                eval { modify_printers_entry($selected) };
                                                                my $err = $@;
                                                                if ($err) {
                                                                  err_dialog(N("Error"), N("Failed to Modify.") . "\n\n" . $err);
                                                                }
                                                              }),
                                         0, gtksignal_connect(Gtk2::Button->new(N("Remove")), clicked => sub {
								my ($selected) = $printer_list->get_selected_indices;
								ask_okcancel("Remove entry ?", "Remove $printer_list->{data}[$selected][1]") or return;
                                                                eval { remove_entry($selected, $printer_list) };
                                                                my $err = $@;
                                                                if ($err) {
                                                                  err_dialog(N("Error"), N("Failed to remove.") . "\n\n" . $err);
                                                                }
                                                              }),
					),
			    ),
	       gtkshow(gtkpack_(Gtk2::HBox->new(0,0),
				0, Gtk2::Image->new_from_file($printershare_icon),
				0, Gtk2::Label->new(N("Printers")),
			       ),
		      ),
	      );

gtkappend_page($nb, gtkpack_(gtkset_border_width(Gtk2::HBox->new, 0),
			     1, create_scrolled_window($user_list),
                             0, gtkpack_(create_vbox('start'),
					 0, gtksignal_connect(Gtk2::Button->new(N("Change password")), clicked => sub {
								my ($selected) = $user_list->get_selected_indices;
                                                                eval { modify_user_info($user_list->{data}[$selected][1], "", "change") };
                                                                my $err = $@;
								if ($err) {
                                                                  err_dialog(N("Error"), N("Failed to change user password.") . "\n\n" . $err);
                                                                }
                                                              }),
                                         0, Gtk2::HSeparator->new,
                                         0, gtksignal_connect(Gtk2::Button->new(N("Add user")), clicked => sub {
                                                                eval { modify_user_info("", "", "add") };
                                                                my $err = $@;
                                                                if ($err) {
                                                                  err_dialog(N("Error"), N("Failed to add user.") . "\n\n" . $err);
                                                                }
                                                              }),
					 0, gtksignal_connect(Gtk2::Button->new(N("Delete user")), clicked => sub {
								my ($selected) = $user_list->get_selected_indices;
								ask_okcancel("Remove entry ?", "Remove $user_list->{data}[$selected][1]") or return;
                                                                eval {
								  remove_user($user_list->{data}[$selected][1]);
								  remove_entry($selected, $user_list);
								};
                                                                my $err = $@;
                                                                if ($err) {
                                                                  err_dialog(N("Error"), N("Failed to delete user.") . "\n\n" . $err);
                                                                }
                                                              }),
                                         0, Gtk2::HSeparator->new,
					 0, gtksignal_connect(Gtk2::Button->new(N("Userdrake")), clicked => sub {
								run_program::raw({ detach => 1 }, 'userdrake');
							      }
							     ),
					),
			    ),
               gtkshow(gtkpack_(Gtk2::HBox->new(0,0),
				0, Gtk2::Image->new_from_file($sambauser_icon),
				0, Gtk2::Label->new(N("Samba Users"))),
		      ),
	      );

$nb->set_show_border(0);

# main interface
$W->add(gtkpack_(Gtk2::VBox->new(0,0),
		 0, $menu,
		 if_(!$::isEmbedded, 0, Gtk2::Banner->new('IC-winacces1-48', N("DrakSamba manage Samba shares"))),
		 #if_($::isEmbedded, 0, Gtk2::Label->new("Here you can add, remove and alter Samba shares.")),
		 1, $nb,
		 0, $okcancel,
		 ),
	);

$W->show_all;
Gtk2->main;