#
# This file is part of Config-Model
#
# This software is Copyright (c) 2014 by Dominique Dumont.
#
# This is free software, licensed under:
#
# The GNU Lesser General Public License, Version 2.1, February 1999
#
package Config::Model::CheckList ;
$Config::Model::CheckList::VERSION = '2.054';
use Mouse ;
use 5.010 ;
use Config::Model::Exception ;
use Config::Model::IdElementReference ;
use Config::Model::Warper ;
use List::MoreUtils qw/any none/;
use Carp;
use Log::Log4perl qw(get_logger :levels);
use Storable qw/dclone/;
extends qw/Config::Model::AnyThing/ ;
my $logger = get_logger("Tree::Element::CheckList") ;
my @introspect_params = qw/refer_to computed_refer_to/ ;
my @accessible_params = qw/default_list upstream_default_list choice ordered/ ;
my @allowed_warp_params = (@accessible_params, qw/level experience/);
has [qw/backup data preset layered/]
=> ( is => 'rw', isa => 'HashRef' , default => sub { {} ;} ) ;
has computed_refer_to => ( is => 'rw', isa => 'Maybe[HashRef]' ) ;
has [qw/refer_to/] => ( is => 'rw', isa => 'Str' ) ;
has [qw/ordered_data choice/]
=> ( is => 'rw', isa => 'ArrayRef' , default => sub { [] ;} ) ;
has [qw/ordered/] => (is => 'ro', isa => 'Bool' ) ;
has [qw/warp help/] => (is => 'rw', isa => 'Maybe[HashRef]') ;
around BUILDARGS => sub {
my $orig = shift ;
my $class = shift ;
my %args = @_ ;
my %h = map { ( $_ => $args{$_}) ;} grep {defined $args{$_}} @allowed_warp_params;
return $class->$orig( backup => dclone (\%h), @_ );
} ;
sub BUILD {
my $self = shift;
if (defined $self->refer_to or defined $self->computed_refer_to) {
$self->submit_to_refer_to() ;
}
$self->set_properties() ; # set will use backup data
if (defined $self->warp) {
my $warp_info = $self->warp ;
$self->{warper} = Config::Model::Warper->new (
warped_object => $self,
%$warp_info ,
allowed => \@allowed_warp_params
) ;
}
$self->cl_init ;
$logger->info("Created check_list element ".$self->element_name);
return $self ;
}
sub cl_init {
my $self = shift ;
$self->warp if ($self->{warp});
if (defined $self->{ref_object} ) {
my $level = $self->parent
-> get_element_property(element => $self->{element_name},
property => 'level',
) ;
$self->{ref_object}->get_choice_from_refered_to if $level ne 'hidden';
}
}
sub name {
my $self = shift ;
my $name = $self->{parent}->name . ' '.$self->{element_name} ;
return $name ;
}
sub value_type { return 'check_list' ;}
# warning : call to 'set' are not cumulative. Default value are always
# restored. Lest keeping track of what was modified with 'set' is
# too hard for the user.
sub set_properties {
my $self = shift ;
# cleanup all parameters that are handled by warp
map(delete $self->{$_}, @allowed_warp_params ) ;
if ($logger->is_debug()) {
my %h = @_;
my $keys = join(',',keys %h) ;
$logger->debug("set_properties called on $self->{element_name} with $keys");
}
# merge data passed to the constructor with data passed to set
my %args = (%{$self->{backup}},@_ );
# these are handled by Node or Warper
map { delete $args{$_} } qw/level experience/ ;
$self->{ordered} = delete $args{ordered} || 0 ;
if (defined $args{choice}) {
my @choice = @{ delete $args{choice} } ;
$self->{default_choice} = \@choice ;
$self->setup_choice( @choice ) ;
}
if (defined $args{default}) {
warn $self->name,": default param is deprecated, use default_list\n";
$args{default_list} = delete $args{default} ;
}
if (defined $args{default_list}) {
$self->{default_list} = delete $args{default_list} ;
}
# store default data in a hash (more convenient)
$self->{default_data} = { map { $_ => 1 } @{$self->{default_list}} } ;
if (defined $args{upstream_default_list}) {
$self->{upstream_default_list} = delete $args{upstream_default_list} ;
}
# store upstream default data in a hash (more convenient)
$self->{upstream_default_data} =
{ map { $_ => 1 } @{$self->{upstream_default_list}} } ;
Config::Model::Exception::Model
-> throw (
object => $self,
error => "Unexpected parameters :".join(' ', keys %args )
)
if scalar keys %args ;
}
sub setup_choice {
my $self = shift ;
my @choice = ref $_[0] ? @{$_[0]} : @_ ;
$logger->debug("CheckList $self->{element_name}: setup_choice with @choice");
# store all enum values in a hash. This way, checking
# whether a value is present in the enum set is easier
delete $self->{choice_hash} if defined $self->{choice_hash} ;
map {$self->{choice_hash}{$_} = 1;} @choice ;
$self->{choice} = \@choice ;
# cleanup current preset and data if it does not fit current choices
foreach my $field (qw/preset data layered/) {
next unless defined $self->{$field} ; # do not create if not present
foreach my $item (keys %{$self->{$field}}) {
delete $self->{$field}{$item} unless defined $self->{choice_hash}{$item} ;
}
}
}
# Need to extract Config::Model::Reference (used by Value, and maybe AnyId).
sub submit_to_refer_to {
my $self = shift ;
if (defined $self->refer_to) {
$self->{ref_object} = Config::Model::IdElementReference -> new (
refer_to => $self->refer_to ,
config_elt => $self,
) ;
}
elsif (defined $self->computed_refer_to) {
$self->{ref_object} = Config::Model::IdElementReference -> new (
computed_refer_to => $self->computed_refer_to ,
config_elt => $self,
) ;
my $var = $self->{computed_refer_to}{variables} ;
# refer_to registration is done for all element that are used as
# variable for complex reference (ie '- $foo' , {foo => '- bar'} )
foreach my $path (values %$var) {
# is ref during test case
#print "path is '$path'\n";
next if $path =~ /\$/ ; # next if path also contain a variable
my $master = $self->grab($path);
next unless $master->can('register_dependency');
$master->register_dependency($self) ;
}
}
else {
croak "checklist submit_to_refer_to: undefined refer_to or computed_refer_to" ;
}
}
sub setup_reference_choice {
my $self = shift ;
$self->setup_choice(@_) ;
}
sub get_type {
my $self = shift;
return 'check_list' ;
}
sub get_cargo_type { goto &cargo_type }
sub cargo_type {
my $self = shift ;
return 'leaf' ;
}
sub apply_fixes {
# no operation. THere's no check_value method because a check list
# supposed to be always correct. Hence apply_fixes is empty.
}
# does not check the validity, but check the item of the check_list
sub check {
my $self = shift ;
my @list = ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_ ;
my %args = ref $_[0] eq 'ARRAY' ? @_[1,$#_] : (check => 'yes') ;
my $check = $self->_check_check ($args{check}) ;
if (defined $self->{ref_object}) {
$self->{ref_object}->get_choice_from_refered_to ;
}
my @changed ;
map {push @changed,$_ if $self->store($_ , 1, $check ) } @list ;
$self->notify_change(note => "check @changed")
unless $self->instance->initial_load;
}
sub clear_item {
my $self = shift;
my $choice = shift;
my $inst = $self->instance;
my $data_name =
$inst->preset ? 'preset'
: $inst->layered ? 'layered'
: 'data';
my $old_v = $self->{$data_name}{$choice};
my $changed = 0;
if ( $old_v ) {
$changed = 1;
}
delete $self->{$data_name}{$choice} ;
if ( $self->{ordered} and $changed) {
my $ord = $self->{ordered_data};
my @new = grep { $_ ne $choice } @$ord;
$self->{ordered_data} = \@new ;
}
return $changed;
}
# internal
sub store {
my ($self, $choice, $value, $check) = @_;
my $inst = $self->instance ;
if ($value != 0 and $value != 1) {
Config::Model::Exception::WrongValue
-> throw ( error => "store: check item value must be boolean, "
. "not '$value'.",
object => $self) ;
return ;
}
my $ok = $self->{choice_hash}{$choice} || 0 ;
my $changed = 0;
if ($ok ) {
my $data_name = $inst->preset ? 'preset'
: $inst->layered ? 'layered'
: 'data';
my $old_v = $self->{$data_name}{$choice} ;
if ( not defined $old_v or $old_v ne $value) {
$changed = 1;
$self->{$data_name}{$choice} = $value ;
}
if ($self->{ordered} and $value) {
my $ord = $self->{ordered_data} ;
push @$ord,$choice unless scalar grep {$choice eq $_} @$ord ;
}
}
elsif ($check eq 'yes') {
my $err_str = "Unknown check_list item '$choice'. Expected '"
. join("', '",@{$self->{choice}}) . "'" ;
$err_str .= "\n\t". $self->{ref_object}->reference_info
if defined $self->{ref_object};
Config::Model::Exception::WrongValue
-> throw ( error => $err_str , object => $self) ;
}
return $changed ;
}
sub uncheck {
my $self = shift ;
my @list = ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_ ;
my %args = ref $_[0] eq 'ARRAY' ? @_[1,$#_] : (check => 'yes') ;
my $check = $self->_check_check ($args{check}) ;
if (defined $self->{ref_object}) {
$self->{ref_object}->get_choice_from_refered_to ;
}
my @changed ;
map { push @changed, $_ if $self->store($_ , 0, $check ) } @list ;
$self->notify_change(note => "uncheck @changed")
unless $self->instance->initial_load;
}
my %accept_mode = map { ( $_ => 1) }
qw/custom standard preset default layered upstream_default user/;
sub is_checked {
my $self = shift ;
my $choice = shift ;
my %args = @_ ;
my $mode = $args{mode} || '';
my $check = $self->_check_check($args{check}) ;
my $ok = $self->{choice_hash}{$choice} || 0 ;
if ($ok ) {
if ($mode and not defined $accept_mode{$mode}) {
croak "is_checked: expected ", join (' or ',keys %accept_mode),
"parameter, not $mode" ;
}
my $dat = $self->{data}{$choice} ;
my $pre = $self->{preset}{$choice} ;
my $def = $self->{default_data}{$choice} ;
my $ud = $self->{upstream_default_data}{$choice} ;
my $lay = $self->{layered}{$choice} ;
my $std_v = $pre // $def // 0 ;
my $user_v = $dat // $pre // $lay // $def // $ud // 0 ;
my $result
= $mode eq 'custom' ? ( $dat && ! $std_v ? 1 : 0 )
: $mode eq 'preset' ? $pre
: $mode eq 'layered' ? $lay
: $mode eq 'upstream_default' ? $ud
: $mode eq 'default' ? $def
: $mode eq 'standard' ? $std_v
: $mode eq 'user' ? $user_v
: $dat // $std_v ;
return $result ;
}
elsif ($check eq 'yes') {
my $err_str = "Unknown check_list item '$choice'. Expected '"
. join("', '",@{$self->{choice}}) . "'" ;
$err_str .= "\n\t". $self->{ref_object}->reference_info
if defined $self->{ref_object};
Config::Model::Exception::WrongValue
-> throw ( error => $err_str ,
object => $self) ;
}
}
# get_choice is always called when using check_list, so having a
# warp safety check here makes sense
sub get_choice {
my $self = shift ;
if (defined $self->{ref_object}) {
$self->{ref_object}->get_choice_from_refered_to ;
}
if (not defined $self->{choice}) {
my $msg = "check_list element has no defined choice. " .
$self->warp_error;
Config::Model::Exception::UnavailableElement
-> throw (
info => $msg,
object => $self->parent,
element => $self->element_name,
) ;
}
return @{ $self->{choice} } ;
}
sub get_default_choice {
my $self = shift ;
return @{$self->{default_choice} || [] } ;
}
sub get_builtin_choice {
carp "get_builtin_choice is deprecated, use get_upstream_default_choice";
goto &get_upstream_default_choice ;
}
sub get_upstream_default_choice {
my $self = shift ;
return @{$self->{upstream_default_data} || [] } ;
}
sub get_help {
my $self = shift ;
my $help = $self->{help} ;
return $help unless @_ ;
my $on_value = shift ;
return $help->{$on_value} if defined $help and defined $on_value ;
return ;
}
sub clear {
my $self = shift ;
map { $self->clear_item($_) } $self->get_choice ; # also triggers notify changes
}
sub clear_values { goto &clear ; }
sub clear_layered {
my $self = shift;
$self->{layered} = {};
}
my %old_mode = ( built_in_list => 'upstream_default_list',
);
sub get_checked_list_as_hash {
my $self = shift ;
my %args = @_ > 1 ? @_ : (mode => $_[0]) ;
my $mode = $args{mode}|| '';
foreach my $k (keys %old_mode) {
next unless $mode eq $k;
$mode = $old_mode{$k} ;
carp $self->location," warning: deprecated mode parameter: $k, ",
"expected $mode\n";
}
if ($mode and not defined $accept_mode{$mode}) {
croak "get_checked_list_as_hash: expected ",
join (' or ',keys %accept_mode),
" parameter, not $mode" ;
}
my $dat = $self->{data} ;
my $pre = $self->{preset} ;
my $def = $self->{default_data} ;
my $lay = $self->{layered} ;
my $ud = $self->{upstream_default_data} ;
# fill empty hash result
my %h = map { $_ => 0 } $self->get_choice ;
my %predef = (%$def, %$pre ) ;
my %std = (%$ud, %$lay, %$def, %$pre ) ;
# use _std_backup if all data values are null (no checked items by user)
my %old_dat = (none { $_ ;} values %$dat) ? %{$self->{_std_backup} || {}} : %$dat ;
if (not $mode and any {$_;} values %predef and none { $_ ;} values %old_dat) {
# changed from nothing to default checked list that must be written
$self->{_std_backup} = { %$def, %$pre } ;
$self->notify_change(note => "use default checklist") ;
}
# custom test must compare the whole list at once, not just one item at a time.
my %result =
$mode eq 'custom' ? ( ( grep { $dat->{$_} xor $std{$_} } keys %h ) ? ( %$pre, %$dat ) : () )
: $mode eq 'preset' ? (%$pre)
: $mode eq 'layered' ? (%$lay)
: $mode eq 'upstream_default' ? (%$ud)
: $mode eq 'default' ? (%$def)
: $mode eq 'standard' ? %std
: $mode eq 'user' ? ( %h, %std, %$dat )
: ( %predef, %$dat );
return wantarray ? %result : \%result;
}
sub get_checked_list {
my $self = shift ;
my %h = $self->get_checked_list_as_hash(@_) ;
my @good_order = $self->{ordered} ? @{$self->{ordered_data}} : sort keys %h ;
my @res = grep { $h{$_} } @good_order ;
return wantarray ? @res : \@res ;
}
sub fetch {
my $self = shift ;
return join (',', $self->get_checked_list(@_));
}
sub fetch_custom {
my $self = shift ;
return join (',', $self->get_checked_list('custom'));
}
sub fetch_preset {
my $self = shift ;
return join (',', $self->get_checked_list('preset'));
}
sub fetch_layered {
my $self = shift ;
return join (',', $self->get_checked_list('layered'));
}
sub get {
my $self = shift ;
my $path = shift ;
if ($path) {
Config::Model::Exception::User
-> throw (
object => $self,
message => "get() called with a value with non-empty path: '$path'"
) ;
}
return $self->fetch(@_) ;
}
sub set {
my $self = shift ;
my $path = shift ;
my $list = shift ;
if ($path) {
Config::Model::Exception::User
-> throw (
object => $self,
message => "set() called with a value with non-empty path: '$path'"
) ;
}
return $self->set_checked_list(split /,/,$list) ;
}
sub load {
my ($self,$string) = @_ ;
my @set = split /,/,$string;
foreach (@set) { s/^"|"$//g; s/\\"/"/g ;}
$self->set_checked_list(@set) ;
}
sub store_set { goto &set_checked_list }
sub set_checked_list {
my $self = shift ;
$logger->debug("called with @_");
my %set = map { $_ => 1 } @_ ;
my @changed ;
foreach my $c ($self->get_choice) {
push @changed,$c if $self->store($c , $set{$c} // 0) ;
}
$self->{ordered_data} = [ @_ ] ; # copy list
$self->notify_change(note => "set_checked_list @changed")
if @changed and not $self->instance->initial_load;
}
sub set_checked_list_as_hash {
my $self = shift ;
my %check = ref $_[0] ? %{$_[0]} : @_ ;
foreach my $c ($self->get_choice) {
if (defined $check{$c}) {
$self->store($c,$check{$c});
}
else {
$self->clear_item($c) ;
}
}
}
sub load_data {
my $self = shift ;
my %args = @_ > 1 ? @_ : ( data => shift) ;
my $data = $args{data};
my $check = $self->_check_check($args{check}) ;
if (ref ($data) eq 'ARRAY') {
$self->set_checked_list(@$data) ;
}
elsif (ref($data) eq 'HASH') {
$self->set_checked_list_as_hash($data) ;
}
else {
Config::Model::Exception::LoadData
-> throw (
object => $self,
message => "load_data called with non array ref arg",
wrong_data => $data ,
) ;
}
}
sub swap {
my ($self,$a,$b) = @_ ;
foreach my $param ($a,$b) {
unless ($self->is_checked($param)) {
my $err_str = "swap: choice $param must be set";
Config::Model::Exception::WrongValue
-> throw ( error => $err_str ,
object => $self) ;
}
}
# perform swap in ordered list
foreach (@{$self->{ordered_data}}) {
if ($_ eq $a) {
$_ = $b ;
}
elsif ($_ eq $b) {
$_ = $a ;
}
}
}
sub move_up {
my ($self,$c) = @_ ;
unless ($self->is_checked($c)) {
my $err_str = "swap: choice $c must be set";
Config::Model::Exception::WrongValue
-> throw ( error => $err_str ,
object => $self) ;
}
# perform move in ordered list
my $list = $self->{ordered_data} ;
for (my $i = 1 ; $i < @$list; $i++) {
if ($list->[$i] eq $c ) {
$list->[$i] = $list->[$i - 1 ];
$list->[$i - 1] = $c ;
last;
}
}
}
sub move_down {
my ($self,$c) = @_ ;
unless ($self->is_checked($c)) {
my $err_str = "swap: choice $c must be set";
Config::Model::Exception::WrongValue
-> throw ( error => $err_str ,
object => $self) ;
}
# perform move in ordered list
my $list = $self->{ordered_data} ;
for (my $i = 0 ; $i + 1 < @$list; $i++) {
if ($list->[$i] eq $c ) {
$list->[$i] = $list->[$i + 1 ];
$list->[$i + 1] = $c ;
last;
}
}
}
# dummy to match Value call
sub warning_msg { '' }
1;
# ABSTRACT: Handle check list element
__END__
=pod
=encoding UTF-8
=head1 NAME
Config::Model::CheckList - Handle check list element
=head1 VERSION
version 2.054
=head1 SYNOPSIS
use Config::Model;
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init($WARN);
# define configuration tree object
my $model = Config::Model->new;
$model->create_config_class(
name => "MyClass",
element => [
# type check_list will use Config::Model::CheckList
my_check_list => {
type => 'check_list',
choice => [ 'A', 'B', 'C', 'D' ],
help => {
A => 'A effect is this',
D => 'D does that',
}
},
],
);
my $inst = $model->instance( root_class_name => 'MyClass' );
my $root = $inst->config_root;
# put data
$root->load( step => 'my_check_list=A' );
my $obj = $root->grab('my_check_list');
my $v = $root->grab_value('my_check_list');
print "check_list value '$v' with help '", $obj->get_help($v), "'\n";
# more data
$obj->check('D');
$v = $root->grab_value('my_check_list');
print "check_list new value is '$v'\n"; # prints check_list new value is 'A,D'
=head1 DESCRIPTION
This class provides a check list element for a L<Config::Model::Node>.
In other words, this class provides a list of booleans items. Each item
can be set to 1 or 0.
The available items in the check list can be :
=over
=item *
A fixed list (with the C<choice> parameter)
=item *
A dynamic list where the available choice are the keys of another hash
of the configuration tree. See L</"Choice reference"> for details.
=back
=head1 CONSTRUCTOR
CheckList object should not be created directly.
=head1 CheckList model declaration
A check list element must be declared with the following parameters:
=over
=item type
Always C<checklist>.
=item choice
A list ref containing the check list items (optional)
=item refer_to
This parameter is used when the keys of a hash are used to specify the
possible choices of the check list. C<refer_to> point to a hash or list
element in the configuration tree. See L<Choice reference> for
details. (optional)
=item computed_refer_to
Like C<refer_to>, but use a computed value to find the hash or list
element in the configuration tree. See L<Choice reference> for
details. (optional)
=item default_list
List ref to specify the check list items which are "on" by default.
(optional)
=item ordered
Specify whether the order of checked items must be preserved.
=item help
Hash ref to provide information on the check list items.
=item warp
Used to provide dynamic modifications of the check list properties
See L<Config::Model::Warper> for details
=back
For example:
=over
=item *
A simple check list with help:
choice_list
=> { type => 'check_list',
choice => ['A' .. 'Z'],
help => { A => 'A help', E => 'E help' } ,
},
=item *
A check list with default values:
choice_list_with_default
=> { type => 'check_list',
choice => ['A' .. 'Z'],
default_list => [ 'A', 'D' ],
},
=item *
A check list whose available choice and default change depending on
the value of the C<macro> parameter:
'warped_choice_list'
=> { type => 'check_list',
warp => { follow => '- macro',
rules => { AD => { choice => [ 'A' .. 'D' ],
default_list => ['A', 'B' ] },
AH => { choice => [ 'A' .. 'H' ] },
}
}
},
=back
=head1 Introspection methods
The following methods returns the checklist parameter :
=over
=item refer_to
=item computed_refer_to
=back
=head1 Choice reference
The choice items of a check_list can be given by another configuration
element. This other element can be:
=over
=item *
The keys of a hash
=item *
Another checklist. In this case only the checked items of the other
checklist will be available.
=back
This other hash or other checklist is indicated by the C<refer_to> or
C<computed_refer_to> parameter. C<refer_to> uses the syntax of the
C<step> parameter of L<grab(...)|Config::AnyThing/"grab(...)">
See L<refer_to parameter|Config::Model::IdElementReference/"refer_to parameter">.
=head2 Reference examples
=over
=item *
A check list where the available choices are the keys of C<my_hash>
configuration parameter:
refer_to_list
=> { type => 'check_list',
refer_to => '- my_hash'
},
=item *
A check list where the available choices are the checked items of
C<other_check_list> configuration parameter:
other_check_list => { type => 'check_list',
choice => [qw/A B C/]
},
refer_to_list
=> { type => 'check_list',
refer_to => '- other_check_list'
},
=item *
A check list where the available choices are the keys of C<my_hash>
and C<my_hash2> and C<my_hash3> configuration parameter:
refer_to_3_lists
=> { type => 'check_list',
refer_to => '- my_hash + - my_hash2 + - my_hash3'
},
=item *
A check list where the available choices are the specified choice and
the choice of C<refer_to_3_lists> and a hash whose name is specified
by the value of the C<indirection> configuration parameter (this
example is admittedly convoluted):
refer_to_check_list_and_choice
=> { type => 'check_list',
computed_refer_to => { formula => '- refer_to_2_list + - $var',
variables { 'var' => '- indirection ' }
},
choice => [qw/A1 A2 A3/],
},
=back
=head1 Methods
=head2 get_type
Returns C<check_list>.
=head2 cargo_type()
Returns 'leaf'.
=head2 check ( ... )
Set choice. Parameter is either a list of choices to set or
a list ref and some optional parameter. I.e:
check (\@list, check => 'skip') ;
C<check> parameter decide on behavior in case of invalid
choice value: either die (if yes) or discard bad value (if skip)
=head2 uncheck (...)
Unset choice. Parameter is either a list of choices to unset or
a list ref and some optional parameter. I.e:
uncheck (\@list, check => 'skip') ;
C<check> parameter decide on behavior in case of invalid
choice value: either die (if yes) or discard bad value (if skip)
=head2 is_checked( choice, [ check => yes|skip ] , [ mode => ... ])
Return 1 if the given C<choice> was set. Returns 0 otherwise.
C<check> parameter decide on behavior in case of invalid
choice value: either die (if yes) or discard bad value (if skip)
C<mode> is either: custom standard preset default layered upstream_default
=head2 get_choice
Returns an array of all items names that can be checked (i.e.
that can have value 0 or 1).
=head2 get_help (choice_value)
Return the help string on this choice value
=head2 clear
Reset the check list (can also be called as C<clear_values>)
=head2 clear_item (choice_value)
Reset an element of the checklist.
=head2 get_checked_list_as_hash ( [ custom | preset | standard | default ] )
Returns a hash (or a hash ref) of all items. The boolean value is the
value of the hash.
Example:
{ A => 0, B => 1, C => 0 , D => 1}
By default, this method will return all items set by the user, or
items set in preset mode or checked by default.
With a parameter, this method will return either:
=over
=item custom
The list entered by the user
=item preset
The list entered in preset mode
=item standard
The list set in preset mode or checked by default.
=item default
The default list (defined by the configuration model)
=item layered
The list specified in layered mode.
=item upstream_default
The list implemented by upstream project (defined in the configuration
model)
=item user
The list set that will be active in the application. (ie. set by user or
by layered data or preset or default)
=back
=head2 get_checked_list ( < mode > )
Returns a list (or a list ref) of all checked items (i.e. all items
set to 1).
=head2 fetch ( < mode > )
Returns a string listing the checked items (i.e. "A,B,C")
=head2 get( path [, < mode> ] )
Get a value from a directory like path.
=head2 set( path , values )
Set a checklist with a directory like path. Since a checklist is a leaf, the path
should be empty. The values are a comma separated list of checked items.
Example : C<< $leaf->set('','A,C,Z') ; >>
=head2 set_checked_list ( item1, item2, ..)
Set all passed items to checked (1). All other available items
in the check list are set to 0.
Example:
# set cl to A=0 B=1 C=0 D=1
$cl->set_checked_list('B','D')
=head2 set_checked_list_as_hash ()
Set check_list items. Missing items in the given list of parameters
are cleared (i.e. set to undef).
=head2 load_data ( ref )
Load check_list as an array or hash ref. Array is forwarded to
L<set_checked_list> , and hash is forwarded to L<set_checked_list_as_hash>.
=head1 Ordered checklist methods
All the methods below are valid only for ordered checklists.
=head1 swap ( choice_a, choice_b)
Swap the 2 given choice in the list. Both choice must be already set.
=head1 move_up ( choice )
Move the choice up in the checklist.
=head1 move_down ( choice )
Move the choice down in the checklist.
=head1 AUTHOR
Dominique Dumont, (ddumont at cpan dot org)
=head1 SEE ALSO
L<Config::Model>,
L<Config::Model::Instance>,
L<Config::Model::Node>,
L<Config::Model::AnyId>,
L<Config::Model::ListId>,
L<Config::Model::HashId>,
L<Config::Model::Value>
=head1 AUTHOR
Dominique Dumont
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by Dominique Dumont.
This is free software, licensed under:
The GNU Lesser General Public License, Version 2.1, February 1999
=cut