File Coverage

blib/lib/HTML/GUI/widget.pm
Criterion Covered Total %
statement 29 148 19.5
branch 0 42 0.0
condition 0 18 0.0
subroutine 10 29 34.4
pod n/a
total 39 237 16.4


line stmt bran cond sub pod time code
1             package HTML::GUI::widget;
2              
3 13     13   25096 use warnings;
  13         25  
  13         382  
4 13     13   71 use strict;
  13         26  
  13         610  
5              
6             =head1 NAME
7              
8             HTML::GUI::widget - Create and control GUI for web application
9              
10             =head1 VERSION
11              
12             Version 0.01
13              
14             =cut
15              
16             our $VERSION = '0.04';
17              
18 13     13   12957 use Locale::TextDomain qw (GUI::HTML);
  13         311796  
  13         98  
19 13     13   137933 use POSIX qw(strftime);
  13         100191  
  13         108  
20 13     13   28378 use Data::Compare;
  13         167280  
  13         96  
21 13     13   17320 use YAML::Syck;
  13         29202  
  13         1000  
22 13     13   7879 use HTML::GUI::tag;
  13         41  
  13         501  
23 13     13   8402 use HTML::GUI::log::eventList;
  13         39  
  13         170  
24              
25 13     13   17888 use Log::Log4perl qw(:easy);
  13         867951  
  13         106  
