diff --git a/lib/Tpda3/Tk/TM.pm b/lib/Tpda3/Tk/TM.pm index 10328b4..3a94af3 100644 --- a/lib/Tpda3/Tk/TM.pm +++ b/lib/Tpda3/Tk/TM.pm @@ -71,7 +71,7 @@ sub init { $self->{embeded_meta}{$emb} = { choices => $args->{$emb} }; } else { - warn "No init args for '$emb'\n"; + warn "No init args for '$emb'\n"; # TODO: show only for ckbuttons } } @@ -194,7 +194,7 @@ sub set_tags { } # Add selector column - if ( $self->{selectorcol} ) { + if ( $self->{selectorcol} and $self->{selectorcol} =~ /^\d+$/) { my $selecol = $self->{selectorcol}; $self->insertCols( $selecol, 1 ); $self->tagCol( 'ro_center', $selecol ); @@ -260,11 +260,11 @@ sub read_row { if ( !$all_cols ) { next if $rw eq 'ro'; # skip ro cols } - # print "reading TM cell on row '$row' for field '$field'\n"; + #say "reading TM cell on row '$row' for field '$field'"; my $cell_data = $self->cell_read( $row, $field ); foreach my $key ( keys %{$cell_data} ) { $row_data->{$key} = $cell_data->{$key}; - # print " $key => ", $cell_data->{$key}, "\n"; + #say " $key => ", $cell_data->{$key}; } } return $row_data; @@ -343,6 +343,7 @@ sub cell_read { $field = $self->get_field_for($col); } my $cell_value = $self->get("$row,$col"); + $cell_value = $cell_value ? 1 : 0 if $w_type eq 'ckbutton'; return { $field => $cell_value }; } @@ -362,16 +363,36 @@ sub cell_write { $field = $self->{fields}[$c]; } $self->set("$r,$c", $value); - my $w; # update the embeded widget + my $w; eval { $w = $self->windowCget( "$r,$c", '-window' ) }; unless ($@) { - if ( $w =~ /Tk::JComboBox/ ) { + if ( $w =~ /JComboBox/i ) { my $var = $w->cget('-textvariable'); - $$var = $value; + if (ref $var eq 'SCALAR') { + $$var = $value; + } + else { + die "jcombobox update failed\n"; + } } - elsif ( $w =~ /Tk::DateEntry/ ) { + elsif ( $w =~ /DateEntry/i ) { my $var = $w->cget('-textvariable'); - $$var = $value; + if (ref $var eq 'SCALAR') { + $$var = $value; + } + else { + die "dateentry update failed\n"; + } + + } + elsif ( $w =~ /Checkbutton/i ) { + my $var = $w->cget('-variable'); + if (ref $var eq 'SCALAR') { + $$var = $value; + } + else { + die "checkbutton update failed\n"; + } } } return; @@ -439,7 +460,7 @@ sub remove_row { # Refresh table $self->activate('origin'); - $self->activate("$row,1"); + $self->activate("$row,1"); # return; } @@ -499,7 +520,7 @@ sub add_embeded_widgets { if ( $w_type eq 'dateentry' ) { $self->windowConfigure( "$row,$col", - -sticky => 'ne', + -sticky => 'nw', -window => $self->build_dateentry( $row, $col ), ); } @@ -507,10 +528,18 @@ sub add_embeded_widgets { my $choices = $self->{embeded_meta}{$field}{choices}; $self->windowConfigure( "$row,$col", - -sticky => 'ne', + -sticky => 'nw', -window => $self->build_jcombobox( $row, $col, $choices ), ); } + elsif ( $w_type eq 'ckbutton' or $w_type eq 'checkbutton') { + my $p = $fields_cfg->{$field}; + $self->windowConfigure( + "$row,$col", + -sticky => 'n', + -window => $self->build_ckbutton( $row, $col, $p ), + ); + } $self->update; } return; @@ -518,43 +547,71 @@ sub add_embeded_widgets { sub embeded_sel_buttons { my ( $self, $row, $col ) = @_; - my $selestyle = defined $self->{selectorstyle} + # TODO: WTF! + my $selestyle = $self->{selectorstyle} ? $self->{selectorstyle} : q{}; - my $selecolor = defined $self->{selectorcolor} + my $selecolor = $self->{selectorcolor} ? $self->{selectorcolor} : q{lightblue}; if ( $selestyle eq 'checkbox' ) { $self->windowConfigure( "$row,$col", -sticky => 's', - -window => $self->build_ckbutton( $row, $col ), + -window => $self->build_sel_ckbutton( $row, $col, $selecolor ), ); } else { $self->windowConfigure( "$row,$col", -sticky => 's', - -window => $self->build_rbbutton( $row, $col, $selecolor ), + -window => $self->build_sel_rbbutton( $row, $col, $selecolor ), ); } return; + } sub build_ckbutton { - my ( $self, $row, $col ) = @_; + my ( $self, $row, $col, $p ) = @_; + my $text = exists $p->{text} ? $p->{text} : ''; + my $image = exists $p->{image} ? $p->{image} : ''; + my $color = exists $p->{selectcolor} ? $p->{selectcolor} : 'lightblue'; + my $width = exists $p->{displ_width} ? $p->{displ_width} : 'width'; + my $button = $self->{frame}->Checkbutton( + + # -image => 'actcross16', + # -selectimage => 'actcheck16', + -width => $width, + -text => $text, + -indicatoron => 0, + -selectcolor => $color, + -offvalue => 0, + -onvalue => 1, + -state => 'normal', + -command => sub { $self->ckbutton_browse($row, $col) } + ); + return $button; +} + +sub build_sel_ckbutton { + my ( $self, $row, $col, $selecolor ) = @_; + my $width = 5; # $self->cell_config_for($field, 'displ_width'); my $button = $self->{frame}->Checkbutton( - -image => 'actcross16', - -selectimage => 'actcheck16', + # -image => 'actcross16', + # -selectimage => 'actcheck16', + -width => $width, -indicatoron => 0, - -selectcolor => 'lightblue', + -selectcolor => $selecolor, + -offvalue => 0, + -onvalue => 1, -state => 'normal', -command => sub { $self->validate("$row,$col") } ); return $button; } -sub build_rbbutton { +sub build_sel_rbbutton { my ( $self, $row, $col, $selecolor ) = @_; my $button = $self->{frame}->Radiobutton( -width => 3, @@ -644,18 +701,42 @@ sub dentry_browse { return $date_str; } +sub ckbutton_browse { + my ( $self, $r, $c ) = @_; + my $value = $self->is_checked($r, $c) ? 1 : 0; + $self->set("$r,$c", $value); + return; +} + sub toggle_ckbutton { my ( $self, $r, $c, $state ) = @_; - my $ckb; - eval { $ckb = $self->windowCget( "$r,$c", -window ); }; + my ($w, $value); + eval { $w = $self->windowCget( "$r,$c", -window ); }; unless ($@) { - if ( $ckb =~ /Checkbutton/ ) { + if ( $w =~ /Checkbutton/i ) { if ( defined $state ) { - $state ? $ckb->select : $ckb->deselect; + $state ? $w->select : $w->deselect; } else { - $self->is_checked( $r, $c ) ? $ckb->deselect : $ckb->select; + $state = $self->is_checked( $r, $c ); + $state ? $w->deselect : $w->select; + $state = not $state; } + $value = $self->is_checked($r, $c); + $self->set("$r,$c", $value); + } + } + return $value; +} + +sub mouse_click_ckbutton { + my ( $self, $r, $c ) = @_; + my $w; + eval { $w = $self->windowCget( "$r,$c", -window ); }; + unless ($@) { + if ( $w =~ /Checkbutton/i ) { + $w->eventGenerate(''); + $w->eventGenerate(''); } } return; @@ -669,9 +750,9 @@ sub is_checked { my $bw; eval { $bw = $self->windowCget( "$r,$c", -window ); }; unless ($@) { - if ( $bw =~ /Checkbutton/ ) { - my $ckb_var = $bw->cget('-variable'); - $is_checked = $$ckb_var ? $$ckb_var : 0; + if ( $bw =~ /Checkbutton/i ) { + my $w_var = $bw->cget('-variable'); + $is_checked = $$w_var ? $$w_var : 0; } # Radiobutton uses the global var $self->{tm_sel} } @@ -814,7 +895,7 @@ C; =back -=head2 build_rbbutton +=head2 build_sel_rbbutton Build Radiobutton. @@ -832,7 +913,7 @@ undef. As a consequence it won't set as selected row 0. Return selector column. -=head2 build_ckbutton +=head2 build_sel_ckbutton Build Checkbutton. diff --git a/t/30-tk-tm.t b/t/30-tk-tm.t index 9397777..66e0c55 100644 --- a/t/30-tk-tm.t +++ b/t/30-tk-tm.t @@ -147,7 +147,7 @@ ok !$tm->init( $mw, $header ), 'make header'; $tm->pack( -expand => 1, -fill => 'both'); -my ( $delay, $milisec ) = ( 1, 1000 ); +my ( $delay, $milisec ) = ( 1, 100 ); $mw->after( $delay * $milisec, diff --git a/t/35-tk-tmshr.t b/t/35-tk-tmshr.t index acbb7ca..e3f49a2 100644 --- a/t/35-tk-tmshr.t +++ b/t/35-tk-tmshr.t @@ -182,15 +182,15 @@ is( $tm->make_header($header), undef, 'make header' ); $tm->pack( -expand => 1, -fill => 'both'); -my $delay = 1; +my ( $delay, $milisec ) = ( 1, 100 ); -$mw->after( $delay * 100, +$mw->after( $delay * $milisec, sub { is( $tm->fill_main($record, 'nr_crt'), undef, 'fill TMSHR' ); } ); $delay++; $mw->after( - $delay * 100, + $delay * $milisec, sub { is( $tm->fill_details($expdata), undef, 'fill TMSHR det 1' ); } @@ -199,7 +199,7 @@ $mw->after( $delay++; $mw->after( - $delay * 100, + $delay * $milisec, sub { is_deeply($tm->get_main_data(), $record, 'compare main data'); is_deeply($tm->get_expdata(), $expdata, 'compare expand data'); @@ -208,7 +208,7 @@ $mw->after( $delay++; -$mw->after( $delay * 100, sub { $mw->destroy } ); +$mw->after( $delay * $milisec, sub { $mw->destroy } ); Tk::MainLoop; diff --git a/t/40-tk-embed-cb.t b/t/40-tk-embed-cb.t new file mode 100644 index 0000000..b0888de --- /dev/null +++ b/t/40-tk-embed-cb.t @@ -0,0 +1,271 @@ +# +# Tpda3 Tk TM embeded windows test script +# Selector: checkbox +# +use 5.010; +use strict; +use warnings; + +use Test::Most; +use Tk; + +use lib qw( lib ../lib ); + +BEGIN { + unless ( $ENV{DISPLAY} or $^O eq 'MSWin32' ) { + plan skip_all => 'Needs DISPLAY'; + exit 0; + } + eval { use Tk; }; + if ($@) { + plan( skip_all => 'Perl Tk is required for this test' ); + } +} + +use Tpda3::Tk::TM; + +# Header for TM, slightly modified data, all cols are 'rw' + +my $header = { + colstretch => '', + selectorcol => 5, + selectorcolor => 'green3', + selectorstyle => 'checkbox', + columns => { + id_doc => { + id => 0, + label => 'Id', + tag => 'ro_center', + displ_width => 5, + valid_width => 5, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanum', + }, + tip_doc => { + id => 1, + label => 'Tip', + # tag => 'enter_left', + displ_width => 20, + valid_width => 20, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanumplus', + embed => 'jcombobox', + }, + doc_date => { + id => 2, + label => 'Date', + # tag => 'enter_left', + displ_width => 13, + valid_width => 10, + numscale => 0, + readwrite => 'rw', + datatype => 'date', + embed => 'dateentry', + }, + den_doc => { + id => 3, + label => 'Denum', + tag => 'enter_left', + displ_width => 40, + valid_width => 20, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanumplus', + }, + valid_doc => { + id => 4, + label => 'Valid', + text => 'YES', + # tag => 'enter_left', + displ_width => 5, + valid_width => 1, + numscale => 0, + readwrite => 'rw', + datatype => 'numeric', + embed => 'ckbutton', + }, + }, +}; + +my $choices = [ + { -name => 'one', -value => 1 }, + { -name => 'two', -value => 2 }, + { -name => 'three', -value => 3 }, +]; + +# Data for tests + +my $records = [ + { id_doc => 1, + tip_doc => 3, + doc_date => '2018-01-01', + den_doc => '1930 Buick Marquette Phaeton', + valid_doc => 1, + }, + { id_doc => 2, + tip_doc => 2, + doc_date => '2018-01-01', + den_doc => 'American Airlines: B767-300', + valid_doc => 0, + }, + { id_doc => 3, + tip_doc => 1, + doc_date => '2018-01-01', + den_doc => 'F/A 18 Hornet 1/72', + valid_doc => 1, + }, +]; + +my $mw = tkinit; +#$mw->geometry('460x80+20+20'); +$mw->geometry('+20+20'); + +my $tm; +my $xtvar = {}; +eval { + $tm = $mw->Scrolled( + 'TM', + -rows => 5, + -cols => 3, + -width => -1, + -height => -1, + -ipadx => 3, + -titlerows => 1, + -validate => 1, + -variable => $xtvar, + -selectmode => 'single', + -resizeborders => 'none', + -bg => 'white', + -scrollbars => 'osw', + ); +}; +ok !$@, 'create TM'; + +is $tm->is_col_name('tip_doc'), 1, 'is col name'; +is $tm->is_col_name(3), '', 'is col name'; + +$header->{tip_doc} = $choices; # add the choices to the args + +ok !$tm->init( $mw, $header ), 'make header'; + +is $tm->cell_config_for( 'tip_doc', 'embed' ), 'jcombobox', + 'cell_config_for tip_doc'; # call after init! + +is $tm->cell_config_for( 1, 'embed' ), 'jcombobox', + 'cell_config_for 1'; # call after init! + +$tm->pack( -expand => 1, -fill => 'both' ); + +my ( $delay, $milisec ) = ( 1, 100 ); + +$mw->after( + $delay * $milisec, + sub { + ok $tm->fill($records), 'fill TM'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply $data, $records, 'read data from TM'; + is $tm->toggle_ckbutton( 2, 5, 1 ), 1, 'toggle ckbutton'; + is $tm->count_is_checked(5), 1, 'is checked count 1'; + + is $tm->count_is_checked(4), 2, 'is checked count 2'; + is $tm->toggle_ckbutton( 2, 4, 1 ), 1, 'toggle ckbutton'; + is $tm->count_is_checked(4), 3, 'is checked count 3'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + my $cell_data = $tm->cell_read( 1, 3 ); + cmp_deeply( + $cell_data, + { den_doc => '1930 Buick Marquette Phaeton' }, + 'read cell from TM' + ); + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->clear_all; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data, [], 'read data from TM after clear' ); + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 1, 0 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], + 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 2, 1 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + is $tm->toggle_ckbutton( $r-1 , 5, 1 ), 1, 'toggle ckbutton'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 3, 2 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], + 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + my $r_data = $tm->read_row($r); + is $tm->has_embeded_widget('tip_doc'), 1, + 'tip_doc has emebeded widget'; + is $tm->has_embeded_widget('den_doc'), '', + 'den_doc has no emebeded widget'; + is $tm->toggle_ckbutton( $r-1 , 5, 1 ), 1, 'toggle ckbutton'; + } +); + +$delay++; + +$mw->after( $delay * $milisec, sub { $mw->destroy } ); + +Tk::MainLoop; + +done_testing(); diff --git a/t/40-tk-embed-rb.t b/t/40-tk-embed-rb.t new file mode 100644 index 0000000..190d3ae --- /dev/null +++ b/t/40-tk-embed-rb.t @@ -0,0 +1,265 @@ +# +# Tpda3 Tk TM embeded windows test script +# Selector: radio (default) +# +use 5.010; +use strict; +use warnings; + +use Test::Most; +use Tk; + +use lib qw( lib ../lib ); + +BEGIN { + unless ( $ENV{DISPLAY} or $^O eq 'MSWin32' ) { + plan skip_all => 'Needs DISPLAY'; + exit 0; + } + eval { use Tk; }; + if ($@) { + plan( skip_all => 'Perl Tk is required for this test' ); + } +} + +use Tpda3::Tk::TM; + +# Header for TM, slightly modified data, all cols are 'rw' + +my $header = { + colstretch => '', + selectorcol => 5, + selectorcolor => 'green3', + selectorstyle => 'radio', + columns => { + id_doc => { + id => 0, + label => 'Id', + tag => 'ro_center', + displ_width => 5, + valid_width => 5, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanum', + }, + tip_doc => { + id => 1, + label => 'Tip', + # tag => 'enter_left', + displ_width => 20, + valid_width => 20, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanumplus', + embed => 'jcombobox', + }, + doc_date => { + id => 2, + label => 'Date', + # tag => 'enter_left', + displ_width => 13, + valid_width => 10, + numscale => 0, + readwrite => 'rw', + datatype => 'date', + embed => 'dateentry', + }, + den_doc => { + id => 3, + label => 'Denum', + tag => 'enter_left', + displ_width => 40, + valid_width => 20, + numscale => 0, + readwrite => 'rw', + datatype => 'alphanumplus', + }, + valid_doc => { + id => 4, + label => 'Valid', + text => 'YES', + # tag => 'enter_left', + displ_width => 5, + valid_width => 1, + numscale => 0, + readwrite => 'rw', + datatype => 'numeric', + embed => 'ckbutton', + }, + }, +}; + +my $choices = [ + { -name => 'one', -value => 1 }, + { -name => 'two', -value => 2 }, + { -name => 'three', -value => 3 }, +]; + +# Data for tests + +my $records = [ + { id_doc => 1, + tip_doc => 3, + doc_date => '2018-01-01', + den_doc => '1930 Buick Marquette Phaeton', + valid_doc => 1, + }, + { id_doc => 2, + tip_doc => 2, + doc_date => '2018-01-01', + den_doc => 'American Airlines: B767-300', + valid_doc => 0, + }, + { id_doc => 3, + tip_doc => 1, + doc_date => '2018-01-01', + den_doc => 'F/A 18 Hornet 1/72', + valid_doc => 1, + }, +]; + +my $mw = tkinit; +#$mw->geometry('460x80+20+20'); +$mw->geometry('+20+20'); + +my $tm; +my $xtvar = {}; +eval { + $tm = $mw->Scrolled( + 'TM', + -rows => 5, + -cols => 3, + -width => -1, + -height => -1, + -ipadx => 3, + -titlerows => 1, + -validate => 1, + -variable => $xtvar, + -selectmode => 'single', + -resizeborders => 'none', + -bg => 'white', + -scrollbars => 'osw', + ); +}; +ok !$@, 'create TM'; + +is $tm->is_col_name('tip_doc'), 1, 'is col name'; +is $tm->is_col_name(3), '', 'is col name'; + +$header->{tip_doc} = $choices; # add the choices to the args + +ok !$tm->init( $mw, $header ), 'make header'; + +is $tm->cell_config_for( 'tip_doc', 'embed' ), 'jcombobox', + 'cell_config_for tip_doc'; # call after init! + +is $tm->cell_config_for( 1, 'embed' ), 'jcombobox', + 'cell_config_for 1'; # call after init! + +$tm->pack( -expand => 1, -fill => 'both' ); + +my ( $delay, $milisec ) = ( 1, 100 ); + +$mw->after( + $delay * $milisec, + sub { + ok $tm->fill($records), 'fill TM'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply $data, $records, 'read data from TM'; + is $tm->count_is_checked(4), 2, 'is checked count 2'; + is $tm->toggle_ckbutton( 2, 4, 1 ), 1, 'toggle ckbutton'; + is $tm->count_is_checked(4), 3, 'is checked count 3'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + my $cell_data = $tm->cell_read( 1, 3 ); + cmp_deeply( + $cell_data, + { den_doc => '1930 Buick Marquette Phaeton' }, + 'read cell from TM' + ); + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->clear_all; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data, [], 'read data from TM after clear' ); + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 1, 0 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 2, 1 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + $tm->add_row; + my ( $r, $i ) = ( 3, 2 ); + $tm->write_row( $r, $records->[$i] ); + is $tm->get_selected, $r, "selected button '$r'"; + my ( $data, $scol ) = $tm->data_read(); + cmp_deeply( $data->[$i], $records->[$i], + 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + my $r_data = $tm->read_row($r); + is $tm->has_embeded_widget('tip_doc'), 1, + 'tip_doc has emebeded widget'; + is $tm->has_embeded_widget('den_doc'), '', + 'den_doc has no emebeded widget'; + } +); + +$delay++; + +$mw->after( $delay * $milisec, sub { $mw->destroy } ); + +Tk::MainLoop; + +done_testing(); diff --git a/t/40-tk-embed.t b/t/40-tk-embed.t index 7241278..e8145bd 100644 --- a/t/40-tk-embed.t +++ b/t/40-tk-embed.t @@ -1,7 +1,7 @@ # # Tpda3 Tk TM embeded windows test script +# Selector: none # - use 5.010; use strict; use warnings; @@ -27,11 +27,8 @@ use Tpda3::Tk::TM; # Header for TM, slightly modified data, all cols are 'rw' my $header = { - colstretch => '', - selectorcol => 4, - selectorcolor => 'green3', - selectorstyle => '', - columns => { + colstretch => '', + columns => { id_doc => { id => 0, label => 'Id', @@ -43,9 +40,10 @@ my $header = { datatype => 'alphanum', }, tip_doc => { - id => 1, - label => 'Tip', - tag => 'enter_left', + id => 1, + label => 'Tip', + + # tag => 'enter_left', displ_width => 20, valid_width => 20, numscale => 0, @@ -54,9 +52,10 @@ my $header = { embed => 'jcombobox', }, doc_date => { - id => 2, - label => 'Date', - tag => 'enter_left', + id => 2, + label => 'Date', + + # tag => 'enter_left', displ_width => 13, valid_width => 10, numscale => 0, @@ -74,6 +73,19 @@ my $header = { readwrite => 'rw', datatype => 'alphanumplus', }, + valid_doc => { + id => 4, + label => 'Valid', + text => 'YES', + + # tag => 'enter_left', + displ_width => 5, + valid_width => 1, + numscale => 0, + readwrite => 'rw', + datatype => 'numeric', + embed => 'ckbutton', + }, }, }; @@ -86,24 +98,34 @@ my $choices = [ # Data for tests my $records = [ - { id_doc => 1, - tip_doc => 3, - doc_date => '2018-01-01', - den_doc => '1930 Buick Marquette Phaeton', + { + id_doc => 1, + tip_doc => 3, + doc_date => '2018-01-01', + den_doc => '1930 Buick Marquette Phaeton', + valid_doc => 1, }, - { id_doc => 2, - tip_doc => 2, - doc_date => '2018-01-01', - den_doc => 'American Airlines: B767-300', + { + id_doc => 2, + tip_doc => 2, + doc_date => '2018-01-01', + den_doc => 'American Airlines: B767-300', + valid_doc => undef, }, - { id_doc => 3, - tip_doc => 1, - doc_date => '2018-01-01', - den_doc => 'F/A 18 Hornet 1/72', + { + id_doc => 3, + tip_doc => 1, + doc_date => '2018-01-01', + den_doc => 'F/A 18 Hornet 1/72', + valid_doc => 1, }, ]; +my $records_exp = $records; +$records_exp->[1]{valid_doc} = 0; + my $mw = tkinit; + #$mw->geometry('460x80+20+20'); $mw->geometry('+20+20'); @@ -128,27 +150,33 @@ eval { }; ok !$@, 'create TM'; -is $tm->is_col_name('tip_doc'), 1, 'is col name'; -is $tm->is_col_name(3), '', 'is col name'; +is $tm->is_col_name('tip_doc'), 1, 'is col name'; +is $tm->is_col_name(3), '', 'is col name'; + +$header->{tip_doc} = $choices; # add the choices to the args -$header->{tip_doc} = $choices; # add the choices to the args - ok !$tm->init( $mw, $header ), 'make header'; is $tm->cell_config_for( 'tip_doc', 'embed' ), 'jcombobox', - 'cell_config_for tip_doc'; # call after init! + 'cell_config_for tip_doc'; # call after init! is $tm->cell_config_for( 1, 'embed' ), 'jcombobox', - 'cell_config_for 1'; # call after init! + 'cell_config_for 1'; # call after init! $tm->pack( -expand => 1, -fill => 'both' ); -my ( $delay, $milisec ) = ( 1, 1000 ); +my ( $delay, $milisec ) = ( 1, 100 ); $mw->after( $delay * $milisec, sub { ok $tm->fill($records), 'fill TM'; + my $cell_data = $tm->cell_read( 1, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 1,4 from TM' ); + $cell_data = $tm->cell_read( 2, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 2,4 from TM' ); + $cell_data = $tm->cell_read( 3, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 3,4 from TM' ); } ); @@ -158,7 +186,19 @@ $mw->after( $delay * $milisec, sub { my ( $data, $scol ) = $tm->data_read(); - cmp_deeply $data, $records, 'read data from TM'; + + cmp_deeply $data, $records_exp, 'read data from TM'; + is $tm->count_is_checked(4), 2, 'is checked count 2'; + is $tm->toggle_ckbutton( 2, 4, 1 ), 1, 'toggle ckbutton'; + is $tm->count_is_checked(4), 3, 'is checked count 3'; + + my $cell_data; + $cell_data = $tm->cell_read( 1, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 1,4 from TM' ); + $cell_data = $tm->cell_read( 2, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 2,4 from TM' ); + $cell_data = $tm->cell_read( 3, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 3,4 from TM' ); } ); @@ -173,6 +213,18 @@ $mw->after( { den_doc => '1930 Buick Marquette Phaeton' }, 'read cell from TM' ); + + is $tm->toggle_ckbutton( 1, 4 ), 0, 'toggle ckbutton 1'; + $cell_data = $tm->cell_read( 1, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 1,4 from TM' ); + + is $tm->toggle_ckbutton( 2, 4 ), 0, 'toggle ckbutton 2'; + $cell_data = $tm->cell_read( 2, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 2,4 from TM' ); + + is $tm->toggle_ckbutton( 3, 4 ), 0, 'toggle ckbutton 3'; + $cell_data = $tm->cell_read( 3, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 3,4 from TM' ); } ); @@ -194,11 +246,11 @@ $mw->after( sub { $tm->add_row; my ( $r, $i ) = ( 1, 0 ); - $tm->write_row( $r, $records->[$i] ); - is $tm->get_selected, $r, "selected button '$r'"; + $tm->write_row( $r, $records_exp->[$i] ); my ( $data, $scol ) = $tm->data_read(); - cmp_deeply( $data->[$i], $records->[$i], 'read data from TM after add' ); - cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + cmp_deeply( $data->[$i], $records_exp->[$i], + 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records_exp->[$i], "data for row $r"; } ); @@ -209,11 +261,11 @@ $mw->after( sub { $tm->add_row; my ( $r, $i ) = ( 2, 1 ); - $tm->write_row( $r, $records->[$i] ); - is $tm->get_selected, $r, "selected button '$r'"; + $tm->write_row( $r, $records_exp->[$i] ); my ( $data, $scol ) = $tm->data_read(); - cmp_deeply( $data->[$i], $records->[$i], 'read data from TM after add' ); - cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + cmp_deeply( $data->[$i], $records_exp->[$i], + 'read data from TM after add' ); + cmp_deeply $tm->read_row($r), $records_exp->[$i], "data for row $r"; } ); @@ -224,17 +276,46 @@ $mw->after( sub { $tm->add_row; my ( $r, $i ) = ( 3, 2 ); - $tm->write_row( $r, $records->[$i] ); - is $tm->get_selected, $r, "selected button '$r'"; + $tm->write_row( $r, $records_exp->[$i] ); my ( $data, $scol ) = $tm->data_read(); - cmp_deeply( $data->[$i], $records->[$i], + cmp_deeply( $data->[$i], $records_exp->[$i], 'read data from TM after add' ); - cmp_deeply $tm->read_row($r), $records->[$i], "data for row $r"; + cmp_deeply $tm->read_row($r), $records_exp->[$i], "data for row $r"; my $r_data = $tm->read_row($r); - is $tm->has_embeded_widget('tip_doc'), 1, - 'tip_doc has emebeded widget'; + is $tm->has_embeded_widget('tip_doc'), 1, 'tip_doc has emebeded widget'; is $tm->has_embeded_widget('den_doc'), '', - 'den_doc has no emebeded widget'; + 'den_doc has no emebeded widget'; + } +); + +$delay++; + +$mw->after( + $delay * $milisec, + sub { + # Mouse click on the checkbox + + my $cell_data; + $cell_data = $tm->cell_read( 1, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 1,4 from TM' ); + + $cell_data = $tm->cell_read( 2, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 2,4 from TM' ); + + $cell_data = $tm->cell_read( 3, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 3,4 from TM' ); + + $tm->mouse_click_ckbutton(1, 4); + $cell_data = $tm->cell_read( 1, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 1,4 from TM' ); + + $tm->mouse_click_ckbutton(2, 4); + $cell_data = $tm->cell_read( 2, 4 ); + cmp_deeply( $cell_data, { valid_doc => 1 }, 'read cell 2,4 from TM' ); + + $tm->mouse_click_ckbutton(3, 4); + $cell_data = $tm->cell_read( 3, 4 ); + cmp_deeply( $cell_data, { valid_doc => 0 }, 'read cell 3,4 from TM' ); } );