summaryrefslogtreecommitdiffstats
path: root/perl-install/diskdrake/smbnfs_gtk.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/diskdrake/smbnfs_gtk.pm')
-rw-r--r--perl-install/diskdrake/smbnfs_gtk.pm271
1 files changed, 271 insertions, 0 deletions
diff --git a/perl-install/diskdrake/smbnfs_gtk.pm b/perl-install/diskdrake/smbnfs_gtk.pm
new file mode 100644
index 000000000..53c69295a
--- /dev/null
+++ b/perl-install/diskdrake/smbnfs_gtk.pm
@@ -0,0 +1,271 @@
+package diskdrake::smbnfs_gtk; # $Id: smbnfs_gtk.pm 88802 2006-11-29 21:37:52Z blino $
+
+use diagnostics;
+use strict;
+
+use fs::get;
+use diskdrake::interactive;
+use common;
+use interactive;
+use fs::remote::smb;
+use fs::remote::nfs;
+use mygtk2 qw(gtknew gtkset);
+use ugtk2 qw(:helpers :wrappers :create);
+
+my ($all_hds, $in, $tree_model, $current_entry, $current_leaf, %icons);
+
+sub main {
+ ($in, $all_hds, my $type) = @_;
+ my ($kind) = $type eq 'smb' ? smb2kind() : nfs2kind();
+ $kind->check($in) or return;
+
+ my $w = ugtk2->new(N("Partitioning"), icon => 'banner-part');
+
+ add_smbnfs($w->{window}, $kind);
+ $w->{rwindow}->set_default_size(400, 300) if $w->{rwindow}->can('set_default_size');
+ $w->{window}->show_all;
+ $w->main;
+}
+
+################################################################################
+# nfs/smb: helpers
+################################################################################
+sub try {
+ my ($kind, $name, @args) = @_;
+ my $f = $diskdrake::interactive::{$name} or die "unknown function $name";
+ try_($kind, $name, \&$f, @args);
+}
+sub try_ {
+ my ($kind, $name, $f, @args) = @_;
+ eval { $f->($in, @args, $all_hds) };
+ if (my $err = $@) {
+ $in->ask_warn(N("Error"), formatError($err));
+ }
+ update($kind);
+ Gtk2->main_quit if member($name, 'Cancel', 'Done');
+}
+
+sub raw_hd_options {
+ my ($in, $raw_hd) = @_;
+ diskdrake::interactive::Options($in, {}, $raw_hd, fs::get::empty_all_hds());
+}
+sub raw_hd_mount_point {
+ my ($in, $raw_hd) = @_;
+ my ($default) = $raw_hd->{device} =~ m|([^/]+)$|;
+ $default =~ s/\s+/-/g;
+ diskdrake::interactive::Mount_point_raw_hd($in, $raw_hd, $all_hds, "/mnt/$default");
+}
+
+sub per_entry_info_box {
+ my ($box, $kind, $entry) = @_;
+ my $info = $entry ? diskdrake::interactive::format_raw_hd_info($entry) : '';
+ $kind->{per_entry_info_box}->destroy if $kind->{per_entry_info_box};
+ gtkpack($box, $kind->{per_entry_info_box} = gtknew('Frame', text => N("Details"), child => gtknew('Label', text => $info, justify => 'left')));
+}
+
+sub per_entry_action_box {
+ my ($box, $kind, $entry) = @_;
+ $_->destroy foreach $box->get_children;
+
+ my @buttons;
+
+ push @buttons, map {
+ my $s = $_;
+ gtknew('Button', text => translate($s), clicked => sub { try($kind, $s, {}, $entry) });
+ } (if_($entry->{isMounted}, N_("Unmount")),
+ if_($entry->{mntpoint} && !$entry->{isMounted}, N_("Mount"))) if $entry;
+
+ my @l = (
+ if_($entry, N_("Mount point") => \&raw_hd_mount_point),
+ if_($entry && $entry->{mntpoint}, N_("Options") => \&raw_hd_options),
+ N_("Cancel") => sub {},
+ N_("Done") => \&done,
+ );
+ push @buttons, map {
+ my ($txt, $f) = @$_;
+ $f ? gtknew('Button', text => translate($txt), clicked => sub { try_($kind, $txt, $f, $entry) })
+ : gtknew('Label', text => "");
+ } group_by2(@l);
+
+ gtkadd($box, gtknew('HBox', children_loose => [ @buttons]));
+}
+
+sub done {
+ my ($in) = @_;
+ diskdrake::interactive::Done($in, $all_hds);
+}
+
+sub export_icon {
+ my ($entry) = @_;
+ $entry ||= {};
+ $icons{$entry->{isMounted} ? 'mounted' : $entry->{mntpoint} ? 'has_mntpoint' : 'default'};
+}
+
+sub update {
+ my ($kind) = @_;
+ per_entry_action_box($kind->{action_box}, $kind, $current_entry);
+ per_entry_info_box($kind->{info_box}, $kind, $current_entry);
+ $tree_model->set($current_leaf, 0 => export_icon($current_entry)) if $current_entry;
+}
+
+sub find_fstab_entry {
+ my ($kind, $e, $b_add_or_not) = @_;
+
+ my $fs_entry = $kind->to_fstab_entry($e);
+
+ if (my $fs_entry_ = find { $fs_entry->{device} eq $_->{device} } @{$kind->{val}}) {
+ $fs_entry_;
+ } elsif ($b_add_or_not) {
+ push @{$kind->{val}}, $fs_entry;
+ $fs_entry;
+ } else {
+ undef;
+ }
+}
+
+sub import_tree {
+ my ($kind, $info_box) = @_;
+ my (%servers_displayed, %wservers, %wexports);
+
+ $tree_model = Gtk2::TreeStore->new("Gtk2::Gdk::Pixbuf", "Glib::String");
+ my $tree = Gtk2::TreeView->new_with_model($tree_model);
+ $tree->get_selection->set_mode('browse');
+
+ my $col = Gtk2::TreeViewColumn->new;
+ $col->pack_start(my $pixrender = Gtk2::CellRendererPixbuf->new, 0);
+ $col->add_attribute($pixrender, 'pixbuf', 0);
+ $col->pack_start(my $texrender = Gtk2::CellRendererText->new, 1);
+ $col->add_attribute($texrender, 'text', 1);
+ $tree->append_column($col);
+
+ $tree->set_headers_visible(0);
+
+ foreach ('default', 'server', 'has_mntpoint', 'mounted') {
+ $icons{$_} = gtknew('Pixbuf', file => "smbnfs_$_");
+ }
+
+ my $add_server = sub {
+ my ($server) = @_;
+ my $identifier = $server->{ip} || $server->{name};
+ my $name = $server->{name} || $server->{ip};
+ $servers_displayed{$identifier} ||= do {
+ my $w = $tree_model->append_set(undef, [ 0 => $icons{server}, 1 => $name ]);
+ $wservers{$tree_model->get_path_str($w)} = $server;
+ $w;
+ };
+ };
+
+ my $find_exports; $find_exports = sub {
+ my ($server) = @_;
+ my @l = eval { $kind->find_exports($server) };
+ return @l if !$@;
+
+ if ($server->{username}) {
+ $in->ask_warn('', N("Can not login using username %s (bad password?)", $server->{username}));
+ fs::remote::smb::remove_bad_credentials($server);
+ } else {
+ if (my @l = fs::remote::smb::authentications_available($server)) {
+ my $user = $in->ask_from_list_(N("Domain Authentication Required"),
+ N("Which username"), [ @l, N_("Another one") ]) or return;
+ if ($user ne 'Another one') {
+ fs::remote::smb::read_credentials($server, $user);
+ goto $find_exports;
+ }
+ }
+ }
+
+ if ($in->ask_from(N("Domain Authentication Required"),
+ N("Please enter your username, password and domain name to access this host."),
+ [
+ { label => N("Username"), val => \$server->{username} },
+ { label => N("Password"), val => \$server->{password}, hidden => 1 },
+ { label => N("Domain"), val => \$server->{domain} },
+ ])) {
+ goto $find_exports;
+ } else {
+ delete $server->{username};
+ ();
+ }
+ };
+
+ my $add_exports = sub {
+ my ($node) = @_;
+
+ my $path = $tree_model->get_path($node);
+ $tree->expand_row($path, 0);
+
+ foreach ($find_exports->($wservers{$tree_model->get_path_str($node)} || return)) { #- can not die here since insert_node provoque a tree_select_row before the %wservers is filled
+ my $s = $kind->to_string($_);
+ my $w = $tree_model->append_set($node, [ 0 => export_icon(find_fstab_entry($kind, $_)),
+ 1 => $s ]);
+ $wexports{$tree_model->get_path_str($w)} = $_;
+ }
+ };
+
+ {
+ my $search = gtknew('Button', text => N("Search servers"));
+ gtkpack__($info_box,
+ gtksignal_connect($search,
+ clicked => sub {
+ $add_server->($_) foreach sort { $a->{name} cmp $b->{name} } $kind->find_servers;
+ gtkset($search, text => N("Search new servers"));
+ }));
+ }
+
+ foreach (uniq(map { ($kind->from_dev($_->{device}))[0] } @{$kind->{val}})) {
+ my $node = $add_server->({ name => $_ });
+ $add_exports->($node);
+ }
+
+ $tree->get_selection->signal_connect(changed => sub {
+ my ($_model, $curr) = $_[0]->get_selected;
+ $curr or return;
+
+ if ($tree_model->iter_parent($curr)) {
+ $current_leaf = $curr;
+ $current_entry = find_fstab_entry($kind, $wexports{$tree_model->get_path_str($curr)} || die(''), 'add');
+ } else {
+ if (!$tree_model->iter_has_child($curr)) {
+ gtkset_mousecursor_wait($tree->window);
+ ugtk2::flush();
+ $add_exports->($curr);
+ gtkset_mousecursor_normal($tree->window);
+ }
+ $current_entry = undef;
+ }
+ update($kind);
+ });
+ $tree;
+}
+
+sub add_smbnfs {
+ my ($widget, $kind) = @_;
+ die if $kind->{main_box};
+
+ $kind->{info_box} = gtknew('VBox');
+ $kind->{display_box} = gtknew('ScrolledWindow', child => import_tree($kind, $kind->{info_box}));
+ $kind->{action_box} = gtknew('HBox');
+ $kind->{main_box} =
+ gtknew('VBox', spacing => 7, children => [
+ 1, gtknew('HBox', spacing => 7, children_loose => [
+ gtkset($kind->{display_box}, width => 200),
+ $kind->{info_box}]),
+ 0, $kind->{action_box},
+ ]);
+
+ $widget->add($kind->{main_box});
+ $current_entry = undef;
+ update($kind);
+ $kind;
+}
+
+sub nfs2kind() {
+ fs::remote::nfs->new({ type => 'nfs', name => 'NFS', val => $all_hds->{nfss}, no_auto => 1 });
+}
+
+sub smb2kind() {
+ fs::remote::smb->new({ type => 'smb', name => 'Samba', val => $all_hds->{smbs}, no_auto => 1 });
+}
+
+
+1;