File Coverage

blib/lib/Tk/MIMEApp.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             package Tk::MIMEApp;
2 1     1   22720 use base qw(Tk::Derived Tk::NoteBook);
  1         4  
  1         739  
3             use IO::File;
4             use MIME::Multipart::Parse::Ordered;
5             use Tk::MarkdownTk;
6             use YAML::Perl;
7             use Tk qw(Ev);
8              
9             use 5.006;
10             use strict;
11             use warnings FATAL => 'all';
12              
13             =head1 NAME
14              
15             Tk::MIMEApp - The great new Tk::MIMEApp!
16              
17             =head1 VERSION
18              
19             Version 0.04
20              
21             =cut
22              
23             our $VERSION = '0.04';
24              
25             our @Shelf = (); # we'll put our books here!
26              
27             Construct Tk::Widget 'MIMEApp';
28              
29             =head1 SYNOPSIS
30              
31             ISA Tk::Notebook. Can load MIME Multipart file with
32             application/x-ptk.markdown parts, converting them to
33             Tk (with Tk::MarkdownTk) for document-driven applications.
34              
35             =head1 SUBROUTINES/METHODS
36              
37             =head2 loadMultipart
38              
39             Method that takes a filehandle and adds a page to the notebook
40             for each application/x-ptk.markdown part. Will also add menu items
41             to the toplevel menu for application/x-yaml.menu parts.
42              
43             =cut
44              
45             sub loadMultipart {
46             # load a MIME-multipart-style file containing at least one application/x-ptk.markdown
47             my ($o,$fh) = @_;
48             $o->{Objects} = {};
49             push @Shelf, $o;
50             my $mmps = MIME::Multipart::Parse::Ordered->new();
51             my $parts = $o->{parts} = $mmps->parse($fh); # now an array... content is in $parts->[$i]->{Body}
52              
53             foreach my $part(@$parts){
54             my $ct = $part->{'Content-Type'};
55             if($ct eq "application/x-ptk.markdown"){
56              
57             # work out the IDs
58             my $id = exists $part->{'ID'} ? $part->{'ID'} : "O$part";
59             my $textid = $id.'_text';
60             my $pageid = $id.'_page';
61              
62             # set up the page
63             my $name = exists $part->{"Title"} ? $part->{"Title"} : "$part";
64             my %u = ();
65             if($name =~ /_/){
66             %u = (-underline=>length($`) );
67             $name = $`.$';
68             }
69             my $page = $o->add($id, -label=>$name, -state=>'normal', %u); # more options needed here!
70            
71             # set up the text
72             my $text = $page->Scrolled('MarkdownTk',-scrollbars=>'se')->pack(-expand=>1,-fill=>'both');
73             $text->insert('end',$part->{Body});
74            
75             # add the objects to the Objects property
76             $o->{Objects}->{$textid} = $text;
77             $o->{Objects}->{$pageid} = $page;
78             }
79             elsif($ct eq "multipart/mixed"){
80             if($part->{"Title"}){
81             $o->toplevel->configure(-title=>$part->{"Title"});
82             }
83             $o->{Objects}->{Main} = $part;
84             }
85             elsif($ct eq 'application/x-yaml.menu'){
86             $o->toplevel->configure(
87             -menu => yaml2menu(
88             $part->{Body},
89             $o->toplevel->Menu(-tearoff=>0,-type=>'menubar')
90             )
91             );
92             }
93             elsif($ct eq 'application/x-perl'){
94             eval ($part->{Body});
95             }
96             }
97             }
98              
99             =head2 yaml2menu
100              
101             Accepts some yaml (scalar) and a Tk::Menu as arguments, and populates
102             the menu from the yaml. Uses YAML::Perl for parsing.
103              
104             =cut
105              
106             sub yaml2menu {
107             # convert a yaml-like text to a tk menu
108             my ($yaml,$menu) = @_;
109             my $data = Load $yaml;
110             return array2menuitems($menu,$data);
111             }
112              
113             =head2 array2menuitems
114              
115             Takes a Tk::Menu and and arrayref describing
116             items and implements them. Called by yaml2menu.
117              
118             =cut
119              
120             sub array2menuitems {
121             my ($menu, $array) = @_;
122             my @opts = qw/activebackground activeforeground accelerator background bitmap columnbreak compound
123             command font foreground hidemargin image indicatoron label menu offvalue onvalue selectcolor
124             selectimage state underline value variable /;
125             my $patt = join('|',@opts);
126             my $re = qr/^-(?:$patt)$/;
127             foreach my $a(@$array){
128             my %v = map {'-'.$_ => $a->{$_}} keys %$a;
129             my $type = 'command';
130             foreach (keys %v){
131             if(! /$re/){ ## if this key is not a regular key...
132             $v{'-label'} = substr($_,1); ### use as label ... removing the leading '-'
133             my $p = $v{$_}; ### save value
134             delete $v{$_}; ### delete
135             if(ref $p){ # it's an array... make a cascade menu...
136             $type = 'cascade';
137             $v{'-menu'} = array2menuitems(
138             $menu->Menu(-type=>'normal',-tearoff=>0),
139             $p
140             );
141             }
142             else {
143             $v{'-command'} = $p;
144             }
145             } # endif
146             } # innerloop
147             ### now we should have a set of options...
148              
149             ## setting up labels and indicides...
150             if($v{'-label'} =~ /_/){
151             $v{'-underline'} = length($`);
152             $v{'-label'} = $`.$';
153             }
154              
155             ## separators...
156             if($v{'-label'} =~ /^-+$/){
157             %v = (); # delete all parameters!
158             $type = 'separator';
159             }
160              
161             $menu->add($type, %v);
162              
163             } # outerloop
164             return $menu;
165             }
166              
167              
168              
169             ### these few subs are taken directly from ROText...
170              
171             =head2 ClassInit
172              
173             Used internally
174              
175             =cut
176              
177             sub ClassInit
178             {
179             my ($class,$mw) = @_;
180             # class binding does not work right due to extra level of
181             # widget hierachy
182             $mw->bind($class,'', ['MouseDown',Ev('x'),Ev('y')]);
183             $mw->bind($class,'', ['MouseUp',Ev('x'),Ev('y')]);
184              
185             $mw->bind($class,'', ['MouseDown',Ev('x'),Ev('y')]);
186             $mw->bind($class,'', ['FocusNext','prev']);
187             $mw->bind($class,'', ['FocusNext','next']);
188              
189             $mw->bind($class,'', 'SetFocusByKey');
190             $mw->bind($class,'', 'SetFocusByKey');
191             return $class;
192             }
193              
194             =head2 Populate
195              
196             Used internally
197              
198             =cut
199              
200             sub Populate
201             {
202             my ($self,$args) = @_;
203             $self->SUPER::Populate($args);
204             $self->ConfigSpecs(-background=>['SELF'], -foreground=>['SELF'],);
205             # do other stuff here...
206             }
207              
208              
209              
210              
211             =head1 AUTHOR
212              
213             jimi, C<< >>
214              
215             =head1 BUGS
216              
217             Please report any bugs or feature requests to C, or through
218             the web interface at L. I will be notified, and then you'll
219             automatically be notified of progress on your bug as I make changes.
220              
221              
222              
223              
224             =head1 SUPPORT
225              
226             You can find documentation for this module with the perldoc command.
227              
228             perldoc Tk::MIMEApp
229              
230              
231             You can also look for information at:
232              
233             =over 4
234              
235             =item * RT: CPAN's request tracker (report bugs here)
236              
237             L
238              
239             =item * AnnoCPAN: Annotated CPAN documentation
240              
241             L
242              
243             =item * CPAN Ratings
244              
245             L
246              
247             =item * Search CPAN
248              
249             L
250              
251             =back
252              
253              
254             =head1 ACKNOWLEDGEMENTS
255              
256              
257             =head1 LICENSE AND COPYRIGHT
258              
259             Copyright 2013 jimi.
260              
261             This program is free software; you can redistribute it and/or modify it
262             under the terms of the the Artistic License (2.0). You may obtain a
263             copy of the full license at:
264              
265             L
266              
267             Any use, modification, and distribution of the Standard or Modified
268             Versions is governed by this Artistic License. By using, modifying or
269             distributing the Package, you accept this license. Do not use, modify,
270             or distribute the Package, if you do not accept this license.
271              
272             If your Modified Version has been derived from a Modified Version made
273             by someone other than you, you are nevertheless required to ensure that
274             your Modified Version complies with the requirements of this license.
275              
276             This license does not grant you the right to use any trademark, service
277             mark, tradename, or logo of the Copyright Holder.
278              
279             This license includes the non-exclusive, worldwide, free-of-charge
280             patent license to make, have made, use, offer to sell, sell, import and
281             otherwise transfer the Package with respect to any patent claims
282             licensable by the Copyright Holder that are necessarily infringed by the
283             Package. If you institute patent litigation (including a cross-claim or
284             counterclaim) against any party alleging that the Package constitutes
285             direct or contributory patent infringement, then this Artistic License
286             to you shall terminate on the date that such litigation is filed.
287              
288             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
289             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
290             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
291             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
292             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
293             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
294             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
295             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296              
297              
298             =cut
299              
300             1; # End of Tk::MIMEApp