/usr/local/CPAN/QWizard/QWizard/Generator/ReadLine.pm
package QWizard::Generator::ReadLine;
use Term::ReadLine;
require Exporter;
use QWizard::Generator;
use strict;
our $VERSION = '3.15';
@QWizard::Generator::ReadLine::ISA = qw(Exporter QWizard::Generator);
our %defaults = ();
our $width = 78;
#our $clear_screen = `clear`; # not ideal, but hey. (see perlfaq8)
our $clear_screen = "\n\n";
sub new {
my $type = shift;
my ($class) = ref($type) || $type;
my %self = %defaults;
my $self = \%self;
$self->{'term'} = new Term::ReadLine "QWizard::ReadLine";
bless($self, $class);
$self->add_handler('text',\&QWizard::Generator::ReadLine::do_entry,
[['single','name'],
['default']]);
$self->add_handler('checkbox',\&QWizard::Generator::ReadLine::do_checkbox,
[['multi','values'],
['default'],
['single', 'name']]);
$self->add_handler('label',\&QWizard::Generator::ReadLine::do_label,
[['multi','values']]);
$self->add_handler('paragraph',\&QWizard::Generator::ReadLine::do_label,
[['multi','values']]);
$self->add_handler('multi_checkbox',
\&QWizard::Generator::ReadLine::do_multicheckbox,
[['multi','default'],
['values,labels']]);
$self->add_handler('radio',
\&QWizard::Generator::ReadLine::do_radio,
[['values,labels', " "],
['default'],
['single','name']]);
$self->add_handler('textbox',\&QWizard::Generator::ReadLine::do_textbox,
[['single','name'],
['default'],
['single','size'],
['single','maxsize'],
['single','submit']]);
# reuse a radio since they're the same
$self->add_handler('menu',
\&QWizard::Generator::ReadLine::do_radio,
[['values,labels', " "],
['default'],
['single','name']]);
# pick a entry box for a file upload. Not quite right, but...
$self->add_handler('fileupload',
\&QWizard::Generator::ReadLine::do_entry,
[['default','values']]);
$self->add_handler('unknown',\&QWizard::Generator::ReadLine::do_unknown,
[]);
$self->init_default_storage();
return $self;
}
sub init_screen {
my ($self, $wiz, $title) = @_;
print $clear_screen;
barrier("*");
maybechompp($title," -- ", " --");
}
sub wait_for {
barrier("-");
}
sub do_question {
my ($self, $q, $wiz, $p, $text, $qcount) = @_;
chompp($text);
}
sub do_question_end {
print "\n";
}
sub start_questions {
my ($self, $wiz, $p, $title, $intro) = @_;
barrier("=");
maybechompp("$title", "title: ");
maybechompp($intro);
print "\n";
}
sub end_questions {
$_[0]->install_tempvars();
}
sub do_entry {
my ($self, $q, $wiz, $p, $name, $def) = @_;
$self->read_it($q, $name, $def);
}
sub do_error {
my ($self, $q, $wiz, $p, $err) = @_;
print "ERROR: $err\n";
}
sub do_textbox {
my ($self, $q, $wiz, $p, $name, $def) = @_;
my ($text, $val);
print "Enter text below. Enter a '.' on a line by itself to finish.\n";
do {
$text .= $val . "\n";
$val = $self->{'term'}->readline(": ");
} while ($val ne '.');
chomp($text);
$self->qwtemp($q->{'name'}, $text);
}
sub do_yn {
my ($self, $def) = @_;
my $val = '';
do {
$val = $self->{'term'}->readline("y/n" . (($def) ? " [$def]" : "")
. ": ");
if ($val eq '' && $def) {
$val = $def;
} elsif ($val ne 'y' && $val ne 'n') {
print "*** illegal answer. You must pick 'y' or 'n'\n";
}
} while ($val ne 'y' && $val ne 'n');
return $val;
}
sub get_yn_default {
my ($def, $vals) = @_;
my $val;
if ($def && $def eq $vals->[0]) {
$val = 'y';
} else { # lets just assume a default of n for easy entry
$val = 'n';
}
return $val;
}
sub do_checkbox {
my ($self, $q, $wiz, $p, $vals, $def, $name) = @_;
my $val = '';
$vals = [1,0] if ($#$vals == -1);
$val = $self->do_yn(get_yn_default($def, $vals));
if ($val eq 'y') {
$self->qwtemp($name, $vals->[0]);
} elsif ($val eq 'n') {
$self->qwtemp($name, $vals->[1]);
}
}
sub do_multicheckbox {
my ($self, $q, $wiz, $p, $defs, $vals, $labels) = @_;
my $count = -1;
foreach my $v (@$vals) {
$count++;
my $l = (($labels->{$v}) ? $labels->{$v} : "$v");
print $l,"\n";
my $val = $self->do_yn(get_yn_default($defs->[$count], [$v,'']));
if ($val eq 'y') {
$self->qwtemp($q->{name} . $v, $vals->[$count]);
} else {
$self->qwtemp($q->{name} . $v, '');
}
push @{$wiz->{'passvars'}},$q->{'name'} . $v;
}
}
sub do_radio {
my ($self, $q, $wiz, $p, $vals, $labels, $def) = @_;
my $count = 0;
my $defcount;
foreach my $v (@$vals) {
$count++;
my $text = (($labels->{$v}) ? $labels->{$v} : "$v");
if ($def eq $v) {
$defcount = $count;
}
printf " %3d) %s\n", $count, $text;
}
my $val;
while ($val !~ /^\d+$/ || $val-1 < 0 || $val-1 > $#$vals) {
if ($val ne '') {
print "*** illegal answer\n";
}
$val = $self->{'term'}->readline("Pick one" .
(($defcount) ? " [$defcount]" : "") .
": ");
$val = $defcount if ($val eq '')
}
$self->qwtemp($q->{name}, $vals->[$val-1]);
}
sub do_label {
my ($self, $q, $wiz, $p, $vals, $def) = @_;
if (defined ($vals)) {
map { chompp($_); }@$vals;
}
}
sub do_menu {
$_[0]->do_radio(@_);
}
sub do_separator {
my ($self, $q, $wiz, $p, $text) = @_;
print "$text\n";
}
sub do_unknown {
my ($self, $q, $wiz, $p) = @_;
print "Error: Unhandled question type '$q->{type}' in primary '$p->{module_name}'.\nIt is highly likely that this page will not function properly after this point.\n";
}
sub read_it {
my ($self, $q, $name, $def, $prompt) = @_;
my $val = $self->{'term'}->readline($prompt ||
((($def)?"[$def] ":"") . ": "));
if ($val eq '' && $def) {
$self->qwtemp($name, $def);
} else {
$self->qwtemp($name, $val);
}
}
##################################################
# action confirm
##################################################
sub start_confirm {
my ($self, $wiz) = @_;
barrier("*");
print "Wrapping up:\n";
print "Do you want to commit the following changes:\n";
}
sub end_confirm {
my ($self, $wiz) = @_;
my $val = $self->do_yn();
if ($val eq 'y') {
$self->qwparam('wiz_confirmed','Commit');
} else {
$self->qwparam('wiz_confirmed','Cancel');
}
}
sub do_confirm_message {
my ($self, $wiz, $msg) = @_;
chompp($msg, " ");
}
sub canceled_confirm {
print "*** cancelled\n";
}
##################################################
# actions
##################################################
sub start_actions {
my ($self, $wiz) = @_;
barrier("*");
print "Processing your request...\n";
}
sub end_actions {
my ($self, $wiz) = @_;
print "Done!\n";
}
sub do_action_output {
my ($self, $wiz, $action) = @_;
chompp("$action", " ");
}
sub do_action_error {
my ($self, $wiz, $errstr) = @_;
chompp("$errstr", "ERROR: ");
}
##################################################
# utils
##################################################
sub chompp {
my ($text, $prefix, $suffix) = shift;
chomp($text);
print $prefix, $text, $suffix,"\n";
}
sub maybechompp {
return if (!$_[0]);
chompp(@_);
}
sub barrier {
print $_[0] x $width, "\n";
}
## we have a temporary storage that we fill in later into the master storage.
our %tempvars;
sub qwtemp {
my ($self, $name, $val) = @_;
$tempvars{$name} = $val;
}
sub install_tempvars {
my $self = shift;
foreach my $k (keys(%tempvars)) {
$self->qwparam($k, $tempvars{$k});
}
%tempvars = ();
}
1;