#!/usr/local/bin/perl
# FILE DBgui/list.pm
#
# list view component of the HP-200LX/DB GUI
#
# written: 1998-03-08
# latest update: 2001-03-11 2:23:23
# $Id: $
#
package HP200LX::DBgui::list;
use strict;
use vars qw($VERSION @ISA);
use Exporter;
$VERSION= '0.09';
@ISA= qw(Exporter HP200LX::DBgui);
use Tk;
# ----------------------------------------------------------------------------
sub new
{
my $class= shift;
my $DBgui= shift;
my $view= shift; # NUMBER!!! (not the name) of the view
my $title= shift;
my %pars= @_;
print ">>> list pars=", join (':', %pars), "\n";
my $height= 15; # || shift?
my $db= $DBgui->{db};
my $vptd= $db->find_viewptdef ($view)
|| $db->find_viewptdef ($view= 0)
|| return;
my $vpt_name= $vptd->{name};
$view= $vptd->{index};
print "view=$view name=$vpt_name\n";
my $fd= $db->{fielddef}; # description abuot data types
my ($col, %fields, $top);
my ($mb_v);
my @columns= (); # column number to name mapping
my @lb= (); # column number to list box mapping
# &HP200LX::DB::vpt::show_viewptdef ($vptd, *STDOUT);
my $cols= $vptd->{cols};
unless (defined ($top= $pars{top}))
{
$top= MainWindow->new ();
$top->title ("$title [$vpt_name]");
# menu bar
my $mb= $top->Frame (-relief => 'raised', -width => 40);
# menu item "view"
$mb->pack (-side => 'top', -fill => 'x');
my $mb_f= $mb->Menubutton (-text => 'File', -relief => 'raised')
->pack (-side => 'left', -padx => 2, -fill => 'x');
$mb_f->command (-label => 'Hide', -command => sub {$top->withdraw ();});
$mb_f->command (-label => 'Exit', -command => sub {exit});
$mb_v= $mb->Menubutton (-text => 'View', -relief => 'raised')
->pack (-side => 'left', -padx => 2, -fill => 'x');
$mb_v->command (-label => 'select view', -command => sub {$DBgui->open_vpt_list});
$mb_v->command (-label => 'dump def',
-command => sub {&HP200LX::DB::vpt::show_viewptdef ($vptd, *STDOUT);});
}
my $List_View=
{
DBgui => $DBgui,
db => $db,
num => 0, # number of records
disp => 0, # record currently shown
top => $top,
view => $view,
vptd => $vptd,
vptt => [], # filled in later on
columns => \@columns,
lists => \@lb,
};
bless $List_View, $class;
# record bar
&HP200LX::DBgui::create_record_bar ($top, $List_View, $DBgui);
my $sbf= $top->Frame ();
$sbf->Label()->pack (-side => 'top'); # place holder
my $sb= $sbf->Scrollbar (-orient => 'vertical', -width => 10)
->pack (-side => 'bottom', -fill => 'y', -expand => 1);
$List_View->{scroll}= $sb;
# 1. produce the main widget as a horizontal composition of
# frames consisting of
# + a Label used as heading and
# + a Listbox used to show the data
# 2. map column names and Listbox items where data can be filled in later
my ($name, $lb);
foreach $col (@$cols)
{
my $num= $col->{num};
my $vc= $top->Frame ();
my $fe= $fd->[$num];
$name= $fe->{name};
$vc->Label (-text => $name, -width => $col->{width}, -relief => 'ridge')
->pack (-side => 'top', -fill => 'x');
$lb= $vc->Listbox (-width => $col->{width},
-height => $height,
-yscrollcommand => ['set', $sb])
->pack (-side => 'bottom', -fill => 'both', -expand => 1);
$vc->pack (-side => 'left', -fill => 'both', -expand => 1);
push (@columns, $name);
push (@lb, $lb);
}
$sbf->pack (-side => 'left', -fill => 'y');
$sb->configure (-command => ['yview', $List_View]);
foreach $lb (@lb)
{
$lb->bind ('<Double-1>' => sub { $List_View->select_item ($lb); } );
}
$mb_v->command (-label => 'refresh',
-command => sub {$List_View->show_rows (1);});
$List_View->show_rows (0);
$List_View;
}
# ----------------------------------------------------------------------------
sub show_rows
{
my $List_View= shift;
my $forced_update= shift;
my $view= $List_View->{view};
my $db= $List_View->{db};
my $columns= $List_View->{columns};
my $lists= $List_View->{lists};
my $vptt= $db->find_viewpttable ($view);
$List_View->{vptt}= $vptt;
# fill data items into each cell
if ($forced_update || $vptt == undef || $#$vptt < 0)
{ # hack up a faked view point table; T2D: refresh the real table
$vptt= $db->refresh_viewpt ($view);
}
my $max= $db->get_last_index ();
# print ">>> insert_row: vptt=", $#$vptt+1, " max=$max\n";
# use view point table to produce the right sorting of the items
my ($i, $j);
for ($j= 0; $j <= $#$columns; $j++)
{
$lists->[$j]->delete (0, 'end');
}
foreach $i (@$vptt)
{
# print ">>>> insert: i=$i\n";
my $rec= $db->FETCH ($i) || next; # or bail out ???
# print ">>>> insert: i=$i found\n";
for ($j= 0; $j <= $#$columns; $j++)
{
my $s= $rec->{$columns->[$j]};
$s=~ tr/\r\n / /s;
$lists->[$j]->insert ('end', $s);
}
}
$List_View->{num}= 1+ $#$vptt;
}
# ----------------------------------------------------------------------------
# vertical scroll method for a composite list view widget:
# calls yview method for each list
sub yview
{
my $w= shift;
foreach (@{$w->{lists}}) { $_->yview (@_); }
}
# ----------------------------------------------------------------------------
sub select_item
{
my $DBlist= shift;
my $listbox= shift;
my $lb_idx= $listbox->index ('active');
my $db_idx= $DBlist->{vptt}->[$lb_idx];
$DBlist->{disp}= $lb_idx;
print ">>> show_card lb_idx=$lb_idx db_idx=$db_idx\n";
$DBlist->{DBgui}->show_card ($db_idx+1);
}
# ----------------------------------------------------------------------------
# Place Holder methods
sub add_record { print "List View Add Record not yet implemented!\n"; }
sub show_record
{
my ($DBlist, $num, $whence)= @_;
if ($whence == 2) { $DBlist->{disp}= $DBlist->{num} - $num; }
elsif ($whence == 1) { $DBlist->{disp} += $num; }
else { $DBlist->{disp}= $num; }
$num= $DBlist->{disp};
$num= $DBlist->{disp}= 1 if ($num < 1);
$num= $DBlist->{disp}= $DBlist->{num} if ($num > $DBlist->{num});
my $db_idx= $DBlist->{vptt}->[$num];
print ">>> show_card num=$num\n";
$DBlist->{DBgui}->show_card ($db_idx+1);
}