diff options
Diffstat (limited to 'perl-install/interactive_newt.pm')
-rw-r--r-- | perl-install/interactive_newt.pm | 439 |
1 files changed, 204 insertions, 235 deletions
diff --git a/perl-install/interactive_newt.pm b/perl-install/interactive_newt.pm index dc21c27e2..b6d5823a3 100644 --- a/perl-install/interactive_newt.pm +++ b/perl-install/interactive_newt.pm @@ -8,252 +8,221 @@ use vars qw(@ISA); use interactive; use common qw(:common :functional); -use log; -use Newt::Newt; #- !! provides Newt and not Newt::Newt - -my $width = 80; -my $height = 25; -my @wait_messages; - -sub new() { - Newt::Init; - Newt::Cls; - Newt::SetSuspendCallback; - open STDERR,">/dev/null" if $::isStandalone; - bless {}, $_[0]; -} - -sub suspend { Newt::Suspend } -sub resume { Newt::Resume } -sub end() { Newt::Finished } -sub exit() { end; exit($_[0]) } -END { end() } - -sub myTextbox { - my @l = map { split "\n" } @_; - my $mess = Newt::Component::Textbox(1, 0, my $w = max(map { length } @l) + 1, my $h = @l, 1 << 6); - $mess->TextboxSetText(join("\n", @_)); - $mess, $w + 1, $h; -} - -sub separator($$) { - my $blank = Newt::Component::Form(\undef, '', 0); - $blank->FormSetWidth ($_[0]); - $blank->FormSetHeight($_[1]); - $blank; -} -sub checkval($) { $_[0] && $_[0] ne ' ' ? '*' : ' ' } - +use Term::Newt; + +my $n = Term::Newt->new; +$n->init; +$n->cls; + +#sub ask_from_entryW { +# my ($o, $title, $messages, $def) = @_; +# my $w = my_gtk->new($title, %$o); +# $w->_ask_from_entry(@$messages); +# $w->main; +#} sub ask_from_listW { my ($o, $title_, $messages, $l, $def) = @_; my ($title, @okcancel) = ref $title_ ? @$title_ : ($title_, _("Ok"), _("Cancel")); - my $mesg = join("\n", @$messages); - my $len = 0; $len += length($_) foreach @$l; if (@$l == 1) { - Newt::WinMessage($title, @$l, $mesg); + $n->win_message($title, @$l, $mesg); $l->[0]; -#- because newt will not try to remove window if bigger than screen ! - } elsif (@$l == 2 && $len < 64) { - $l->[Newt::WinChoice($title, @$l, $mesg) - 1]; -#- because newt will not try to remove window if bigger than screen ! - } elsif (@$l == 3 && $len < 64) { - $l->[Newt::WinTernary($title, @$l, $mesg) - 1]; + } elsif (@$l == 2) { + $l->[$n->win_choice($title, @$l, $mesg) - 1]; + } elsif (@$l == 3) { + $l->[$n->win_ternary($title, @$l, $mesg) - 1]; } else { - my $special = !@okcancel; - if ($special) { - $l = [ @$l ]; - @okcancel = pop @$l; - } my $i; map_index { $i = $::i if $def eq $_ } @$l; - my ($r, $e) = Newt::WinMenu($title, $mesg, 40, 5, 5, 8, $l, $i, @okcancel); - $r > 1 and die "ask_from_list cancel"; - if ($special) { - $r ? $okcancel[0] : $l->[$e]; - } else { - $l->[$e]; - } + print STDERR "($i)\n"; + my ($r, $e) = $n->newtWinMenu($title, $mesg, 40, 5, 5, 8, $l, $i, @okcancel); + return if $r > 1; + $l->[$e]; } } -sub ask_many_from_list_with_help_refW { - my ($o, $title, $messages, @lists) = @_; - my ($list) = map { $_->[0] } @lists; - my ($val) = map { $_->[2] } @lists; - my $height = min(int @$list, 18); - - my $sb = Newt::Component::VerticalScrollbar(-1, -1, $height, 9, 10); - my $checklist = $sb->Form('', 0); - $checklist->FormSetHeight($height); - $checklist->FormSetBackground(9); - - my @l = map_index { - Newt::Component::Checkbox(1, $::i + 1, $_, checkval(${$val->[$::i]} ||= ''), " *"); - } @$list; - $checklist->FormAddComponent($_) foreach @l; - - my $listg = Newt::Grid::HCloseStacked($checklist, $height < @$list ? (separator(1, $height), $sb) : ()); - - my ($buttons, $ok, $cancel) = Newt::Grid::ButtonBar(_("Ok"), _("Cancel")); - - my $form = Newt::Component::Form(\undef, '', 0); - my $window = Newt::Grid::GridBasicWindow(first(myTextbox(@$messages)), $listg, $buttons); - $window->GridWrappedWindow($title); - $window->GridAddComponentsToForm($form, 1); - my $r = $form->RunForm; - - $form->FormDestroy; - Newt::PopWindow; - - $$r == $$cancel and return; - - mapn { - my ($a, $b) = @_; - $$a = $b->CheckboxGetValue == ord '*'; - } $val, \@l; - - 1; -} - - -sub ask_from_entries_refW { - my ($o, $title, $messages, $l, $val, %hcallback) = @_; - my ($title_, @okcancel) = deref($title); - my $ignore; #-to handle recursivity - my $old_focus = -2; - - #-the widgets - my @widgets = map { -#- $_->{type} = "entry" if $_->{type} eq "list" && !$_->{not_edit}; - ${$_->{val}} ||= ''; - if ($_->{type} eq "list") { - my $w = Newt::Component::Listbox(-1, -1, 1, 0); - $w->ListboxSetWidth(20); - $w->ListboxAddEntry($_) foreach @{$_->{list}}; - $w; - } elsif ($_->{type} eq "bool") { - Newt::Component::Checkbox(-1, -1, $_->{text} || '', checkval(${$_->{val}}), " *"); - } else { - Newt::Component::Entry(-1, -1, '', 20, ($_->{hidden} && 1 << 1) | 1 << 2); - } - } @$val; - - my @updates = mapn { - my ($w, $ref) = @_; - sub { - ${$ref->{val}} = - $ref->{type} eq "bool" ? - $w->CheckboxGetValue == ord '*' : - $ref->{type} eq "list" ? - $w->ListboxGetCurrent : - $w->EntryGetValue; - }; - } \@widgets, $val; - - my @updates_inv = mapn { - my ($w, $ref) = @_; - sub { - my $val = ${$ref->{val}}; - $ignore = 1; - if ($ref->{type} eq "bool") { - $w->CheckboxSetValue(checkval($val)); - } elsif ($ref->{type} eq "list") { - map_index { - $w->ListboxSetCurrent($::i) if $val eq $_; - } @{$ref->{list}}; - } else { - $w->EntrySet($val, 1); - } - $ignore = 0; - }; - } \@widgets, $val; - - &$_ foreach @updates_inv; - - #- !! callbacks must be kept in a list otherwise perl will free them !! - #- (better handling of addCallback needed) - my @callbacks = map_index { - my $ind = $::i; - sub { - return if $ignore; #-handle recursive deadlock - return $old_focus++ if $old_focus == -2; #- handle special first case - - &$_ foreach @updates; - - #- TODO: this is very rough :( - if ($old_focus == $ind) { - $hcallback{changed}->($ind) if $hcallback{changed}; - } else { - $hcallback{focus_out}->($ind) if $hcallback{focus_out}; - } - &$_ foreach @updates_inv; - $old_focus = $ind; - }; - } @widgets; - map_index { $_->addCallback($callbacks[$::i]) } @widgets; - - my $grid = Newt::Grid::CreateGrid(3, int @$l); - map_index { - $grid->GridSetField(0, $::i, 1, ${Newt::Component::Label(-1, -1, $_)}, 0, 0, 1, 0, 1, 0); - $grid->GridSetField(1, $::i, 1, ${$widgets[$::i]}, 0, 0, 0, 0, 1, 0); - } @$l; - - my ($buttons, $ok, $cancel) = Newt::Grid::ButtonBar(@okcancel); - - my $form = Newt::Component::Form(\undef, '', 0) or die; - my $window = Newt::Grid::GridBasicWindow(first(myTextbox(@$messages)), $grid, $buttons); - $window->GridWrappedWindow($title_); - $window->GridAddComponentsToForm($form, 1); - - run: - my $r = $form->RunForm; - &$_ foreach @updates; - - if ($$r != $$cancel && $hcallback{complete}) { - my ($error, $focus) = $hcallback{complete}->(); - #-update all the value - &$_ foreach @updates_inv; - goto run if $error; - } - $form->FormDestroy; - Newt::PopWindow; - $$r != $$cancel; -} - - -sub waitbox($$) { - my ($title, $messages) = @_; - my ($t, $w, $h) = myTextbox(@$messages); - my $f = Newt::Component::Form(\undef, '', 0); - Newt::CenteredWindow($w, $h, $title); - $f->FormAddComponent($t); - $f->DrawForm; - Newt::Refresh; - $f->FormDestroy; - push @wait_messages, $f; - $f; -} - - -sub wait_messageW($$$) { - my ($o, $title, $messages) = @_; - { form => waitbox($title, $messages), title => $title }; -} - -sub wait_message_nextW { - my ($o, $messages, $w) = @_; - $o->wait_message_endW($w); - $o->wait_messageW($w->{title}, $messages); -} -sub wait_message_endW { - my ($o, $w) = @_; - log::l("interactive_newt does not handle none stacked wait-messages") if $w->{form} != pop @wait_messages; - Newt::PopWindow; -} - -sub kill { -} - +#sub ask_many_from_list_refW($$$$$) { +# my ($o, $title, $messages, $list, $val) = @_; +# my $n = 0; +# my $w = my_gtk->new('', %$o); +# my $box = gtkpack(new Gtk::VBox(0,0), +# map { +# my $nn = $n++; +# my $o = Gtk::CheckButton->new($_); +# $o->set_active(${$val->[$nn]}); +# $o->signal_connect(clicked => sub { invbool \${$val->[$nn]} }); +# $o; +# } @$list); +# gtkadd($w->{window}, +# gtkpack_(create_box_with_title($w, @$messages), +# 1, @$list > 11 ? gtkset_usize(createScrolledWindow($box), 0, 250) : $box, +# 0, $w->create_okcancel, +# ) +# ); +# $w->{ok}->grab_focus; +# $w->main && $val; +#} +# +# +#sub ask_from_entries_refW { +# my ($o, $title, $messages, $l, $val, %hcallback) = @_; +# my ($title_, @okcancel) = ref $title ? @$title : $title; +# my $num_fields = @{$l}; +# my $ignore = 0; #-to handle recursivity +# +# my $w = my_gtk->new($title_, %$o); +# #-the widgets +# my @widgets = map { +# if ($_->{type} eq "list") { +# my $w = new Gtk::Combo; +# $w->set_use_arrows_always(1); +# $w->entry->set_editable(!$_->{not_edit}); +# $w->set_popdown_strings(@{$_->{list}}); +# $w->disable_activate; +# $_->{val} ||= $_->{list}[0]; +# $w; +# } elsif ($_->{type} eq "bool") { +# my $w = Gtk::CheckButton->new($_->{text}); +# $w->set_active(${$_->{val}}); +# my $i = $_; $w->signal_connect(clicked => sub { $ignore or invbool \${$i->{val}} }); +# $w; +# } else { +# new Gtk::Entry; +# } +# } @{$val}; +# my $ok = $w->create_okcancel(@okcancel); +# +# sub widget { +# my ($w, $ref) = @_; +# ($ref->{type} eq "list" && @{$ref->{list}}) ? $w->entry : $w +# } +# my @updates = mapn { +# my ($w, $ref) = @_; +# sub { +# $ref->{type} eq "bool" and return; +# ${$ref->{val}} = widget($w, $ref)->get_text; +# }; +# } \@widgets, $val; +# +# my @updates_inv = mapn { +# my ($w, $ref) = @_; +# sub { +# $ref->{type} eq "bool" ? +# $w->set_active(${$ref->{val}}) : +# widget($w, $ref)->set_text(${$ref->{val}}) +# }; +# } \@widgets, $val; +# +# +# for (my $i = 0; $i < $num_fields; $i++) { +# my $ind = $i; #-cos lexical bindings pb !! +# my $widget = widget($widgets[$i], $val->[$i]); +# my $changed_callback = sub { +# return if $ignore; #-handle recursive deadlock +# &{$updates[$ind]}; +# if ($hcallback{changed}) { +# &{$hcallback{changed}}($ind); +# #update all the value +# $ignore = 1; +# &$_ foreach @updates_inv; +# $ignore = 0; +# }; +# }; +# if ($hcallback{focus_out}) { +# my $focusout_callback = sub { +# return if $ignore; +# &{$hcallback{focus_out}}($ind); +# #update all the value +# $ignore = 1; +# &$_ foreach @updates_inv; +# $ignore = 0; +# }; +# $widget->signal_connect(focus_out_event => $focusout_callback); +# } +# if (ref $widget eq "Gtk::Entry") { +# $widget->signal_connect(changed => $changed_callback); +# my $go_to_next = sub { +# if ($ind == ($num_fields -1)) { +# $w->{ok}->grab_focus(); +# } else { +# widget($widgets[$ind+1],$val->[$ind+1])->grab_focus(); +# } +# }; +# $widget->signal_connect(activate => $go_to_next); +# $widget->signal_connect(key_press_event => sub { +# my ($w, $e) = @_; +# #-don't know why it works, i believe that +# #-i must say before &$go_to_next, but with it doen't work HACK! +# $w->signal_emit_stop("key_press_event") if chr($e->{keyval}) eq "\x8d"; +# }); +# $widget->set_text(${$val->[$i]{val}}) if ${$val->[$i]{val}}; +# $widget->set_visibility(0) if $val->[$i]{hidden}; +# } +# &{$updates[$i]}; +# } +# +# my @entry_list = mapn { [($_[0], $_[1])]} $l, \@widgets; +# +# gtkadd($w->{window}, +# gtkpack( +# create_box_with_title($w, @$messages), +# create_packtable({}, @entry_list), +# $ok +# )); +# widget($widgets[0],$val->[0])->grab_focus(); +# if ($hcallback{complete}) { +# my $callback = sub { +# my ($error, $focus) = &{$hcallback{complete}}; +# #-update all the value +# $ignore = 1; +# foreach (@updates_inv) { &{$_};} +# $ignore = 0; +# if ($error) { +# $focus ||= 0; +# widget($widgets[$focus], $val->[$focus])->grab_focus(); +# } else { +# return 1; +# } +# }; +# #$w->{ok}->signal_connect(clicked => $callback) +# $w->main($callback); +# } else { +# $w->main(); +# } +#} +# +# +#sub wait_messageW($$$) { +# my ($o, $title, $message) = @_; +# +# my $w = my_gtk->new($title, %$o, grab => 1); +# my $W = pop @$message; +# gtkadd($w->{window}, +# gtkpack(new Gtk::VBox(0,0), +# @$message, +# $w->{wait_messageW} = new Gtk::Label($W))); +# $w->sync; +# $w; +#} +#sub wait_message_nextW { +# my ($o, $message, $w) = @_; +# $w->{wait_messageW}->set($message); +# $w->sync; +#} +#sub wait_message_endW { +# my ($o, $w) = @_; +# $w->destroy; +#} +# +#sub kill { +# my ($o) = @_; +# $o->{before_killing} ||= 0; +# while (@interactive::objects > $o->{before_killing}) { +# my $w = pop @interactive::objects; +# $w->destroy; +# } +# @my_gtk::grabbed = (); +# $o->{before_killing} = @interactive::objects; +#} 1; |