File Coverage

blib/lib/ZConf/Runner/GUI/Curses.pm
Criterion Covered Total %
statement 19 88 21.5
branch 0 26 0.0
condition n/a
subroutine 7 9 77.7
pod n/a
total 26 123 21.1


line stmt bran cond sub pod time code
1             package ZConf::Runner::GUI::Curses;
2              
3 1     1   23483 use warnings;
  1         3  
  1         30  
4 1     1   6 use strict;
  1         2  
  1         30  
5 1     1   637 use ZConf::Runner;
  1         4  
  1         42  
6 1     1   18 use File::MimeInfo::Magic;
  1         3  
  1         91  
7 1     1   7 use File::MimeInfo::Applications;
  1         2  
  1         215  
8              
9             =head1 NAME
10              
11             ZConf::Runner::GUI::Curses - Run a file using a choosen methode, desktop entry or mimetype.
12              
13             =head1 VERSION
14              
15             Version 1.0.1
16              
17             =cut
18              
19             our $VERSION = '1.0.1';
20              
21             =head1 SYNOPSIS
22              
23             This provides the Curses backend for ZConf::Runner::GUI.
24              
25             use ZConf::Runner::GUI::Curses;
26              
27             my $zcr=ZConf::Runner::GUI::Curses->new();
28              
29             =head1 METHODES
30              
31             =head2 new
32              
33             This initializes it.
34              
35             One arguement is taken and that is a hash value.
36              
37             =head3 hash values
38              
39             =head4 useX
40              
41             This is if it should try to use X or not. If it is not defined,
42             ZConf::GUI->useX is used.
43              
44             =head4 zcgui
45              
46             This is the ZConf::GUI object. A new one will be created if it is
47             not passed.
48              
49             =head4 zcrunner
50              
51             This is a ZConf::Runner object to use. If it is not specified,
52             a new one will be created.
53              
54             =cut
55              
56             sub new{
57 0     0     my %args;
58 0 0         if(defined($_[1])){
59 0           %args= %{$_[1]};
  0            
60             }
61              
62 0           my $self={error=>undef, errorString=>undef};
63 0           bless $self;
64              
65             #initiates
66 0 0         if (defined($args{zcrunner})) {
67 0           $self->{zcr}=$args{zcrunner};
68             }else {
69 0           $self->{zcr}=ZConf::Runner->new();
70             }
71              
72 0           $self->{zconf}=$self->{zcr}->{zconf};
73              
74             #
75 0 0         if (defined($args{useX})) {
76 0           $self->{useX}=$args{useX};
77             }else {
78 1     1   8 use ZConf::GUI;
  1         2  
  1         1067  
79 0           $self->{useX}=ZConf::GUI->new({zconf=>$self->{zconf}});
80             }
81            
82 0           return $self;
83             }
84              
85             =head2 ask
86              
87             Please see the documentation for ZConf::Runner::GUI->ask.
88              
89             =cut
90              
91             sub ask{
92 0     0     my $self=$_[0];
93 0           my %args;
94 0 0         if (defined($_[1])) {
95 0           %args= %{$_[1]};
  0            
96             }
97             #blanks any previous errors
98 0           $self->errorblank;
99              
100 0           my $action=$args{action};
101 0           my $object=$args{object};
102              
103             #gets the mimetype for the object
104 0           my $mimetype=mimetype($object);
105              
106             #this makes sure we got a mimetype
107 0 0         if (!defined($mimetype)) {
108 0           warn('ZConf-Runner ask:12: Could not determime the mimetype for "'.$object.'"');
109 0           $self->{error}=12;
110 0           $self->{errorString}='Could not determime the mimetype for "'.$object.'"';
111 0           return undef;;
112             }
113              
114 0           my $terminal='xterm -rv -e ';
115             #if the enviromental variable 'TERMINAL' is set, use
116 0 0         if(defined($ENV{TERMINAL})){
117 0           $terminal=$ENV{TERMINAL};
118             }
119              
120             #escapes it for executing it
121 0           my $eAction=$action;
122 0           $eAction=~s/\"/\\\"/g;
123 0           my $eObject=$object;
124 0           $eObject=~s/\"/\\\"/g;
125              
126 0           my $askcommand='perl -e \'use ZConf::Runner::GUI::Curses;'.
127             'my $zcr=ZConf::Runner::GUI::Curses->new(); '.
128             '$zcr->askGUI({action=>"'.$eAction.'", object=>"'.$eObject.'"});\'';
129              
130 0 0         if ($self->{useX}) {
131 0           system($terminal.' '.$askcommand);
132 0 0         if ($? == -1) {
133 0           warn("ZConf-Runner ask:15: Failed to '".$terminal.' '.$askcommand."'");
134 0           $self->{error}=15;
135 0           $self->{errorString}="Failed to '".$terminal.' '.$askcommand."'";
136 0           return undef;
137             }
138              
139             #we reread it to get any changes
140 0           $self->{zconf}->read({config=>'runner'});
141 0 0         if ($self->{zconf}->{error}) {
142 0           warn('ZConf-Runner-GUI-Curses ask:2: ZConf errored with "'.$self->{zconf}->{error}.
143             '" when trying to reread the ZConf config "runner". errorString="'.
144             $self->{zconf}->{errorString}.'"');
145 0           return undef;
146             }
147              
148 0           my $returned=$self->{zcr}->actionIsSetup($mimetype, $action);
149 0 0         if ($self->{error}) {
150 0           warn('ZConf-Runner ask: actionIsSetup("'.$mimetype.'", "'
151             .$action.'") failed');
152 0           return undef;
153             }
154              
155             #we just assume yes was pushed right now as it is impossible to get
156             #the exit status from something executed using xterm
157 0           return $returned;
158             }else {
159 0           system($askcommand);
160 0           my $exitcode=$? >> 8;
161 0 0         if ($? == -1) {
162 0           warn("ZConf-Runner-GUI-Curses ask:15: Failed to '".$askcommand."'");
163 0           $self->{error}=15;
164 0           $self->{errorString}="Failed to '".$askcommand."'";
165 0           return undef;
166             }
167              
168             #if Quit was selected, just return undef, but don't error
169 0 0         if ($exitcode == 14) {
170 0           return undef;
171             }
172              
173             #if ok was selected and it added with out issue
174 0 0         if ($exitcode == 15) {
175 0           return 1;
176             }
177              
178             #if we get here, it means we errored
179 0           warn("ZConf-Runner ask:16: '".$askcommand."' failed with a exit of '".
180             $exitcode."'");
181 0           $self->{error}=16;
182 0           $self->{errorString}="'".$askcommand."' failed with a exit of '".$exitcode."'";
183 0           return undef;
184             }
185             }
186              
187             =head2 askGUI
188              
189             This handles the actual GUI. Do to the nature of Curses::UI, do not call this directly
190             as it will result in your application exiting.
191              
192             =cut
193              
194             sub askGUI{
195             my $self=$_[0];
196             my %args;
197             if (defined($_[1])) {
198             %args= %{$_[1]};
199             }
200              
201             my $action=$args{action};
202             my $object=$args{object};
203              
204             #blanks any previous errors
205             $self->errorblank;
206              
207             #gets the mimetype for the object
208             my $mimetype=mimetype($object);
209              
210             #this makes sure we got a mimetype
211             if (!defined($mimetype)) {
212             warn('ZConf-Runner-GUI-Curses ask:12: Could not determime the mimetype for "'.$object.'"');
213             $self->{error}=12;
214             $self->{errorString}='Could not determime the mimetype for "'.$object.'"';
215             exit 12;
216             }
217              
218             #get possible applications
219             my ($default, @others) = mime_applications_all($mimetype);
220              
221             #builds the desktop entry array and desktop entry array
222             #the array is used for the values
223             #the hash is used for the the listbox display
224             my @deA;
225             my %deH;
226             my $int=0;
227             #only do the following if it is defined
228             if (defined($default)){
229             $deA[0]=$default->{file};
230             $deA[0]=~s/.*\///;
231             $deA[0]=~s/\.desktop$//;
232             $deA[0]=~s/\n//;
233            
234             $deH{$deA[0]}='*'.$default->get('Name');
235            
236             #we bump this to one as $deA[0] has been setup already
237             $int=1;
238             }
239             my $otherInt=0;
240             while (defined($others[$int])) {
241             $deA[$int]=$others[$otherInt]->{file};
242             $deA[$int]=~s/.*\///;
243             $deA[$int]=~s/\.desktop$//;
244             $deA[$int]=~s/\n//;
245              
246             $deH{$deA[$int]}=$others[$otherInt]->get('Name');
247              
248             $otherInt++;
249             $int++;
250             }
251              
252 1     1   591 use Curses::UI;
  0            
  0            
253             my $cui = Curses::UI->new( -clear_on_exit => 1);
254              
255             #creates the window
256             my $win = $cui->add('window', 'Window', {});
257              
258             #creates the container
259             my $container = $win->add('container', 'Container');
260              
261             #creates the label for the subject text entry
262             my $mimetypeLabel=$container->add('mimetypeLabel', 'Label', -y=>0,
263             -Text=>'Mimetype: '.$mimetype );
264              
265             #this is the label for the desktop entry list box
266             my $desktopLBlabel=$container->add('desktopLBlabel', 'Label', -y=>2, -width=>26,
267             -Text=>'Available Desktop Entries:');
268              
269             #this just labels the three items after it as being desktop values
270             my $desktopValues=$container->add('desktopValues', 'Label', -y=>13,
271             -Text=>'Desktop Entry Values:');
272              
273             #the name of the desktop entry
274             my $desktopName=$container->add('desktopName', 'Label', -y=>14, -width=>80,
275             -Text=>'Name: ');
276              
277             #what the desktop entry executes
278             my $desktopExec=$container->add('desktopExec', 'Label', -y=>15, -width=>80,
279             -Text=>'Exec: ');
280              
281             #the comment for the desktop entry
282             my $desktopComment=$container->add('desktopComment', 'Label', -y=>16, -width=>80,
283             -Text=>'Comment: ');
284              
285             #this allows selection of the what desktop entry to use
286             my $desktopLB=$container->add('desktopLB', , 'Listbox', -y=>3,
287             -width=>30, -height=>8, -border=>1,
288             -values=>\@deA,
289             -labels=>\%deH,
290             -radio=>1,
291             name=>$desktopName,
292             exec=>$desktopExec,
293             comment=>$desktopComment,
294             -onchange=>sub{
295             my $self=$_[0];
296             my $entry = File::DesktopEntry->new($self->get());
297             $self->{name}->text('Name: '.$entry->get('Name'));
298             $self->{exec}->text('Exec: '.$entry->get('Exec'));
299             $self->{comment}->text('Comment: '.$entry->get('Comment'));
300             }
301             );
302              
303             #sets the selection to the first one
304             if (defined($deA[0])) {
305             $desktopLB->set_selection($deA[0]);
306             }
307              
308             #the label for the type
309             my $typeLabel=$container->add('typeLabel', 'Label', -y=>2, -x=>30,
310             -Text=>'Type:');
311              
312             #this is the type
313             my $typeLB=$container->add('typeLB', , 'Listbox', -y=>3, -x=>30,
314             -width=>'13', -height=>8, -border=>1,
315             -values=>['desktop', 'exec'],
316             -labels=>{'desktop'=>'Desktop', 'exec'=>'Exec'},
317             -radio=>1
318             );
319             $typeLB->set_selection('desktop'); #default to desktop
320              
321             #various notes
322             my $defaultSymbol=$container->add('defaultSymbol', 'Label', -y=>11,
323             -Text=>'*=default Exec: %f=file');
324              
325             #label the exec
326             my $execLabel=$container->add('execLabel', 'Label', -y=>12,
327             -Text=>'Exec:');
328              
329             #allows the exec to be updated
330             my $execEditor=$container->add('execEditor', 'TextEntry', -y=>12, -x=>6);
331              
332              
333             #the various buttons...
334             my $buttons=$container->add('buttons',
335             'Buttonbox',
336             -y=>1,
337             desktopLB=>$desktopLB,
338             typeLB=>$typeLB,
339             exec=>$execEditor,
340             zcr=>$self->{zcr},
341             mimetype=>$mimetype,
342             action=>$action,
343             -buttons=>[{-label=>'Quit',
344             -value=>'quit',
345             -onpress=>sub{
346             exit 14;
347             },
348             },
349             {
350             -label=>'Ok',
351             -value=>'ok',
352             -onpress=>sub{
353             my $self=$_[0];
354             my $entry=$self->{desktopLB}->get();
355             my $type=$self->{typeLB}->get();
356             my $exec=$self->{exec}->get();
357             my $mimetype=$self->{mimetype};
358              
359             #error if desktop is selected and none
360             #exist or is selected
361             if (($type eq 'desktop') &&
362             !defined($entry)) {
363             warn('ZConf-Runner-GUI-Curses askGUI:14: No desktop entry'.
364             'specified or none exists for this mimetype.');
365             #we are not going to set the error or etc here
366             #as we exit.
367             exit 16;
368             }
369            
370            
371             #figures out what the do should be
372             my $do=undef;
373             if ($type eq 'desktop') {
374             $do=$entry;
375             }else {
376             $do=$exec;
377             }
378              
379             #
380             $self->{zcr}->newRunner({
381             mimetype=>$mimetype,
382             action=>$action,
383             type=>$type,
384             do=>$do
385             }
386             );
387              
388             #checks for any errors
389             if ($self->{zcr}->{error}) {
390             exit 17;
391             }
392              
393             #exit ok
394             exit 15;
395             }
396             }
397             ]
398             );
399              
400             #start the CUI loop...
401             #there is no return outside of exit from here :(
402             $cui->mainloop;
403             return;
404             }
405              
406             =head2 dialogs
407              
408             This returns the available dailogs.
409              
410             =cut
411              
412             sub dialogs{
413             return ('ask');
414             }
415              
416             =head2 windows
417              
418             This returns a list of available windows.
419              
420             =cut
421              
422             sub windows{
423             return undef;
424             }
425              
426             =head2 errorblank
427              
428             This blanks the error storage and is only meant for internal usage.
429              
430             It does the following.
431              
432             $self->{error}=undef;
433             $self->{errorString}="";
434              
435             =cut
436              
437             #blanks the error flags
438             sub errorblank{
439             my $self=$_[0];
440              
441             $self->{error}=undef;
442             $self->{errorString}="";
443              
444             return 1;
445             }
446              
447             =head1 dialogs
448              
449             ask
450              
451             =head1 windows
452              
453             At this time, no windows are supported.
454              
455             =head1 AUTHOR
456              
457             Zane C. Bowers, C<< >>
458              
459             =head1 BUGS
460              
461             Please report any bugs or feature requests to C, or through
462             the web interface at L. I will be notified, and then you'll
463             automatically be notified of progress on your bug as I make changes.
464              
465              
466              
467              
468             =head1 SUPPORT
469              
470             You can find documentation for this module with the perldoc command.
471              
472             perldoc ZConf::Runner::GUI::Curses
473              
474              
475             You can also look for information at:
476              
477             =over 4
478              
479             =item * RT: CPAN's request tracker
480              
481             L
482              
483             =item * AnnoCPAN: Annotated CPAN documentation
484              
485             L
486              
487             =item * CPAN Ratings
488              
489             L
490              
491             =item * Search CPAN
492              
493             L
494              
495             =back
496              
497              
498             =head1 ACKNOWLEDGEMENTS
499              
500              
501             =head1 COPYRIGHT & LICENSE
502              
503             Copyright 2008 Zane C. Bowers, all rights reserved.
504              
505             This program is free software; you can redistribute it and/or modify it
506             under the same terms as Perl itself.
507              
508              
509             =cut
510              
511             1; # End of ZConf::Runner::GUI::Curses