package Lire::UI::FileWidget; use strict; use base qw/ Curses::UI::Container Lire::UI::Widget /; use Curses::UI::Common; use Carp; use vars qw/@CARP_NOT/; use Lire::Utils qw/ check_object_param /; use Lire::UI::Utils qw/button_label/; use Locale::TextDomain 'lire'; @CARP_NOT = qw/Curses::UI::Container/; sub new { my $class = shift; my %userargs = @_; keys_to_lowercase(\%userargs); check_object_param( $userargs{'value'}, 'value', 'Lire::Config::Scalar' ); my $self = $class->Curses::UI::Container::new( %userargs, '-height' => 2, '-releasefocus' => 1, '-border' => 0 ); my $file_field = $self->add( 'file_field', 'TextEntry', '-height' => 1, '-sbborder' => 1, '-text' => $userargs{'value'}->get(), '-onchange' => \&_on_change_cb ); my $browse_btn = $self->add( 'browse_btn', 'Buttonbox', '-y' => 1, '-buttons' => [ { '-label' => button_label( __( 'Browse' )), '-onpress' => \&_browse_cb } ] ); $self->add( 'warn_label', 'Label', '-text' => '', '-y' => 1, '-bold' => '1' ); # Buttonbox as last focus in a releasefocus container # doesn't work too well with Curses::UI $self->set_focusorder( 'browse_btn', 'file_field' ); $self->_refresh_warn_label(); $self->layout(); return $self; } sub layout { my $self = $_[0]; $self->{'-height'} = 2; return $self->SUPER::layout(); } sub layout_contained_objects { my $self = $_[0]; my $browse_btn = $self->getobj( 'browse_btn' ); return $self unless $browse_btn; $browse_btn->{'-width'} = length $browse_btn->{'-buttons'}[0]{'-label'}; my $label = $self->getobj( 'warn_label' ); $label->{'-x'} = $browse_btn->{'-width'} + 1; $label->{'-width'} = length( $self->invalid_label_str() ); return $self->SUPER::layout_contained_objects() } sub refresh_view { my $self = $_[0]; my $file_widget = $self->getobj( 'file_field' ); $file_widget->text( $self->{'value'}->get() ); $self->_refresh_warn_label(); return; } sub _refresh_warn_label { my $self = $_[0]; my $warn_label = $self->getobj( 'warn_label' ); $warn_label->text( $self->{'value'}->spec()->is_valid( $self->{'value'}->get() ) ? '' : $self->invalid_label_str() ); return; } # template methods sub invalid_label_str { return __( 'Invalid filename' ); } sub browser_title_str { return __( 'Select a File'); } sub browse_dialog { my $self = $_[0]; my $file_field = $self->getobj( 'file_field' ); return $self->root()->filebrowser( '-title' => $self->browser_title_str(), '-file' => $file_field->get(), '-editfilename' => 1, '-show_hidden' => 1 ); } # callback functions sub _on_change_cb { my $file_widget = $_[0]; my $self = $file_widget->parent(); $self->{'value'}->set( $file_widget->{'-text'} ); $self->_refresh_warn_label(); $self->run_event( 'onvaluechanged' ); return; } sub _browse_cb { my $button = $_[0]; my $self = $button->parent(); my $file_field = $self->getobj( 'file_field' ); my $new_file = $self->browse_dialog(); if ( defined $new_file ) { $file_field->text( $new_file ); _on_change_cb( $file_field ); } return; } 1;