File Coverage

blib/lib/Script/Toolbox/Util/Menues.pm
Criterion Covered Total %
statement 6 173 3.4
branch 0 76 0.0
condition 0 3 0.0
subroutine 2 29 6.9
pod 0 19 0.0
total 8 300 2.6


line stmt bran cond sub pod time code
1             package Script::Toolbox::Util::Menues;
2              
3 10     10   34 use strict;
  10         10  
  10         254  
4 10     10   27 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  10         8  
  10         16757  
5              
6             require Exporter;
7              
8             @ISA = qw(Exporter);
9             # Items to export into callers namespace by default. Note: do not export
10             # names by default without a very good reason. Use EXPORT_OK instead.
11             # Do not simply export all your public functions/methods/constants.
12             @EXPORT = qw(
13            
14             );
15             #$VERSION = '0.03';
16              
17              
18             # Preloaded methods go here.
19              
20             #-----------------------------------------------------------------------------
21             # {'menueName>' =>[{label=>,value=>,jump=>,argv=>},...]}
22             #-----------------------------------------------------------------------------
23             sub new
24             {
25 0     0 0   my $classname = shift;
26 0           my $self = {};
27 0           bless( $self, $classname );
28 0           $self->_init( @_ );
29 0           return $self;
30             }
31              
32             #-----------------------------------------------------------------------------
33             # {'' =>[{label=>,value=>,jump=>,argv=>},...]}
34             #-----------------------------------------------------------------------------
35             sub _init
36             {
37 0     0     my ($self, $newDef) = @_;
38              
39 0           $self->{'def'} = {};
40 0 0         return if( ref $newDef ne 'HASH' );
41 0           $self->addMenue($newDef);
42             }
43              
44             #------------------------------------------------------------------------------
45             #------------------------------------------------------------------------------
46             sub _getHead($){
47 0     0     my ($self,$def) = @_;
48 0           my $s = '';
49 0           foreach my $k ( @{$def} ) {
  0            
50 0 0         next if( ! defined $k->{'header'} );
51 0           $s .= sprintf "%s", $k->{'header'};
52             }
53 0 0         return $s ne '' ? $s : undef;
54             }
55             #------------------------------------------------------------------------------
56             #------------------------------------------------------------------------------
57             sub _getFoot($){
58 0     0     my ($self,$def) = @_;
59 0           my $s = '';
60 0           foreach my $k ( @{$def} ) {
  0            
61 0 0         next if( ! defined $k->{'footer'} );
62 0           $s .= sprintf "%s", $k->{'footer'};
63             }
64 0 0         return $s ne '' ? $s : undef;
65             }
66              
67             #------------------------------------------------------------------------------
68             # ...
69             # {'label'=>'Call the submenue 1','jump'=>'SubMenue1'}
70             # SubMenue1: is the name of a previous defined menue in the same menues container
71             #------------------------------------------------------------------------------
72             sub _resolveSubmenue($){
73 0     0     my ($self,$opt) = @_;
74              
75 0 0         return if( !defined $opt->{'jump'} );
76 0 0         return if( ref \$opt->{'jump'} ne 'SCALAR' );
77              
78 0           my $subName = $opt->{'jump'};
79 0           $opt->{'jump'} = \&Script::Toolbox::Util::Menues::run;
80 0           $opt->{'argv'} = [$self,$subName];
81 0           return;
82             }
83              
84             #------------------------------------------------------------------------------
85             # [{label=>,value=>,jump=>,argv=>},...]}
86             #------------------------------------------------------------------------------
87             sub _getOpts($){
88 0     0     my ($self,$def) = @_;
89 0           my @s;
90 0           foreach my $k ( @{$def} ) {
  0            
91 0 0         next if( ! defined $k->{'label'} );
92 0           $self->_resolveSubmenue($k);
93 0           push @s, $k;
94             }
95 0           return \@s;
96             }
97              
98             #------------------------------------------------------------------------------
99             # , [{label=>,value=>,jump=>,argv=>},...]}
100             #------------------------------------------------------------------------------
101             sub addMenue($){
102 0     0 0   my ($self,$newDef) = @_;
103              
104 0 0         return if( ref $newDef ne 'HASH' );
105              
106 0           foreach my $name ( keys %{$newDef} ){
  0            
107 0           my $def = $newDef->{$name};
108 0           $self->{'def'}{$name}{'head'} = $self->_getHead($def);
109 0           $self->{'def'}{$name}{'foot'} = $self->_getFoot($def);
110 0           $self->{'def'}{$name}{'opts'} = $self->_getOpts($def);
111             }
112 0           return;
113             }
114              
115             #------------------------------------------------------------------------------
116             # ,
117             #------------------------------------------------------------------------------
118             sub setHeader($$){
119 0     0 0   my ($self,$name,$head) = @_;
120              
121 0           $self->{'def'}{$name}{'head'} = $head;
122 0           return;
123             }
124              
125              
126             #------------------------------------------------------------------------------
127             # ,
128             #------------------------------------------------------------------------------
129             sub setAutoHeader($){
130 0     0 0   my ($self,$name) = @_;
131            
132 0 0         if( defined $name) {
133 0           $self->{'def'}{$name}{'autohead'} = 1;
134 0           return;
135             }
136 0           foreach my $n (keys %{$self->{'def'}} ){
  0            
137 0           $self->{'def'}{$n}{'autohead'} = 1;
138             }
139             }
140              
141             #------------------------------------------------------------------------------
142             #------------------------------------------------------------------------------
143             sub _delAutoHead($){
144 0     0     my ($ah) = @_;
145 0 0         delete $ah->{'autohead'} if( defined $ah->{'autohead'} );
146             }
147              
148             #------------------------------------------------------------------------------
149             # ,
150             #------------------------------------------------------------------------------
151             sub delAutoHeader($){
152 0     0 0   my ($self,$name) = @_;
153              
154 0 0         if( defined $name) {
155 0           _delAutoHead( $self->{'def'}{$name} );
156 0           return;
157             }
158 0           foreach my $n (keys %{$self->{'def'}} ){
  0            
159 0           _delAutoHead( $self->{'def'}{$n} );
160             }
161             }
162              
163             #------------------------------------------------------------------------------
164             # ,
165             #------------------------------------------------------------------------------
166             sub getHeader($){
167 0     0 0   my ($self,$name) = @_;
168              
169 0           my $autoHead = $self->{'def'}{$name}{'autohead'};
170 0           my $H;
171 0           my $h = $self->{'def'}{$name}{'head'};
172 0 0 0       $h = "Menue: $name" if(!defined $h && defined $autoHead);
173 0 0         $H = {'header' => $h} if( defined $h );
174              
175 0           return $H;
176             }
177              
178             #------------------------------------------------------------------------------
179             # ,
180             #------------------------------------------------------------------------------
181             sub setFooter($$){
182 0     0 0   my ($self,$name,$foot) = @_;
183              
184 0           $self->{'def'}{$name}{'foot'} = $foot;
185 0           return;
186             }
187              
188             #------------------------------------------------------------------------------
189             # ,
190             #------------------------------------------------------------------------------
191             sub getFooter($){
192 0     0 0   my ($self,$name) = @_;
193              
194 0           my $foot = $self->{'def'}{$name}{'foot'} ;
195 0 0         return {'footer'=> $foot} if(defined $foot);
196 0           return undef;
197             }
198              
199             #------------------------------------------------------------------------------
200             # , {label=>,value=>,jump=>,argv=>}
201             #------------------------------------------------------------------------------
202             sub addOption($$){
203 0     0 0   my ($self,$name,$opt) = @_;
204              
205 0 0         $self->{'def'}{$name}{'opts'} = [] if( ! defined $self->{'def'}{$name}{'opts'} );
206              
207 0           $self->_resolveSubmenue($opt);
208 0           push @{$self->{'def'}{$name}{'opts'}}, $opt;
  0            
209 0           return;
210             }
211              
212             #------------------------------------------------------------------------------
213             #------------------------------------------------------------------------------
214             sub _getParams($){
215 0     0     my ($self,$name) = @_;
216              
217 0           my @p;
218 0 0         my $s = $self->getHeader($name); push @p, $s if( defined $s );
  0            
219 0 0         $s = $self->getFooter($name); push @p, $s if( defined $s );
  0            
220 0           push @p, {'label'=>'RETURN'};
221             map {
222 0           push @p, $_;
223 0           } @{$self->{'def'}{$name}{'opts'}};
  0            
224              
225 0           return \@p;
226             }
227              
228             #------------------------------------------------------------------------------
229             # Validate parameters and rearrange parameters in case of internal menue call
230             # ( submenue call by name).
231             # Return 0 if parameters invalid.
232             #------------------------------------------------------------------------------
233             sub validateParams($$){
234 0     0 0   my ($self,$name) = @_;
235 0 0         return 0 if( ! defined $$self );
236 0 0         if( ref $$self eq 'ARRAY' ) {
237 0 0         return 0 if( ref $$self->[0] ne 'Script::Toolbox::Util::Menues' );
238 0           $$name = $$self->[1];
239 0           $$self = $$self->[0];
240             }
241 0 0         return 1 if( defined $$self->{'def'}{$$name} );
242 0           Script::Toolbox::Util::Log("\nWARNING: Submenue $$name is not defined!");
243 0           sleep 5;
244 0           return 0;
245             }
246              
247             #------------------------------------------------------------------------------
248             # Run the named menue as long as $cnt is true. $cnt will be decremented by each
249             # loop. That means if $cnt starts with 0 we have an endless loop.
250             # Return the number of the last selected option.
251             # The option 'RETURN' will be created automaticly and has option number 0 by
252             # default.
253             #------------------------------------------------------------------------------
254             sub run($$){
255 0     0 0   my ($self,$name,$cnt) = @_;
256              
257 0 0         return if( ! validateParams(\$self,\$name) );
258 0 0         $cnt = 1 if( ! defined $cnt);
259 0 0         $cnt = 1 if( $cnt !~ /^[-]?\d+$/ );
260 0 0         $cnt =-1 if( $cnt == 0 );
261 0           my $o; my $m;
262 0           while($cnt--) {
263 0           my $p = $self->_getParams($name);
264 0           ($o,$m) = Script::Toolbox::Util::Menue($p);
265 0           $self->{'def'}{$name}{'selected'}{'num'} = $o;
266 0           $self->{'def'}{$name}{'selected'}{'opt'} = $m->[$o];
267 0 0         return $o if( $o == 0 );
268             }
269 0           return $o;
270             }
271              
272             #------------------------------------------------------------------------------
273             # Return current nmber of selected option.
274             #------------------------------------------------------------------------------
275             sub currNumber($){
276 0     0 0   my ($self,$name) = @_;
277 0           return $self->{'def'}{$name}{'selected'}{'num'};
278             }
279              
280             #------------------------------------------------------------------------------
281             # Return current label of selected option.
282             #------------------------------------------------------------------------------
283             sub currLabel($){
284 0     0 0   my ($self,$name) = @_;
285 0           return $self->{'def'}{$name}{'selected'}{'opt'}{'label'};
286             }
287              
288             #------------------------------------------------------------------------------
289             # Return current value of selected option.
290             #------------------------------------------------------------------------------
291             sub currValue($){
292 0     0 0   my ($self,$name) = @_;
293 0           return $self->{'def'}{$name}{'selected'}{'opt'}{'value'};
294             }
295              
296             #------------------------------------------------------------------------------
297             # Return the callback address and argv address of selected option.
298             #------------------------------------------------------------------------------
299             sub currJump($){
300 0     0 0   my ($self,$name) = @_;
301              
302 0           my $call = $self->{'def'}{$name}{'selected'}{'opt'}{'jump'};
303 0           my $args = $self->{'def'}{$name}{'selected'}{'opt'}{'argv'};
304            
305 0           return $call,$args;
306             }
307              
308             #------------------------------------------------------------------------------
309             # Set a new label for current selected option. Return old label.
310             #------------------------------------------------------------------------------
311             sub setCurrLabel($$){
312 0     0 0   my ($self,$name,$newLabel) = @_;
313              
314 0           my $cn = $self->currNumber($name) -1;
315 0           my $ol = $self->{'def'}{$name}{'opts'}[$cn]{'label'};
316 0           $self->{'def'}{$name}{'opts'}[$cn]{'label'} = $newLabel;
317 0           return $ol;
318             }
319              
320             #------------------------------------------------------------------------------
321             # Set a new value for current selected option. Return old value.
322             #------------------------------------------------------------------------------
323             sub setCurrValue($$){
324 0     0 0   my ($self,$name,$newValue) = @_;
325              
326 0           my $cn = $self->currNumber($name) -1;
327 0           my $ov = $self->{'def'}{$name}{'opts'}[$cn]{'value'};
328 0           $self->{'def'}{$name}{'opts'}[$cn]{'value'} = $newValue;
329 0           return $ov;
330             }
331              
332             #------------------------------------------------------------------------------
333             # Set new callback address und argv for the current selected option.
334             #------------------------------------------------------------------------------
335             sub setCurrJump($$$){
336 0     0 0   my ($self,$name,$callBack,$argv) = @_;
337              
338 0           my $cn = $self->currNumber($name) -1;
339 0           $self->{'def'}{$name}{'opts'}[$cn]{'jump'} = $callBack;
340 0           $self->{'def'}{$name}{'opts'}[$cn]{'argv'} = $argv;
341 0           return $callBack,$argv;
342             }
343              
344             #------------------------------------------------------------------------------
345             #------------------------------------------------------------------------------
346             sub _invalidParam($$$$$){
347 0     0     my ($self,$name,$pattern,$search,$return) = @_;
348 0 0         return 1 if( !defined $pattern );
349 0 0         return 1 if( !defined $search );
350 0 0         return 1 if( !defined $return );
351 0 0         return 1 if( !defined $self->{'def'}{$name}{'opts'});
352 0 0         return 1 if( $search !~ /(number|value|label)/ );
353 0 0         return 1 if( $return !~ /(number|value|label)/ );
354 0           return 0;
355             }
356              
357             #------------------------------------------------------------------------------
358             # Search the labels array for $pattern matching in $search. If matching return
359             # value of type return.
360             # $pattern='[Mm]ax' $search='value' $return='label'
361             # => returns all labels where value column matching Max or max.
362             # search: /(label,number,value)/
363             # return: /(label,number,value)/
364             #------------------------------------------------------------------------------
365             sub getMatching($$$$){
366 0     0 0   my ($self,$name,$pattern,$search,$return) = @_;
367 0 0         return '' if( _invalidParam($self,$name,$pattern,$search,$return));
368              
369 0           my $L = $self->{'def'}{$name}{'opts'};
370 0           my @R;
371 0           my $i=1;
372 0           foreach my $l ( @{$L} ){
  0            
373 0 0         if( $search eq 'number' ){
374 0 0         push @R, $l->{$return} if( $i =~ /$pattern/);
375 0           $i++;
376             }else{
377 0 0         next if( !defined $l->{$search} );
378 0 0         next if( $l->{$search} !~ /$pattern/ );
379 0           push @R, $l->{$return};
380             }
381             }
382 0           return \@R;
383             }
384              
385              
386             1;
387             __END__