26              
27             our @ISA = qw(HTML::GUI::tag);
28              
29             =head1 WIDGET
30              
31             base class for HTML widgets
32              
33             =cut
34              
35             #the root directory to look after the screen definition
36             our $rootDirectory = '/' ;
37              
38             # Define the default values for the new widget
39             my %GHW_defaultValue = (display =>1 , constraints => []);
40              
41             # array of string : list of all public properties of the widget
42             my @publicPropList = qw/type value id display
43             constraints label title class disabled/;
44              
45              
46             =head1 PUBLIC METHODS
47              
48             =pod
49              
50             =head3 new
51              
52             Parameters :
53             params : hash ref : Contains the properties of the widget :
54             -type : text, select, checkbox
55             -value : the value of the widget
56             -id : the id of the widget (mandatory)
57             -display : if false, the fied has the propertie style="display:none"
58             -constraints : array ref of contraints names
59             -label : text associated with the fiel
60             -title : title to display when the mouse cursor is over the widget
61             -class : css class to associate with the widget
62             -disabled : the widget is disabled or not
63              
64             Return :
65            
66              
67             Description :
68             create a new html widget.
69             It can be feed with data manually or automatically with a hash.
70              
71             =cut
72              
73             sub new
74             {
75 1     1   1314 my($class,
76             $params) = @_;
77 1         181 my $this = $class->SUPER::new($params);
78              
79 0           foreach my $propName(@publicPropList){
80 0 0         if (exists $params->{$propName}){
81 0           $this->{$propName} = $params->{$propName};
82             #we don't like undef as property value
83 0 0         $this->{$propName} = '' unless defined $this->{$propName};
84             }else{
85 0   0       $this->{$propName} =
86             $GHW_defaultValue{$propName} ||"";
87             }
88             }
89 0           $this->{alert} = [];
90 0           $this->{debug} = [];
91              
92 0           $this->{style} = [];
93 0           $this->{class} = [];
94            
95 0           $this->{parent} = undef; #a ref to the parent widget
96              
97 0           bless($this, $class);
98             }
99              
100              
101             =head1 FACTORY
102              
103             instantiante any widget previously serialized
104              
105             =cut
106              
107             =pod
108              
109             =head3 instantiate
110              
111             Create widgets from the data structure $data
112             This is a class method so it should be use like this :
113             HTML::GUI::widget->instantiate($myString)
114              
115             Parameters :
116             -$data : the data structure which describe the widgets
117             -$path : the path (used to name the screen objects)
118              
119             Return :
120             a widget or undef if the $data is not correct
121              
122             =cut
123              
124             sub instantiate {
125 0     0     my ($class,$data,$path) = @_;
126              
127 0 0 0       if (!$data || !exists $data->{type}){
128 0           return undef;
129             }
130 0           my $wtype = $data->{type}.'::' ;
131 0 0         if (!exists $HTML::GUI::{$wtype}){
132 0           my $moduleFilename = $data->{type}.'.pm';
133 0 0         if ($moduleFilename !~ '::'){
134             #no namespace specified => this is a HTML::GUI native
135             #widget
136 0           $moduleFilename = 'HTML::GUI::'.$moduleFilename;
137             }
138             #convert module name to fileName
139 0           $moduleFilename =~ s/::/\//g;
140              
141 0           require $moduleFilename;
142             }
143              
144             # Rastafarian code inside !!
145             # Automatic instantation of widgets
146             # We explore the available packages to instantiate
147             # the good objects (see perlmod and perlobj for more explanation
148             # about this particular notation).
149              
150 0           my $package = $HTML::GUI::{$wtype};
151 0           my $constructor = $package->{new};
152 0           return &$constructor('HTML::GUI::'.$data->{type},$data,$path);
153              
154             }
155              
156             =pod
157              
158             =head3 instantiateFromYAML
159              
160             Instantiante a widget from a yaml string
161             This is a class method so it should be use like this :
162             HTML::GUI::widget->instantiateFromYAML($myString)
163              
164             parameters :
165             - $class : the className
166             - $yamlString : the yaml string describing the widget
167             - $path : the path (used to name the screen objects)
168              
169             returns :
170             -the new widget or undef if the yaml does not describe a widget
171              
172             =cut
173              
174             sub instantiateFromYAML{
175 0     0     my ($class,$yamlString,$path) = @_;
176              
177 0           $YAML::Syck::ImplicitTyping =1 ;
178 0           $YAML::Syck::ImplicitUnicode=1; #try to get correct utf8 handling
179 0           my $descriptionData = YAML::Syck::Load($yamlString);
180 0           return HTML::GUI::widget->instantiate($descriptionData,$path);
181              
182             }
183             =pod
184              
185             =head3 setParent
186              
187             Return :
188             nothing
189              
190             Description :
191             set the reference to the parent of the widget in the widget tree
192              
193             =cut
194              
195             sub setParent
196             {
197 0     0     my($self,$parent) = @_;
198 0           $self->{parent} = $parent;
199              
200             }
201              
202             =pod
203              
204             =head3 top
205              
206             Return :
207             the root of the widget tree or itself if the widget doesn't belong to
208             any container
209              
210             =cut
211             sub top {
212 0     0     my($self) = @_;
213 0 0         if (defined $self->{parent}){
214 0           return $self->{parent}->top();
215             }else{
216 0           return $self;
217             }
218             }
219              
220              
221             =pod
222              
223             =head3 setRootDirectory
224              
225             Description :
226             Define the root Directory of the screen definitions
227              
228             =cut
229              
230             sub setRootDirectory
231             {
232 0     0     my ($class,$rootDir)=@_;
233 0           $HTML::GUI::widget::rootDirectory = $rootDir;
234             }
235              
236             =pod
237              
238             =head3 getRootAncestor
239              
240             Description :
241             search the root of the current widget tree.
242              
243             Return :
244             The root object of the current tree
245              
246             =cut
247             sub getRootAncestor
248             {
249 0     0     my($self) = @_;
250 0 0         if (defined $self->{parent}){
251 0           return $self->{parent}->getRootAncestor();
252             }else{
253 0           return $self;
254             }
255             }
256              
257             =pod
258              
259             =head3 getHtml
260              
261             Parameters :
262              
263             Return :
264             string
265              
266             Description :
267             Return the html of the widget.
268              
269             =cut
270              
271             sub getHtml
272             {
273 0     0     my($self ) = @_;
274             #UML_MODELER_BEGIN_PERSONAL_CODE_getHtml
275             #UML_MODELER_END_PERSONAL_CODE_getHtml
276             }
277              
278              
279             =pod
280              
281             =head3 getId
282              
283             Return :
284             string
285              
286             Description :
287             return the id of the widget.
288              
289             =cut
290              
291             sub getId
292             {
293 0     0     my($self) = @_;
294 0           return $self->{id};
295             }
296              
297             =pod
298              
299             =head3 getIds
300              
301             Return :
302             array
303              
304             Description :
305             return an array of the ids of the widget.
306             For simple widget, it's the same thing as getId
307             but it's different for container which can have many widgets.
308              
309             =cut
310              
311             sub getIds
312             {
313 0     0     my($self) = @_;
314 0           return ($self->{id});
315             }
316              
317             =pod
318              
319             =head3 getTempId
320              
321             Return a new widget id who is unique for the current screen.
322              
323             =cut
324             my $idCounter = 0;
325             sub getTempId{
326 0     0     my($self) = @_;
327 0           $idCounter++;
328 0           return 'GHW::tmpId::'.$idCounter;
329             }
330              
331             =pod
332              
333             =head3 getElementById
334              
335             Parameters :
336             id : string : id of the object to find.
337              
338             Description :
339             return the widget whose id is $id or undef if no object has this id
340              
341              
342             =cut
343              
344             sub getElementById
345             {
346              
347 0     0     my($self,$id) = @_;
348              
349 0 0         return undef unless ($id eq $self->getId());
350              
351 0           return $self;
352             }
353              
354              
355             =pod
356              
357              
358             =head3 getStyleContent
359              
360             Description :
361             return the content of the html 'style' attribute
362             Parameters :
363             style : hashref : reference to a hash containing all styles attributs ; if not defined, the function use $self->style to generate a html content
364              
365             =cut
366             sub getStyleContent($$){
367 0     0     my ($self,$style)=@_;
368 0           my @styleList = ();
369 0           my $styleData = $style;
370 0           my @propNames = ();
371 0           @propNames = keys %$styleData;
372 0           @propNames = sort {$a cmp $b} @propNames; #always the same order
  0            
373              
374 0           foreach my $styleProp (@propNames){
375 0           push @styleList, $styleProp.":".$style->{$styleProp};
376             }
377            
378 0           return join ";",@styleList;
379             }
380              
381              
382              
383             =pod
384              
385             =head3 setProp
386              
387             Parameters :
388             params : hash ref : defines params value
389              
390             Return :
391            
392              
393             Description :
394            
395              
396             =cut
397              
398             sub setProp
399             {
400 0     0     my($self,
401             $params, # hash ref : defines params value
402             ) = @_;
403 0           my $pubPropHash = $self->getPubPropHash();
404 0           foreach my $propName(keys %$params){
405 0 0         if (!$pubPropHash->{$propName}){
406 0           $self->alert( __x("Propertie [{propName}] doesn't exists !!"
407             ."Can't set value [{value}] ",
408             propName => $propName,
409             value => $params->{$propName}));
410             }else{
411 0   0       $self->{$propName} = $params->{$propName} || "";
412             }
413             }
414             }
415              
416              
417             =pod
418              
419             =head3 getProp
420              
421             Parameters :
422             $propName : the name of the property we want to read
423              
424             Return :
425             - the value of the property if it exists
426             - undef if the property doesn't exists
427              
428             =cut
429              
430             sub getProp
431             {
432 0     0     my($self,
433             $propName,
434             ) = @_;
435 0           my $pubPropHash = $self->getPubPropHash();
436 0 0         if (!$pubPropHash->{$propName}){
437 0           $self->alert( __x("Propertie [{propName}] doesn't exists !!"
438             ."Can't get the value !!",
439             propName => $propName,));
440 0           return undef;
441             }else{
442 0           return $self->{$propName};
443             }
444             }
445              
446              
447             =pod
448              
449             =head3 getDefinitionData
450            
451             This method is the miror of the "new" method it generate a data structure that defines the widget, calling the "new" function with this hash ref will create the same widget. It is usefull for serialing a widget.
452             With no parameters it works for a generic widget, but it is possible to specify paramters in order to specialise the behavior for a particular class.
453             The expression "definition data" means the data that are specified when calling the 'new' function. Exemple :
454              
455             my $definitionData = {id => "textObject",
456             value=> '2'};
457              
458             my $textInputWidget = HTML::GUI::text->new($definitionData);
459              
460             Parameters :
461             - $paramPublicProp : the hash to feed with the public properties, if undef a new hash is created
462             - $paramDefaultValue : an ARRAY ref containing a list of the default values (if a propertie is set to a default value, il is not specified as a "definition data"), if undef the default values of generic widgets is used
463             - $paramPublicPropList : the list of properties that can be "definition data", if undef the list of public properties of a generic widget is used
464              
465             Return :
466             - a ref to the hash that define the public properties of the widget
467              
468             =cut
469             sub getDefinitionData($;$$$)
470             {
471 0     0     my ($self,$paramPublicProp,$paramDefaultValue, $paramPublicPropList) = @_;
472            
473 0   0       my $publicProp = $paramPublicProp || {};
474 0 0         my $defaultValues = $paramDefaultValue ?
475             $paramDefaultValue : \%GHW_defaultValue;
476 0 0         my $publicPropList = $paramPublicPropList ?
477             $paramPublicPropList :\@publicPropList;
478              
479 0           foreach my $propName(@{$publicPropList}){
  0            
480 0 0         if (exists $self->{$propName} ){
481 0           my $defaultValue = $defaultValues->{$propName};
482 0 0 0       if (defined $defaultValue
    0 0        
    0 0        
483             && Data::Compare::Compare($self->{$propName}, $defaultValue)){
484 0           next;
485             }elsif(!ref $self->{$propName}
486 0           && $self->{$propName} eq ''){
487 0           next;
488             }elsif('ARRAY' eq ref $self->{$propName}
489             && ! scalar @{$self->{$propName}}){
490 0           next;
491             }
492 0           $publicProp->{$propName} = $self->{$propName};
493             }
494             }
495 0           return $publicProp;
496             }
497              
498             =pod
499              
500             =head3 serializeToYAML
501              
502             return a string describing the current widget in YAML format
503              
504             =cut
505              
506             sub serializeToYAML
507             {
508 0     0     my ($self)=@_;
509 0           $YAML::Syck::ImplicitTyping =1 ;
510 0           $YAML::Syck::ImplicitUnicode=1; #try to get correct utf8 handling
511 0           my $dataString =YAML::Syck::Dump($self->getDefinitionData());
512             #we want a utf-8 encoded string
513             #so we convert the escape sequences (\x09...)
514 0           $dataString =~ s/\\x([0-9A-Fa-f]{2})/chr(hex($1))/eg;
  0            
515 0           return $dataString;
516             }
517              
518              
519             =pod
520              
521             =head3 writeToFile
522              
523             write the seralization of the current objet into the file $fileName.
524             Currently, only the YAML is available, so $fileName MUST be like "*.yaml"
525             Parameters :
526             - $fileName : the name of the file to write into
527             returns :
528             - 1 if the operation terminates normally
529             - 0 if a problem occurs
530              
531             =cut
532              
533             sub writeToFile
534             {
535 0     0     my ($self,$fileName)=@_;
536 0 0         if ($fileName !~ /\.yaml$/){
537             #TODO : rise an error here
538 0           return 0;
539             }
540 0           my $dataString = $self->serializeToYAML ();
541 0 0         open(FH,'>:utf8',"$fileName") or return 0 ;
542              
543 0           print FH $dataString;
544 0           close FH;
545 0           return 1;
546             }
547              
548             =pod
549              
550             =head3 instantiateFromFile
551              
552             Instantiate widgets from a file
553             Currently, only the YAML format is available, so $fileName MUST be like "*.yaml"
554             Parameters :
555             - $fileName : the name of the file to read
556             - $baseDir (optional) : the base Directory (this path is added befaor $fileName
557             to effectively locate the file on the filesystem)
558             returns :
559             - the widgets object newly created if the operation terminates normally
560             - undef if a problem occurs
561              
562             =cut
563             sub instantiateFromFile
564             {
565 0     0     my ($class,$fileName,$baseDir)=@_;
566 0           my $wholeName = '';
567              
568              
569 0 0         if (defined $baseDir){
570 0           $wholeName = $baseDir.$fileName;
571             }else{
572 0           $wholeName = $rootDirectory.$fileName;
573             }
574              
575 0 0         if (!-e $wholeName){
576 0           die "the file $wholeName doesn't exists";
577             }
578 0           undef $/; #we want to read the whole flie at once
579 0           open DATAFILE ,'<:encoding(utf8)', $wholeName;
580 0           my $whole_file = ;
581 0           close DATAFILE;
582 0 0         if ($fileName =~ /\.yaml$/){
583 0           return HTML::GUI::widget->instantiateFromYAML($whole_file,$fileName);
584             }
585 0           return undef;
586             }
587              
588             =pod
589              
590             =head3 clone
591              
592             Parameters :
593             params : hash ref : params to overload the params of the current objet (changing the id is a good idea)
594              
595             Return :
596             widget
597              
598             Description :
599            
600              
601             =cut
602              
603             sub clone
604             {
605 0     0     my($self,
606             $params, # hash ref : params to overload the params of the current objet (changing the id is a good idea)
607             ) = @_;
608             #UML_MODELER_BEGIN_PERSONAL_CODE_clone
609             #UML_MODELER_END_PERSONAL_CODE_clone
610             }
611              
612              
613             =pod
614              
615             =head3 error
616              
617             Parameters :
618             type : string : Visibility of the error (pub/priv)
619             params : hashref : params of the error
620             Description :
621             record one error in the current objet
622              
623             =cut
624              
625             sub error
626             {
627             my($self,
628             $params, # hashref : params of the error
629             ) = @_;
630             my $eventList = HTML::GUI::log::eventList::getCurrentEventList();
631             my %errorParams = ( visibility => 'pub',
632             'error-type' => 'internal',);
633             foreach my $paramName qw/visibility error-type constraint-info message/{
634             if (exists $params->{$paramName}){
635             $errorParams{$paramName} = $params->{$paramName};
636             }
637             }
638             $errorParams{widgetSrc} = $self;
639             my $errorEvent = HTML::GUI::log::error->new(\%errorParams);
640             DEBUG "ERREUR :".$errorEvent->getMessage();
641             $eventList->addEvent($errorEvent);
642             }
643              
644              
645              
646             =head3 printTime
647              
648             Parameters :
649             $time : string : a value returned by the function time
650             Description :
651             return a human readable string of the date $time
652              
653             =cut
654             sub printTime($$)
655             {
656             my ($self,$time)=@_;
657             return strftime "%a %b %e %H:%M:%S %Y", localtime($time);
658             }
659              
660             =head3 dumpStack
661              
662             Parameters :
663             stackName : string : name of the stack to convert to string
664             Description :
665             return a human readable string of the stack $stackName
666              
667             =cut
668             sub dumpStack
669             {
670             my ($self,$stackName)=@_;
671             my $dumpString="";
672             my %stackNames = (
673             error => 'error',
674             debug => 'debug',
675             alert => 'alert',
676             );
677             if (!exists $stackNames{$stackName}){
678             return "bad stack name [".$stackName."]\n";
679             }
680             foreach my $event (@{$self->{$stackName}}){
681             $dumpString .= "[".$self->printTime($event->{time})."]";
682             $dumpString .= $event->{message}."\n";
683             foreach my $frame (@{$event->{stack}}){
684             $dumpString .= " ->".$frame->{subroutine}
685             ." line:".$frame->{line}
686             ." in:".$frame->{filename}."\n";
687             }
688             $dumpString .="\n";
689             }
690             return $dumpString;
691             }
692              
693              
694             =pod
695              
696             =head3 getCurrentStack
697              
698             Description :
699             return a array of the current stack
700              
701             =cut
702             sub getCurrentStack
703             {
704             my ($self) = @_;
705             my @stack ;
706             my $i=0;
707             my ($package, $filename, $line,$subroutine) ;
708             while ($i==0 || $filename){
709             ($package, $filename, $line,$subroutine) = caller($i);
710             push @stack, {
711             'package' => $package,
712             filename => $filename,
713             line => $line,
714             subroutine=> $subroutine,
715             } unless (!defined $filename);
716             $i++;
717             }
718             return \@stack;
719             }
720              
721             =head3 alert
722              
723             Description :
724             store an alert message in the current objet
725              
726             =cut
727             sub alert($$)
728             {
729             my($self,
730             $message, # string : alert message
731             ) = @_;
732             push @{$self->{alert}},{
733             'time'=>time,
734             message => $message,
735             stack => $self->getCurrentStack(),
736             };
737             }
738              
739             =head3 debug
740              
741             Parameters :
742             message : string : message to debug
743             Description :
744             record one debug in the current objet
745              
746              
747             =cut
748              
749             sub debug($)
750             {
751             my ($self,$message)=@_;
752             push @{$self->{debug}},{
753             'time'=>time,
754             message => $message,
755             };
756             }
757              
758              
759             =head3 getLabel
760              
761             Description :
762             return the label of the current obj
763              
764              
765             =cut
766             sub getLabel()
767             {
768             my ($self) = @_;
769             return $self->{label};
770             }
771              
772             =head3 getLabelHtml
773              
774             Description :
775             return the html of the label of the current obj
776             If the label is a void string, return ''
777              
778              
779             =cut
780              
781             sub getLabelHtml
782             {
783             my ($self)=@_;
784             my %tagProp =();
785             my $label = $self->{label};
786              
787             if ($label eq ''){
788             return '';
789             }
790             $tagProp{for} = $self->{id};
791              
792             return $self->getHtmlTag("label",\%tagProp, $self->escapeHtml($label));
793             }
794              
795              
796             =head1 METHODS FOR SUBCLASSING
797              
798              
799              
800             =cut
801              
802              
803             =head1 PRIVATE METHODS
804              
805              
806              
807             =cut
808              
809              
810              
811             =head3 getPubPropHash
812              
813             Returns :
814             propHash : hash : a hash containing the value '1' pour each public propertie
815              
816              
817             =cut
818              
819             my $pubPropHash = undef;
820             sub getPubPropHash{
821             my($self ) = @_;
822              
823             return $pubPropHash if (defined $pubPropHash);
824             foreach my $propName(@publicPropList){
825             $pubPropHash->{$propName} = 1;
826             }
827             return $pubPropHash;
828             }
829              
830             =head3 getPath
831              
832             Return :
833             a string containing the actual path of the module
834              
835             =cut
836              
837             sub getPath
838             {
839             my($self ) = @_;
840              
841             my $path = $INC{'HTML/GUI/container.pm'};
842             $path =~ s/container.pm$//;
843             return $path;
844             }
845              
846              
847             =pod
848              
849             =head3 validate
850              
851             Description :
852             All widgets are OK by default. The input widgets have custom
853             validate function to implements constraints.
854              
855             Return :
856             always 1
857              
858             =cut
859              
860             sub validate
861             {
862             my($self ) = @_;
863             return 1;
864             }
865              
866              
867             =pod
868              
869             =head3 getValueHash
870              
871             Description :
872             Default method for all non-input and non-container widgets
873             Return :
874             undef
875              
876             =cut
877              
878             sub getValueHash
879             {
880             my($self) = @_;
881             return undef;
882             }
883              
884              
885             =head3 fired
886            
887             Parameters :
888             $params : the hash ref containing the POST key-value pairs.
889              
890             Decription :
891             this function aims to be specialized for buttons.
892              
893             Returns :
894             - true if the current object was fired
895             - false otherwise
896              
897             =cut
898             sub fired
899             {
900             my($self,$params) = @_;
901              
902             return 0;
903             }
904              
905             =head3 getNodeSession
906              
907             Decription :
908             return a hash ref to the session. This is a low level API to
909             manage multiple user session in multiple windows.
910             This function MUST be refined by the choosen engine.
911              
912             Returns :
913             - a hash ref to the session corresponding to the user agent cookie
914             - a void hash ref if no session can be found
915              
916             =cut
917             sub getNodeSession
918             {
919             return {};
920             }
921              
922             =head3 getSession
923              
924             Decription :
925             return a hash ref to the session corresponding to one window of the browser. If a user opens two windows of the same brower, he will need to connect two times, getSession will return two different sessions.
926             This method MUST be implemented by the engine
927              
928             Returns :
929             - a hash ref to the session corresponding to the user agent cookie
930             - a void hash ref if no session can be found
931              
932             =cut
933             sub getSession
934             {
935             return {};
936             }
937              
938             =pod
939              
940             =head3 getFunctionFromName
941              
942             Description :
943             Find the function whose name is $functionName
944             If the module of the function not loaded, it will be loaded automatically.
945              
946             Returns :
947             - a ref to the function whose name is $functionName if it exists
948             - undef if no function of this name exists
949              
950             =cut
951             sub getFunctionFromName{
952             my ($self,$functionName) = @_;
953             if (!$functionName){
954             return undef; #nothing to do
955             }
956             my @funcPath = split '::',$functionName;
957             my $funcName = pop @funcPath;
958             my $moduleName = join '::',@funcPath;
959             #for testing purpose
960             $moduleName ||= 'main';
961             $functionName = $moduleName.'::'.$funcName;
962             if (!defined &{$functionName}){
963             my $status = undef;
964             my $evalError = '';
965             if ($moduleName ne ''){
966             $status = eval "require $moduleName";
967             $evalError = $@;
968             }
969             if (!defined $status && $moduleName ne ''){
970             my $msg = '['.$moduleName."] is not a valid module name : ".$evalError;
971             ERROR($msg);
972             $self->error({
973             'message' =>$msg,
974             });
975             return undef;
976             }elsif(!defined &{$functionName}){
977             my $msg = '['.$moduleName.'] is not a valid module name';
978             ERROR($msg);
979             $self->error({
980             'message' => $msg,
981             });
982             return undef
983             }
984             }
985             return \&{$functionName};
986             }
987             =head1 AUTHOR
988              
989             Jean-Christian Hassler, C<< >>
990              
991             =head1 BUGS
992              
993             Please report any bugs or feature requests to
994             C, or through the web interface at
995             L.
996             I will be notified, and then you'll automatically be notified of progress on
997             your bug as I make changes.
998              
999              
1000             =head1 SUPPORT
1001              
1002             You can find documentation for this module with the perldoc command.
1003              
1004             perldoc HTML::GUI::widget
1005              
1006             You can also look for information at:
1007              
1008             =over 4
1009              
1010             =item * AnnoCPAN: Annotated CPAN documentation
1011              
1012             L
1013              
1014             =item * CPAN Ratings
1015              
1016             L
1017              
1018             =item * RT: CPAN's request tracker
1019              
1020             L
1021              
1022             =item * Search CPAN
1023              
1024             L
1025              
1026             =back
1027              
1028             =head1 ACKNOWLEDGEMENTS
1029              
1030             =head1 COPYRIGHT & LICENSE
1031              
1032             Copyright 2007 Jean-Christian Hassler, all rights reserved.
1033              
1034             This program is free software; you can redistribute it and/or modify it
1035             under the same terms as Perl itself.
1036              
1037             =cut
1038              
1039             1; # End of HTML::GUI::widget