File Coverage

blib/lib/Gtk2/PathButtonBar.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Gtk2::PathButtonBar;
2              
3 1     1   20945 use Gtk2 '-init';
  0            
  0            
4             use warnings;
5             use strict;
6              
7             =head1 NAME
8              
9             Gtk2::PathButtonBar - Creates a bar for path manipulation.
10              
11             =head1 VERSION
12              
13             Version 0.1.2
14              
15             =cut
16              
17             our $VERSION = '0.1.2';
18              
19              
20             =head1 SYNOPSIS
21              
22             This creates a collection of buttons and a entry widget to help with browsing a
23             path or etc.
24              
25             It is composed of two lines. The first line contains a set of buttons. The first button
26             is a button that blanks the current path. This is the 'goRoot' button and displays what ever
27             the user has decided the root is by setting the 'root' key when invoking the new funtions.
28             The buttons after that are ones that correspond to a chunk of the path, broken up by what ever
29             the delimiter is set to. When any of these are pressed, the entry text is changed as well to
30             relfect it. The 'goRoot' button clears the path to ''.
31              
32             The second line starts with a label. The label is the same as on the 'goRoot' button and is
33             what ever the root is set as. After that there is a single line text entry widget. This allows
34             the path to be set by typing it in. After the text entry widget, there is a button labeled 'Go'.
35             When this button is pressed, it updates the button bar with what is in text entry widget.
36              
37             Any time the path is updated, '$self->{exec}' is ran through eval.
38              
39             use Gtk2;
40             use Gtk2::PathButtonBar;
41            
42             Gtk2->init;
43            
44             my $window = Gtk2::Window->new();
45            
46             my $pbb=Gtk2::PathButtonBar->new({exec=>'print "path=".${$myself}->{path}."\na=".${$myself}->{vars}{a}."\n";',
47             vars=>{a=>1},
48             });
49            
50             print $pbb->{vbox}."\n";
51            
52             $window->add($pbb->{vbox});
53            
54             $window->show;
55              
56             =head1 FUNCTIONS
57              
58             =head2 new
59              
60             This initiates this widget. This takes it's arguements in the form of a hash.
61             The accepted keys can be found below.
62              
63             =head3 delimiter
64              
65             This is what will be considered a delimiter between directories or whatever. The
66             default is '/'.
67              
68             =head3 exec
69              
70             This is a string that will be executed any time any change is done. Change the
71             text in the string entry box does not constitute a change till the 'Go' button is pressed.
72              
73             For example, setting it to the following, would cause it to print the current path
74             followed a new line and then a 'a=' what ever '$self->{vars}{a}' is set to.
75              
76             exec=>'print "path=".${$myself}->{path}."\na=".${$myself}->{vars}{a}."\n:;
77              
78             If you wish to pass any sort of variables to this, it is strongly suggested you do it by
79             using the 'vars' key in the hash passed to the new function.
80              
81             Upon a failure to execute the code in exec, it will issue a warning.
82              
83             =head3 root
84              
85             This is what will be displayed as being the root. This wills how up in the 'goRoot' button
86             and in the label before the entry box.
87              
88             If it is not defined, it defaults to what ever the delimiter is. If the delimiter is not set,
89             that means this will display '/', which works nicely for most unix FS stuff.
90              
91             =head3 path
92              
93             This is the path that the it will originally be set to.
94              
95             =head3 vars
96              
97             This is meant to contain variables that will be used with '$self->{exec}'.
98              
99             =cut
100              
101             sub new {
102             my %args;
103             if(defined($_[1])){
104             %args= %{$_[1]};
105             }
106              
107             my $self={error=>undef, set=>undef, errorString=>'', buttons=>{}};
108             bless $self;
109              
110             if (!defined($args{exec})) {
111             $args{exec}='print ${$myself}->{path}."\n";';
112             }
113             $self->{exec}=$args{exec};
114              
115             if (!defined($args{vars})) {
116             $args{vars}={};
117             }
118             $self->{vars}=$args{vars};
119              
120             #I've not added in the if statement for this yet and in retrospect I like the
121             #idea of leaving it out.
122             # #determines if root will be shown or not
123             # if (!defined($args{showRoot})) {
124             # $args{showRoot}=1
125             # }
126             # $self->{showRoot}=$args{showRoot};
127              
128             #If the delimiter is not set, set it to '/'.
129             if (!defined($args{delimiter})) {
130             $args{delimiter}='/';
131             }
132             $self->{delimiter}=$args{delimiter};
133              
134             #If the root is not defined, use the delimiter.
135             if (!defined($args{root})) {
136             $args{root}=$args{delimiter};
137             }
138             $self->{root}=$args{root};
139              
140             if (!defined($args{path})) {
141             $args{path}='';
142             }
143             $self->{path}=$args{path};
144              
145             #con
146             $self->{vbox}=Gtk2::VBox->new(0, 1);
147             $self->{vbox}->show;
148              
149             #the hbox that contains the buttons
150             $self->{bhbox}=Gtk2::HBox->new(0, 1);
151             $self->{vbox}->pack_start($self->{bhbox}, 0, 0, 1);
152             $self->{bhbox}->show;
153              
154             #the hbox that contains the string box and go button
155             $self->{shbox}=Gtk2::HBox->new(0, 1);
156             $self->{vbox}->pack_start($self->{shbox}, 0, 0, 1);
157             $self->{shbox}->show;
158              
159             #this adds the root label
160             $self->{rootLabel}=Gtk2::Label->new($self->{root});
161             $self->{rootLabel}->show;
162             $self->{shbox}->pack_start($self->{rootLabel}, 0, 0, 1);
163              
164             #sets up the entry
165             $self->{entry}=Gtk2::Entry->new();
166             #sets the entry to the path
167             $self->{entry}->set_text($args{path});
168             $self->{shbox}->pack_start($self->{entry}, 1, 1, 1);
169             $self->{entry}->show;
170              
171             #this button calls the go function
172             $self->{go}=Gtk2::Button->new();
173             $self->{goLabel}=Gtk2::Label->new("Go");
174             $self->{go}->add($self->{goLabel});
175             $self->{goLabel}->show;
176             $self->{go}->show;
177             $self->{go}->signal_connect("clicked" => sub{$_[1]->go;}, $self);
178             $self->{shbox}->pack_start($self->{go}, 0, 0, 1);
179              
180             #this button calls the go function
181             $self->{goRoot}=Gtk2::Button->new();
182             $self->{goRootLabel}=Gtk2::Label->new($self->{root});
183             $self->{goRoot}->add($self->{goRootLabel});
184             $self->{goRootLabel}->show;
185             $self->{goRoot}->show;
186             $self->{goRoot}->signal_connect("clicked" => sub{$_[1]->goRoot;}, $self);
187             $self->{bhbox}->pack_start($self->{goRoot}, 0, 0, 1);
188              
189             #
190             $self->makeButtons();
191            
192             return $self;
193             }
194              
195             =head2 go
196              
197             This is called when a new path is set by pressing the go button.
198              
199             There is no reason to ever call this from '$self->{exec}'.
200              
201             =cut
202              
203             sub go{
204             my $self=$_[0];
205             my $myself=\$self;#this is done for simplying coding the exec stuff
206             #If we did not have it here, stuff for in the buttons would go wonky and vice versa.
207             $self->{path}=$self->{entry}->get_text;
208              
209             $self->{path}=~s/$self->{delimiter}+/$self->{delimiter}/g;
210             $self->{path}=~s/^$self->{delimiter}+//;
211             $self->{path}=~s/$self->{delimiter}+$//;
212             $self->{entry}->set_text($self->{path});
213              
214             eval($self->{exec}) or warn("Gtk2::PathButtonBar go: eval failed on for... \n".$self->{exec}."\n");
215              
216             $self->makeButtons;
217             }
218              
219             =head2 goRoot
220              
221             This is called when a new path is set by pressing the root button.
222              
223             If you wish to call this from '$self->{exec}', do it as below.
224              
225             ${$myself}->goRoot;
226              
227             =cut
228              
229             sub goRoot{
230             my $self=$_[0];
231             my $myself=\$self;#this is done for simplying coding the exec stuff
232             #If we did not have it here, stuff for in the buttons would go wonky and vice versa.
233             $self->{path}='';
234             $self->{entry}->set_text($self->{path});
235              
236             eval($self->{exec}) or warn("Gtk2::PathButtonBar goRoot: eval failed on for... \n".$self->{exec}."\n");
237              
238             $self->makeButtons;
239            
240             }
241              
242             =head2 makeButtons
243              
244             This is a internal function that rebuilds the button bar.
245              
246             If you wish to call this from '$self->{exec}', do it as below.
247              
248             ${$myself}->makeButtons;
249              
250             =cut
251              
252             sub makeButtons{
253             my $self=$_[0];
254              
255             my @split=split($self->{delimiter}, $self->{path});
256              
257             my $splitInt=0;
258              
259             my $path='';
260              
261             #adds or changes buttons
262             while ($splitInt <= $#split) {
263             $path=$path.$split[$splitInt].$self->{delimiter};
264              
265             #the action works like this...
266             #1: Create $myself for allowing a way of accessing self both here and in 'goRoot' and 'go'.
267             #2: Gets the new path.
268             #3: Sets the entry text.
269             #4: rebuilds the buttons
270             #5: eval what ever is in '$self->{exec}'.
271              
272             #add a new button if it does not exist
273             if (defined($self->{buttons}{$splitInt})) {
274             $self->{bhbox}->remove($self->{buttons}{$splitInt});
275             $self->{buttons}{$splitInt}->destroy;
276             $self->{buttons}{$splitInt."Label"}->destroy;
277             delete($self->{buttons}{$splitInt});
278             delete($self->{buttons}{$splitInt."Label"});
279             }
280              
281             $self->{buttons}{$splitInt}=Gtk2::Button->new();
282             $self->{buttons}{$splitInt."Label"}=Gtk2::Label->new($split[$splitInt].$self->{delimiter});
283             $self->{buttons}{$splitInt}->add($self->{buttons}{$splitInt."Label"});
284             $self->{buttons}{$splitInt."Label"}->show;
285             $self->{buttons}{$splitInt}->show;
286             $self->{buttons}{$splitInt}->signal_connect("clicked" => sub{
287             my $myself=\$_[1]->{self};
288             $_[1]->{self}->{path}=$_[1]->{path};
289             $_[1]->{self}->{entry}->set_text($_[1]->{path});
290             $_[1]->{self}->makeButtons;
291             eval($_[1]->{self}->{exec}) or warn("Gtk2::PathButtonBar goRoot: eval failed on for... \n".$_[1]->{self}->{exec}."\n");
292             },
293             {
294             self=>$self,
295             path=>$path
296             }
297             );
298             $self->{bhbox}->pack_start($self->{buttons}{$splitInt}, 0, 0, 1);
299              
300             $splitInt++;
301             }
302              
303             #removes unneeded buttons
304             #any button past this point in $splitInt is a old one that is no longer in the page
305             while (defined($self->{buttons}{$splitInt})) {
306             $self->{bhbox}->remove($self->{buttons}{$splitInt});
307             $self->{buttons}{$splitInt}->destroy;
308             $self->{buttons}{$splitInt."Label"}->destroy;
309             delete($self->{buttons}{$splitInt});
310             delete($self->{buttons}{$splitInt."Label"});
311              
312             $splitInt++;
313             }
314              
315             }
316              
317             =head2 setPath
318              
319             This changes the current path.
320              
321             One arguement is accepted and that is the path.
322              
323             $pbb->setPath($somepath);
324             if($self->{error}){
325             print "Error!\n";
326             }
327              
328             =cut
329              
330             sub setPath{
331             my $self=$_[0];
332             my $path=$_[1];
333              
334             $self->errorblank;
335              
336             if (!defined($path)) {
337             $self->{error}=1;
338             $self->{errorString}='No path specified';
339             warn('Gtk2-PathButtonBar setPath:1: '.$self->{errorString});
340             return undef;
341             }
342              
343             #this removes the delimiter if it starts with it
344             $path=~s/^$self->{delimiter}//;
345             $path=~s/$self->{delimiter}$//;
346              
347             #set the path
348             $self->{entry}->set_text($path);
349             $self->{path}=$path;
350              
351             #now that we have changed it, update the buttons
352             $self->makeButtons;
353              
354             return 1;
355             }
356              
357             =head2 errorblank
358              
359             This blanks the error storage and is only meant for internal usage.
360              
361             It does the following.
362              
363             $self->{error}=undef;
364             $self->{errorString}="";
365              
366             =cut
367              
368             #blanks the error flags
369             sub errorblank{
370             my $self=$_[0];
371              
372             $self->{error}=undef;
373             $self->{errorString}="";
374              
375             return 1;
376             }
377              
378             =head1 ERROR CODES
379              
380             =head2 1
381              
382             No path specified.
383              
384             =head1 AUTHOR
385              
386             Zane C. Bowers, C<< >>
387              
388             =head1 BUGS
389              
390             Please report any bugs or feature requests to C, or through
391             the web interface at L. I will be notified, and then you'll
392             automatically be notified of progress on your bug as I make changes.
393              
394              
395              
396              
397             =head1 SUPPORT
398              
399             You can find documentation for this module with the perldoc command.
400              
401             perldoc Gtk2::PathButtonBar
402              
403              
404             You can also look for information at:
405              
406             =over 4
407              
408             =item * RT: CPAN's request tracker
409              
410             L
411              
412             =item * AnnoCPAN: Annotated CPAN documentation
413              
414             L
415              
416             =item * CPAN Ratings
417              
418             L
419              
420             =item * Search CPAN
421              
422             L
423              
424             =back
425              
426              
427             =head1 ACKNOWLEDGEMENTS
428              
429              
430             =head1 COPYRIGHT & LICENSE
431              
432             Copyright 2008 Zane C. Bowers, all rights reserved.
433              
434             This program is free software; you can redistribute it and/or modify it
435             under the same terms as Perl itself.
436              
437              
438             =cut
439              
440             1; # End of Gtk2::PathButtonBar