File Coverage

blib/lib/Data/TreeDumper/Renderer/GTK.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1              
2             package Data::TreeDumper::Renderer::GTK ;
3              
4 1     1   5647 use 5.006;
  1         3  
  1         37  
5 1     1   4 use strict;
  1         2  
  1         27  
6 1     1   4 use warnings;
  1         4  
  1         42  
7              
8             require Exporter;
9 1     1   857 use AutoLoader qw(AUTOLOAD);
  1         1435  
  1         5  
10              
11             our %EXPORT_TAGS = ( 'all' => [ qw() ] );
12             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
13             our @EXPORT = qw();
14              
15             our $VERSION = '0.02';
16              
17 1     1   1635 use Data::TreeDumper ;
  0            
  0            
18              
19             use Gtk2 -init;
20             use Glib ':constants';
21              
22             use base qw(Gtk2::TreeView Exporter);
23              
24             sub new
25             {
26             my $class = shift;
27             my %args = (data => undef, @_);
28              
29             my $self = bless Gtk2::TreeView->new, $class;
30              
31             $self->insert_column_with_attributes(0, 'Data', Gtk2::CellRendererText->new, text => 0);
32             $self->set_data ($args{data}, $args{dumper_setup}) if exists $args{data} ;
33             $self->set_title ($args{title});
34              
35             $self->signal_connect
36             (
37             button_press_event =>
38             sub 
39             {
40             my ($widget, $event) = @_;
41             if ($event->button == 3) {
42             _do_context_menu ($widget, $event);
43             return TRUE;
44             }
45            
46             return FALSE;
47             }
48             );
49              
50              
51             return $self;
52             }
53              
54             sub _do_context_menu
55             {
56             my ($self, $event) = @_;
57             my $menu = Gtk2::Menu->new;
58             foreach my $method ('expand_all', 'collapse_all') {
59             my $label = join ' ', map { ucfirst $_ } split /_/, $method;
60             my $item = Gtk2::MenuItem->new ($label);
61             $menu->append ($item);
62             $item->show;
63             $item->signal_connect (activate => sub {
64             $self->$method;
65             });
66             }
67             $menu->popup (undef, undef, undef, undef, $event->button, $event->time);
68             }
69              
70             sub set_data
71             {
72             my ($self, $data, $dumper_setup) = @_;
73              
74             my $model = Gtk2::TreeStore->new ('Glib::String');
75              
76             DumpTree
77             (
78             $data
79             , 'GTK-perl data dump'
80             , %$dumper_setup
81             , RENDERER =>
82             {
83             NODE  => \&RenderNode
84            
85             # data needed by the renderer
86             , PREVIOUS_LEVEL => 0
87             , MODEL => $model
88             , PARENT => [Gtk2::TreePath->new_from_string()]
89             }
90             ) ;
91              
92             $self->set_model ($model);
93             }
94              
95             sub set_title
96             {
97             my ($self, $title) = @_;
98            
99             if (defined $title and length $title) {
100             $self->get_column (0)->set_title ($title);
101             $self->set_headers_visible (TRUE);
102             } else {
103             $self->set_headers_visible (FALSE);
104             }
105             }
106              
107              
108             #-------------------------------------------------------------------------------------------
109              
110             sub RenderNode
111             {
112             my
113             (
114             $element
115             , $level
116             , $is_terminal
117             , $previous_level_separator
118             , $separator
119             , $element_name
120             , $element_value
121             , $td_address
122             , $address_link
123             , $perl_size
124             , $perl_address
125             , $setup
126             ) = @_ ;
127              
128             my $model = $setup->{RENDERER}{MODEL} ;
129             my $parents = $setup->{RENDERER}{PARENT} ;
130             my $previous_level = $setup->{RENDERER}{PREVIOUS_LEVEL} ;
131              
132             # wind up the parents list if necessary
133             splice @$parents, 0, ($previous_level - $level) if($level < $previous_level) ;
134              
135             my $path = $parents->[0] ;
136             my $parent = $model->get_iter($path) if($path->get_depth() > 0) ;
137            
138             $element_value = " = $element_value" if($element_value ne '') ;
139              
140             my $address = $td_address ;
141             $address .= "-> $address_link" if defined $address_link ;
142              
143             $perl_size = "<$perl_size>" if $perl_size ne '' ;
144              
145             my $rendering ;
146             if($setup->{DISPLAY_ADDRESS})
147             {
148             $rendering = "$element_name$element_value [$address] $perl_size $perl_address" ;
149             }
150             else
151             {
152             $rendering = "$element_name$element_value $perl_size $perl_address" ;
153             }
154              
155             unless($is_terminal)
156             {
157             my $parent = $model->append ($parent);
158             $model->set($parent, 0, $rendering);
159            
160             my $path = $model->get_path($parent) ;
161             unshift @{$setup->{RENDERER}{PARENT}}, $path ;
162             }
163             else
164             {
165             $model->set($model->append($parent),0, $rendering);
166             }
167            
168             $setup->{RENDERER}{PREVIOUS_LEVEL} = $level ;
169             } 
170            
171              
172             1;
173              
174             __END__
175            
176             =head1 NAME
177            
178             Data::TreeDumper::Renderer::GTK - Gtk2::TreeView renderer for B<Data::TreeDumper>
179            
180             =head1 SYNOPSIS
181            
182             my $treedumper = Data::TreeDumper::Renderer::GTK->new
183             (
184             data => \%data,
185             title => 'Test Data',
186             dumper_setup => {DISPLAY_PERL_SIZE => 1}
187             );
188            
189             $treedumper->modify_font(Gtk2::Pango::FontDescription->from_string ('monospace'));
190             $treedumper->expand_all;
191            
192             # some boilerplate to get the widget onto the screen...
193             my $window = Gtk2::Window->new;
194            
195             my $scroller = Gtk2::ScrolledWindow->new;
196             $scroller->add ($treedumper);
197            
198             $window->add ($scroller);
199             $window->show_all;
200            
201             =head1 HIERARCHY
202            
203             Glib::Object
204             +----Gtk2::Object
205             +----Gtk2::Widget
206             +----Gtk2::Container
207             +----Gtk2::TreeView
208             +----Data::TreeDumper::Renderer::GTK
209            
210             =head1 DESCRIPTION
211            
212             GTK-perl renderer for B<Data::TreeDumper>.
213            
214             This widget is the gui equivalent of Data::TreeDumper; it will display a
215             perl data structure in a TreeView, allowing you to fold and unfold child
216             data structures and get a quick feel for what's where. Right-clicking
217             anywhere in the view brings up a context menu, from which the user can
218             choose to expand or collapse all items.
219            
220             =head1 EXAMPLE
221            
222             B<gtk_test.pl>
223            
224            
225             =head1 METHODS
226            
227             =over
228            
229             =item widget = Data::TreeDumper::Renderer::GTK::TreeDumper->new (...)
230            
231             Create a new TreeDumper. The optional arguments are expect to be key/val
232             pairs.
233            
234             =over
235            
236             =item - dumper_setup => hash reference
237            
238             All data is passed to Data::TreeDumper
239            
240             =item - data => scalar
241            
242             Equivalent to calling C<< $treedumper->set_data ($scalar) >>.
243            
244             =item - title => string or undef
245            
246             Equivalent to calling C<< $treedumper->set_title ($string) >>.
247            
248             =back
249            
250             =item $treedumper->set_data ($newdata)
251            
252             =over
253            
254             =item * $newdata (scalar)
255            
256             =back
257            
258             Fill the tree with I<$newdata>, which may be any scalar. The tree does
259             not reference I<$newdata> -- necessary data is copied.
260            
261             =item $treedumper->set_title ($title=undef)
262            
263             =over
264            
265             =item * $title (string or undef) a new title
266            
267             =back
268            
269             Set the string displayed as the column title. The view is created with one
270             column, and the header is visible only if there is a title set.
271            
272             =back
273            
274             =head1 EXPORT
275            
276             None
277            
278             =head1 AUTHORS
279            
280             Khemir Nadim ibn Hamouda. <nadim@khemir.net>
281             Muppet <scott at asofyet dot org>
282            
283             Copyright (c) 2005 Nadim Ibn Hamouda el Khemir and
284             Muppet. All rights reserved.
285            
286             This program is free software; you can redistribute
287             it and/or modify it under the same terms as Perlitself.
288            
289             If you find any value in this module, mail me! All hints, tips, flames and wishes
290             are welcome at <nadim@khemir.net>.
291            
292             =head1 SEE ALSO
293            
294             B<Data::TreeDumper> for advanced usage of the dumper engine.
295            
296             =cut
297