Config-Model-TkUI
view release on metacpan or search on metacpan
lib/Config/Model/TkUI.pm view on Meta::CPAN
}
sub reload {
my $cw = shift;
carp "reload: too many parameters" if @_ > 1;
my $force_display_path = shift // ''; # force open editor on this path
$logger->trace( "reloading tk tree"
. ( defined $force_display_path ? " (force display $force_display_path)" : '' ) );
my $actions = $cw->{cm_actions} //= {};
# eval is required to trap bad regexp entered in filter widget
my %filter_args = map { ($_ => $cw->{$_} // '') }
qw/elt_filter_value show_only_custom hide_empty_values instance/ ;
eval {
apply_filter(actions => $actions, fd_path => $force_display_path, %filter_args);
};
if ($@) {
my $msg = $@;
say "filter error: $msg";
$msg =~ s/at lib.*//s; # remove file from error message
$cw->show_message("filter error: $msg");
}
my $tree = $cw->{tktree};
my $instance_name = $cw->{instance}->name;
my $root = $cw->{instance}->config_root;
my $new_drawing = not $tree->infoExists($instance_name);
my $scan_root = sub {
my $opening = shift ;
$tree->itemConfigure($instance_name, 2, -text => $root->fetch_gist);
$cw->{scanner}->scan_node( [ $instance_name, $cw, $opening, $actions, $force_display_path ], $root );
};
if ($new_drawing) {
$tree->add( $instance_name, -data => [ $scan_root, $root ] );
$tree->itemCreate( $instance_name, 0, -text => $instance_name, );
$tree->itemCreate( $instance_name, 2, -text => '' );
$tree->setmode( $instance_name, 'close' );
$tree->open($instance_name);
}
# the first parameter indicates that we are opening the root
$scan_root->( 1 );
$cw->{editor}->reload if defined $cw->{editor};
}
# call-back when Tree element is selected
sub on_browse {
my ( $cw, $path ) = @_;
$cw->update_loc_bar($path);
$cw->update_history($path);
$cw->create_element_widget('view');
}
sub update_loc_bar {
my ( $cw, $path ) = @_;
#$cw->{path}=$path ;
my $datar = $cw->{tktree}->infoData($path);
my $obj = $datar->[1];
my $loc = $cw->{location} = $obj->location_short;
return $loc;
}
sub update_history ($cw, $loc) {
my $history = $cw->{path_history};
# avoid consecutive duplicated entries
if ($history->@* > 1 and $loc eq $history->[-1]) {
return;
}
push $history->@*, $loc;
my $path_idx = $cw->{path_index} = $history->$#*;
# enable previous button when history has more than one item
$cw->Subwidget('prev_btn')->configure(-state => $path_idx > 0 ? 'normal' : 'disabled');
my $h_cascade = $cw->Subwidget('history');
my $max_count = 20;
$cw->{history_count} //= 0;
if ($cw->{history_count}++ > $max_count) {
# delete all history entries from the menu
$h_cascade->menu->delete(0, 'end');
# Add the last $max_count history entries to the menu
for (my $i = 0; $i <= $max_count; $i++) {
my $entry_idx = $path_idx - $i;
$h_cascade->menu->add(
'command',
-label => $history->[$entry_idx],
-command =>sub { $cw->go_to_loc($path_idx); }
);
}
}
else {
# add a menu entry
$h_cascade->command(
-label => $loc,
-command => sub { $cw->go_to_loc($path_idx); }
);
}
return;
}
sub go_to_loc ($cw, $idx) {
my $path = $cw->{path_history}[$idx];
my $loc = $cw->update_loc_bar($path);
# enable previous button when history has more than one item
$cw->Subwidget('prev_btn')->configure(-state => $idx > 0 ? 'normal' : 'disabled');
# when jumping into history, the next location does not make
# sense, hence next button is disabled
$cw->Subwidget('next_btn')->configure(-state => 'disabled');
$cw->force_display($path, $loc);
$cw->create_element_widget('view', $path);
}
sub go_to_previous ($cw) {
my $idx = --$cw->{path_index};
my $path = $cw->{path_history}[$idx];
my $loc = $cw->update_loc_bar($path);
$cw->Subwidget('prev_btn')->configure(-state => $idx > 0 ? 'normal' : 'disabled');
lib/Config/Model/TkUI.pm view on Meta::CPAN
my $sub_elt = $elt->fetch_with_id($idx);
# check for display order mismatch
if ( $tkt->infoExists($newpath) ) {
if ( $prevpath ne $tk_previous_path{$newpath} ) {
$logger->trace(
"disp_hash deleting mismatching $newpath mode $eltmode cargo_type $elt_type");
$tkt->delete( entry => $newpath );
}
}
# check for content mismatch
if ( $tkt->infoExists($newpath) ) {
my $previous_data = $tkt->info( data => $newpath );
# $previous_data is an object (or an empty string to avoid warnings)
my $previous_elt = $previous_data->[1] || '';
$eltmode = $tkt->getmode($newpath); # will reuse mode below
$logger->trace( "disp_hash reuse $newpath mode $eltmode cargo_type $elt_type"
. " obj $previous_elt (expect $sub_elt)" );
# string comparison of objects is intentional to check that the tree
# refers to the correct Config::Model object
if ( $sub_elt ne $previous_elt ) {
$logger->trace( "disp_hash delete $newpath mode $eltmode (got "
. "$previous_elt expected $sub_elt)" );
# wrong order, delete the entry
$tkt->delete( entry => $newpath );
}
}
if ( not $tkt->infoExists($newpath) ) {
my @opt = $prevpath ? ( -after => $prevpath ) : ( -at => 0 );
$logger->trace(
"disp_hash add $newpath mode $eltmode cargo_type $elt_type" . " elt $sub_elt" );
my @data = ( $scan_sub, $sub_elt );
weaken( $data[1] );
$tkt->add( $newpath, -data => \@data, @opt );
$tkt->itemCreate( $newpath, 0, -text => $node->shorten_idx($idx) );
$tkt->setmode( $newpath => $eltmode );
}
# update the node gist
my $gist = $elt_type =~ /node/ ? $elt->fetch_with_id($idx)->fetch_gist : '';
$tkt->itemCreate( $newpath, 2, -text => $gist );
my $elt_loc = $sub_elt->location;
# hide new entry if hash is not yet opened
$cw->setmode( 'hash', $newpath, $eltmode, $elt_loc, $opening, $actions, $scan_sub );
if ( $force_display_path and $force_display_path eq $elt_loc ) {
$cw->force_display($newpath, $elt_loc)
}
$prevpath = $newpath;
}
}
sub update_hash_image {
my ( $cw, $elt, $path ) = @_;
my $tkt = $cw->{tktree};
# check hash status and set warning image if necessary
my $img;
{
no warnings qw/uninitialized/;
$img = $warn_img if $elt->warning_msg;
}
if ( defined $img ) {
$tkt->itemCreate( $path, 1, -itemtype => 'image', -image => $img );
}
else {
$tkt->itemDelete( $path, 1 ) if $tkt->itemExists( $path, 1 );
}
}
sub setmode {
my ( $cw, $type, $newpath, $eltmode, $elt_loc, $opening, $actions, $scan_sub ) = @_;
my $tkt = $cw->{tktree};
$actions->{$elt_loc} //= '';
my $force_open = $actions->{$elt_loc} eq 'show' ? 1 : 0;
my $force_close = $actions->{$elt_loc} eq 'hide' ? 1 : 0;
$logger->trace( "$type: elt_loc '$elt_loc', opening $opening "
. "eltmode $eltmode force_open $force_open");
if ( not $force_close and ($eltmode ne 'open' or $force_open or $opening )) {
$tkt->show( -entry => $newpath );
# counter-intuitive: want to display [-] if force opening and not leaf item
$tkt->setmode( $newpath => 'close' ) if ( $force_open and $eltmode ne 'none' );
}
elsif ($force_close and $eltmode eq 'open') {
$tkt->hide( -entry => $newpath );
}
else {
$tkt->close($newpath);
}
# counterintuitive but right: scan will be done when the entry
# is opened. mode can be open, close, none
$scan_sub->( $force_open ) if ( ( $eltmode ne 'open' ) or $force_open );
}
sub trim_value {
my $cw = shift;
my $value = shift;
# undef value required lest Tk dies with:
# value for "-text" missing at /usr/lib/x86_64-linux-gnu/perl5/5.28/Tk.pm line 251
return undef unless defined $value; ## no critic(Subroutines::ProhibitExplicitReturnUndef)
$value =~ s/\n/ /g;
$value = substr( $value, 0, 15 ) . '...' if length($value) > 15;
return $value;
}
( run in 0.467 second using v1.01-cache-2.11-cpan-d7f47b0818f )