File Coverage

blib/lib/App/Chart/Gtk2/Job.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # Copyright 2007, 2008, 2009, 2010, 2011, 2016, 2017 Kevin Ryde
2              
3             # This file is part of Chart.
4             #
5             # Chart is free software; you can redistribute it and/or modify it under the
6             # terms of the GNU General Public License as published by the Free Software
7             # Foundation; either version 3, or (at your option) any later version.
8             #
9             # Chart is distributed in the hope that it will be useful, but WITHOUT ANY
10             # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11             # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12             # details.
13             #
14             # You should have received a copy of the GNU General Public License along
15             # with Chart. If not, see <http://www.gnu.org/licenses/>.
16              
17             package App::Chart::Gtk2::Job;
18 1     1   411 use strict;
  1         2  
  1         24  
19 1     1   5 use warnings;
  1         2  
  1         24  
20 1     1   4 use Carp;
  1         2  
  1         63  
21 1     1   202 use Gtk2;
  0            
  0            
22             use POSIX qw(dup2 EWOULDBLOCK INT_MIN INT_MAX);
23             use Locale::TextDomain ('App-Chart');
24              
25             use Glib::Ex::FreezeNotify;
26             use App::Chart;
27              
28             # uncomment this to run the ### lines
29             # use Smart::Comments;
30              
31             # Have had some trouble with segvs during exit
32             #
33             #
34              
35             use Glib::Object::Subclass
36             'Glib::Object',
37             signals => { notify => \&_do_notify,
38             message => { param_types => ['Glib::String'],
39             return_type => undef },
40             status_changed => { param_types => ['Glib::String'],
41             return_type => undef },
42             },
43             properties => [Glib::ParamSpec->int
44             ('priority',
45             'Priority',
46             'The priority of this job.',
47             INT_MIN, INT_MAX,
48             0, # default
49             Glib::G_PARAM_READWRITE),
50              
51             Glib::ParamSpec->string
52             ('name',
53             'Job name',
54             'Blurb.',
55             '',
56             Glib::G_PARAM_READWRITE),
57              
58             # various nested perl array
59             Glib::ParamSpec->scalar
60             ('args',
61             'Job arguments',
62             'Blurb.',
63             Glib::G_PARAM_READWRITE),
64              
65             Glib::ParamSpec->string
66             ('status',
67             'Status',
68             'Blurb.',
69             '',
70             Glib::G_PARAM_READWRITE),
71              
72             Glib::ParamSpec->object
73             ('subprocess',
74             'Subprocess',
75             'Blurb.',
76             # actually 'App::Chart::Gtk2::Subprocess', but saying that
77             # creates package load order headaches
78             'Glib::Object',
79             Glib::G_PARAM_READWRITE),
80              
81             Glib::ParamSpec->boolean
82             ('done',
83             'Done',
84             'Blurb.',
85             0,
86             Glib::G_PARAM_READWRITE),
87              
88             ];
89              
90              
91             #------------------------------------------------------------------------------
92              
93             sub INIT_INSTANCE {
94             my ($self) = @_;
95             $self->{'status'} = '';
96             }
97              
98             sub SET_PROPERTY {
99             my ($self, $pspec, $newval) = @_;
100             my $pname = $pspec->get_name;
101             $self->{$pname} = $newval; # per default GET_PROPERTY
102             }
103              
104             sub FINALIZE_INSTANCE {
105             my ($self) = @_;
106             $self->stop;
107             }
108              
109             # 'notify' signal class closure
110             sub _do_notify {
111             my ($self, $pspec) = @_;
112             ### Job _do_notify(): $pspec->get_name
113              
114             $self->signal_chain_from_overridden ($pspec);
115              
116             # emit 'status-changed' under notify so it's held up by freeze_notify
117             if ($pspec->get_name eq 'status') {
118             ### Job emit status-changed ...
119             $self->signal_emit ('status-changed', $self->{'status'});
120             }
121             }
122              
123             sub priority {
124             my ($self) = @_;
125             return $self->get('priority');
126             }
127             sub status {
128             my ($self) = @_;
129             return $self->{'status'};
130             }
131              
132             sub delete {
133             my ($self) = @_;
134             $self->stop;
135             App::Chart::Gtk2::JobQueue->remove_job ($self);
136             }
137              
138             sub start {
139             my ($class, @params) = @_;
140             ### Job start()
141             ### @params
142              
143             my $self = $class->new (@params);
144             require App::Chart::Gtk2::JobQueue;
145             App::Chart::Gtk2::JobQueue->enqueue ($self);
146             return $self;
147             }
148              
149             sub stop {
150             my ($self) = @_;
151             ### Job stop()
152             my $freezer = Glib::Ex::FreezeNotify->new ($self);
153             if (my $proc = $self->{'subprocess'}) {
154             $freezer->add ($proc);
155             $proc->stop; # will remove itself from our 'subprocess' property
156             }
157             $self->set (done => 1,
158             status => __('Stopped'));
159             }
160             sub is_stoppable {
161             my ($self) = @_;
162             return defined $self->{'subprocess'};
163             }
164             sub is_done {
165             my ($self) = @_;
166             return ! defined $self->{'subprocess'};
167             }
168              
169             sub message {
170             my ($self, $str) = @_;
171             if ($str eq '') { return; }
172             ### Job message: "$self \"$str\""
173             $self->signal_emit ('message', $str);
174             }
175              
176             sub type {
177             return 'Job';
178             }
179              
180              
181             1;
182             __END__
183              
184             =head1 NAME
185              
186             App::Chart::Gtk2::Job -- download job object
187              
188             =head1 SYNOPSIS
189              
190             use App::Chart::Gtk2::Job;
191              
192             =head1 FUNCTIONS
193              
194             =over 4
195              
196             =item C<< App::Chart::Gtk2::Job->start (key=>value,...) >>
197              
198             Start a new download job.
199              
200             args array ref of command line arguments
201             type string
202              
203             =item C<< $job->stop() >>
204              
205             Stop C<$job>.
206              
207             =item C<< $job->is_stoppable() >>
208              
209             Return true if C<$job> is running, which means it can be stopped.
210              
211             =item C<< $job->is_done() >>
212              
213             Return true if C<$job> not running, but has finished, either successfully or
214             unsuccessfully.
215              
216             =back
217              
218             =head1 PROPERTIES
219              
220             =over 4
221              
222             =item C<name> (integer)
223              
224             ...
225              
226             =item C<args> (arrayref of strings, create-only)
227              
228             ...
229              
230             =item C<priority> (integer)
231              
232             ...
233              
234             =item C<status> (string)
235              
236             A free-form string describing the status of the job. For example while in
237             the job queue it's "Waiting", and later if finished successfully then "Done".
238              
239             =back
240              
241             =cut
242