File Coverage

blib/lib/Padre/Plugin/FormBuilder/Perl.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Padre::Plugin::FormBuilder::Perl;
2            
3             =pod
4            
5             =head1 NAME
6            
7             Padre::Plugin::FormBuilder::Perl - wxFormBuilder to Padre dialog code generator
8            
9             =head1 SYNOPSIS
10            
11             my $generator = Padre::Plugin::FormBuilder::Perl->new(
12             dialog => $fbp_object->dialog('MyDialog')
13             );
14            
15             =head1 DESCRIPTION
16            
17             This is a L-specific variant of L.
18            
19             It overloads various methods to make things work in a more Padre-specific way.
20            
21             =cut
22            
23 2     2   50319 use 5.008005;
  2         8  
  2         89  
24 2     2   12 use strict;
  2         4  
  2         75  
25 2     2   12 use warnings;
  2         6  
  2         649  
26 2     2   53 use Scalar::Util 1.19 ();
  2         50  
  2         58  
27 2     2   1519 use Params::Util 0.33 ();
  2         12256  
  2         50  
28 2     2   2120 use FBP::Perl 0.75 ();
  0            
  0            
29            
30             our $VERSION = '0.04';
31             our @ISA = 'FBP::Perl';
32            
33            
34            
35            
36            
37             ######################################################################
38             # Constructor
39            
40             sub new {
41             my $self = shift->SUPER::new(
42             # Apply the default prefix style
43             prefix => 2,
44             @_,
45             );
46            
47             # The encapsulate accessor
48             $self->{encapsulate} = $self->{encapsulate} ? 1 : 0;
49            
50             return $self;
51             }
52            
53             sub encapsulate {
54             $_[0]->{encapsulate};
55             }
56            
57            
58            
59            
60            
61             ######################################################################
62             # Dialog Generators
63            
64             sub form_class {
65             my $self = shift;
66             my $form = shift;
67             my $lines = $self->SUPER::form_class($form);
68             my $year = 1900 + (localtime(time))[5];
69            
70             # Append the copywrite statement that Debian/etc need
71             push @$lines, <<"END_PERL";
72            
73             # Copyright 2008-$year The Padre development team as listed in Padre.pm.
74             # LICENSE
75             # This program is free software; you can redistribute it and/or
76             # modify it under the same terms as Perl 5 itself.
77             END_PERL
78            
79             return $lines;
80             }
81            
82             sub project_header {
83             my $self = shift;
84             my $lines = $self->SUPER::project_header(@_);
85            
86             # Add the modification warning
87             my $class = Scalar::Util::blessed($self);
88             push @$lines, (
89             "# This module was generated by $class.",
90             "# To change this module edit the original .fbp file and regenerate.",
91             "# DO NOT MODIFY THIS FILE BY HAND!",
92             "",
93             );
94            
95             return $lines;
96             }
97            
98             sub form_new {
99             my $self = shift;
100             my $dialog = shift;
101             my $lines = $self->SUPER::form_new($dialog);
102            
103             # Find the full list of public windows
104             my @public = grep {
105             $_->permission eq 'public'
106             } $dialog->find( isa => 'FBP::Window' );
107            
108             if ( $self->encapsulate and @public ) {
109             # Generate code to save the wxWidgets id values to the hash slots
110             my @save = ( '' );
111             foreach my $window ( @public ) {
112             my $name = $window->name;
113             my $variable = $self->object_variable($window);
114             push @save, "\t\$self->{$name} = $variable->GetId;";
115             }
116            
117             # Splice the bind code into the constructor
118             splice( @$lines, $#$lines - 2, 0, @save );
119             }
120            
121             return $lines;
122             }
123            
124             sub project_dist {
125             my $self = shift;
126             my $project = shift;
127             my $name = $project->name;
128            
129             # If the name is a module name (which it is) then convert to
130             # the common dashed version.
131             $name =~ s/::/-/g;
132            
133             return $name;
134             }
135            
136             sub form_super {
137             my $self = shift;
138             my @super = $self->SUPER::form_super(@_);
139             if ( @super ) {
140             unshift @super, 'Padre::Wx::Role::Main';
141             }
142             return @super;
143             }
144            
145             sub form_wx {
146             my $self = shift;
147             my $topic = shift;
148            
149             # Which Wx modules does this form need
150             my @modules = ();
151             if ( $self->find_plain( $topic => 'FBP::HtmlWindow' ) ) {
152             push @modules, 'Html';
153             }
154             if ( $self->find_plain( $topic => 'FBP::Grid' ) ) {
155             push @modules, 'Grid';
156             }
157             if ( $self->find_plain( $topic => 'FBP::Calendar' ) ) {
158             push @modules, 'Calendar';
159             push @modules, 'DateTime';
160             } elsif ( $self->find_plain( $topic => 'FBP::DatePickerCtrl' ) ) {
161             push @modules, 'DateTime';
162             }
163             if ( $self->find_plain( $topic => 'FBP::RichTextCtrl' ) ) {
164             push @modules, 'RichText';
165             }
166            
167             # Generate the use lines
168             my $params = '()';
169             if ( @modules ) {
170             $params = join ', ', map { "'$_'" } @modules;
171             }
172             my $lines = [
173             "use Padre::Wx $params;",
174             "use Padre::Wx::Role::Main ();",
175             ];
176            
177             return $lines;
178             }
179            
180             sub form_custom {
181             my $self = shift;
182             my $form = shift;
183             my $lines = $self->SUPER::form_custom( $form, @_ );
184            
185             # Are any of the files used by the form relative
186             # and within the share directory.
187             if ( grep { /^share\b/ } $self->form_files($form) ) {
188             push @$lines, "use File::ShareDir ();";
189             }
190            
191             return $lines;
192             }
193            
194             sub form_files {
195             my $self = shift;
196             my $form = shift;
197             my @files = ();
198            
199             # Static bitmaps
200             push @files, map {
201             $_->bitmap
202             } $form->find( isa => 'FBP::StaticBitmap' );
203            
204             # Tools
205             push @files, map {
206             $_->bitmap
207             } $form->find( isa => 'FBP::Tool' );
208            
209             # Menu entries
210             push @files, map {
211             $_->bitmap
212             } $form->find( isa => 'FBP::MenuItem' );
213            
214             # Bitmap buttons
215             push @files, map {
216             $_->bitmap,
217             $_->disabled,
218             $_->selected,
219             $_->hover,
220             $_->focus,
221             } $form->find( isa => 'FBP::BitmapButton' );
222            
223             # Animation controls
224             push @files, map {
225             $_->inactive_bitmap
226             } $form->find( isa => 'FBP::AnimationCtrl' );
227            
228             # Clean and filter
229             my %seen = ();
230             return grep {
231             not $seen{$_}++
232             } map {
233             s/; Load From File$// ? $_ : ()
234             } grep {
235             defined $_
236             } map {
237             Params::Util::_STRING($_)
238             } @files;
239             }
240            
241             sub object_accessor {
242             my $self = shift;
243             unless ( $self->encapsulate ) {
244             return $self->SUPER::object_accessor(@_);
245             }
246            
247             my $object = shift;
248             my $name = $object->name;
249             return $self->nested(
250             "sub $name {",
251             "Wx::Window::FindWindowById(\$_[0]->{$name});",
252             "}",
253             );
254             }
255            
256             sub object_event {
257             my $self = shift;
258             my $window = shift;
259             my $event = shift;
260             my $name = $window->name;
261             my $method = $window->$event();
262            
263             return $self->nested(
264             "sub $method {",
265             "\$_[0]->main->error('Handler method $method for event $name.$event not implemented');",
266             "}",
267             );
268             }
269            
270             # Because we expect everything to be shimmed, apply a stricter interpretation
271             # of lexicality if the code is being generated for Padre.
272             sub object_lexical {
273             my $self = shift;
274             unless ( $self->encapsulate ) {
275             return $self->SUPER::object_lexical(@_);
276             }
277             return 1;
278             }
279            
280             # File name
281             sub file {
282             my $self = shift;
283             my $string = shift;
284             return undef unless Params::Util::_STRING($string);
285             return undef unless $string =~ s/; Load From File$//;
286             unless ( $string =~ s/^share[\\\/]// ) {
287             return $self->quote($string);
288             }
289            
290             # Special sharedir form
291             my $file = $self->quote($string);
292             my $dist = $self->quote($self->project_dist($self->project));
293             return "File::ShareDir::dist_file( $dist, $file )";
294             }
295            
296             sub wx {
297             my $self = shift;
298             unless ( $self->prefix > 1 ) {
299             return $self->SUPER::wx(@_);
300             }
301            
302             # Apply the same null checks as the normal method
303             my $string = shift;
304             return 0 if $string eq '';
305             return -1 if $string eq 'wxID_ANY';
306            
307             # Handle constants in the new Wx::FOO style
308             $string =~ s/\bwx/Wx::/gi;
309            
310             # Tidy a collection of multiple constants
311             $string =~ s/\s*\|\s*/ | /g;
312            
313             return $string;
314             }
315            
316             1;
317            
318             =pod
319            
320             =head1 SUPPORT
321            
322             Bugs should be reported via the CPAN bug tracker at
323            
324             L
325            
326             For other issues, or commercial enhancement or support, contact the author.
327            
328             =head1 AUTHOR
329            
330             Adam Kennedy Eadamk@cpan.orgE
331            
332             =head1 SEE ALSO
333            
334             L
335            
336             =head1 COPYRIGHT
337            
338             Copyright 2010 - 2012 Adam Kennedy.
339            
340             This program is free software; you can redistribute
341             it and/or modify it under the same terms as Perl itself.
342            
343             The full text of the license can be found in the
344             LICENSE file included with this module.
345            
346             =cut