File Coverage

blib/lib/Term/Report.pm
Criterion Covered Total %
statement 3 113 2.6
branch 0 52 0.0
condition 0 23 0.0
subroutine 1 14 7.1
pod 8 11 72.7
total 12 213 5.6


line stmt bran cond sub pod time code
1             package Term::Report;
2 1     1   5878 no warnings 'portable';
  1         2  
  1         1691  
3              
4             $|++;
5             require 5.6.0;
6             our ($CR, $FH);
7             our $VERSION = '1.18';
8              
9              
10             sub new {
11 0     0 1   my ($class, %params) = @_;
12              
13 0   0       my $self = bless {
      0        
      0        
      0        
      0        
14             curText => undef,
15             prevText => undef,
16             currentRow => $params{startRow} || 1,
17             startRow => $params{startRow} || 1,
18             startCol => $params{startCol} || 1,
19             numFormat => $params{numFormat},
20             statusBar => $params{statusBar},
21             SP => {}, ## Save point list
22             noPrint => 0, ## Delays printing of text
23             fh => $params{fh} || *STDOUT,
24             }, ref($class) || $class;
25              
26 0           $FH = $self->{fh};
27              
28             ## Do we want to format numbers?
29 0 0         if ($self->{numFormat}){
30 0 0         if ($self->loadModule("Number::Format", "numFormat")){
31 0 0         if (ref($self->{numFormat}) ne 'ARRAY'){
32 0           $self->{numFormat} = Number::Format->new(
33             -MON_DECIMAL_POINT => ',',
34             -INT_CURR_SYMBOL => '',
35             -DECIMAL_DIGITS => 0,
36             );
37             }
38             else{
39 0           $self->{numFormat} = Number::Format->new(@{$self->{numFormat}});
  0            
40             }
41             }
42             }
43              
44             ## Do we have a Term::StatusBar?
45 0 0         if ($self->{statusBar}){
46 0 0         if ($self->loadModule("Term::StatusBar", "statusBar")){
47 0 0         if (ref($self->{statusBar}) ne "ARRAY"){
48 0           $self->{statusBar} = Term::StatusBar->new(fh=>$self->{fh});
49             }
50             else{
51 0           push @{$self->{statusBar}}, ("fh", $self->{fh});
  0            
52 0           $self->{statusBar} = Term::StatusBar->new(@{$self->{statusBar}});
  0            
53             }
54             }
55             }
56              
57             ## If Term::StatusBar is inside, we will override
58             ## it's SIG{INT}. If not wrapped and called after
59             ## we are created, SIG{INT} will not 'behave' and
60             ## will drop the cursor on the 2nd row rather than
61             ## 2 rows down from current cursor position.
62 0           $CR = \$self->{currentRow};
63 0           $SIG{INT} = \&{__PACKAGE__."::sigint"};
  0            
64              
65 0 0 0       if (!defined $params{cls} || $params{cls}){ print $FH "\033[2J\033[0;0H"; }
  0            
66              
67 0           return $self;
68             }
69              
70              
71             ##
72             ## This must be done manually now since trying to do it
73             ## in DESTROY causes problems in many instances
74             ##
75             sub finished {
76 0     0 1   print $FH "\033[$$CR;1H\033[0m\n\n";
77             }
78              
79             ##
80             ## Just in case this isn't done in caller. We
81             ## need to be able to reset the display.
82             ##
83             sub sigint {
84 0     0 0   finished();
85 0           exit;
86             }
87              
88              
89             ##
90             ## Attempt to load module
91             ##
92              
93             sub loadModule {
94 0     0 0   my ($self, $module, $key) = @_;
95              
96 0           eval "require $module";
97              
98 0 0         if ($@){
99 0           $self->{$key} = 0;
100 0           return 0;
101             }
102 0           return 1;
103             }
104              
105             ##
106             ## Used to get/set object variables.
107             ##
108             sub AUTOLOAD {
109 0     0     my ($self, $val) = @_;
110 0           (my $method = $AUTOLOAD) =~ s/.*:://;
111              
112 0 0         if (exists $self->{$method}){
113 0 0         if (defined $val){
114 0           $self->{$method} = $val;
115             }
116             else{
117 0           return $self->{$method};
118             }
119             }
120             }
121              
122              
123             ##
124             ## Clears the screen
125             ##
126             sub clear {
127 0     0 1   print $FH "\033[2J\033[0;0H";
128 0           $self->{currentRow} = $self->{startRow};
129             }
130              
131              
132             ##
133             ## Prints text to screen based on manual
134             ## cursor positioning.
135             ##
136             sub finePrint {
137 0     0 1   my ($self, $row, $col, @text) = @_;
138 0           my $text = join('', @text);
139              
140             ## Passed a save point label
141 0 0         if ($row !~ /^\d+$/){
142 0           my $label = $row;
143              
144 0 0         if (!exists $self->{SP}->{$label}){
145 0           die "\033[20;0HNo SavePoint by the name <$label>\n";
146             }
147 0           $row = $self->{SP}->{$label}->row;
148              
149 0 0         if (my $t = $self->{SP}->{$label}->text){
150             ## We only want to reset once to avoid
151             ## flickering as much as possible
152 0 0         if (!$self->{SP}->{$label}->reset){
153             ## Clear current row to replace text
154 0           print $FH "\033[$row;1H\033[K";
155 0           $text = $t.$text;
156 0           $self->{SP}->{$label}->reset(1);
157 0           $col = $self->{SP}->{$label}->col;
158             }
159             else{
160 0           $col = $self->{SP}->{$label}->textLen+1;
161             }
162             }
163             else{
164 0           $col = $self->{SP}->{$label}->textLen;
165             }
166             }
167              
168 0           print $FH "\033[$row;${col}H";
169 0 0         $self->{currentRow} = $row if $row > $self->{currentRow};
170              
171 0 0         if ($self->{numFormat}){
172 0           $text =~ s/(\d+)/$self->{numFormat}->format_number($1)/sge;
  0            
173             }
174              
175 0           print $FH $text;
176             }
177              
178              
179             ##
180             ## Prints text to screen based on current
181             ## cursor positioning.
182             ##
183             sub printLine {
184 0     0 1   my $self = shift;
185 0           my $text = join('', @_);
186              
187 0 0         if ($self->{numFormat}){
188 0           $text =~ s/(\d+)/$self->{numFormat}->format_number($1)/sge;
  0            
189             }
190              
191 0 0         if (!$self->{prevText}){
192 0           $self->adjustCurRow(\$text);
193 0           print $FH "\033[$self->{currentRow};$self->{startCol}H";
194 0           $self->{prevText} = $text;
195             }
196             else{
197 0 0         if ($self->{prevText} !~ /\n/){
198 0 0         if ($text =~ /^\n/){
199 0           $self->adjustCurRow(\$text);
200 0           $self->{prevText} = $text;
201 0           print $FH "\033[$self->{currentRow};$self->{startCol}H";
202             }
203             else{
204 0           $self->{prevText} .= $text;
205 0           print $FH "\033[$self->{currentRow};", (length($self->{prevText})), "H";
206             }
207             }
208             else{
209 0           $self->{currentRow} += ($self->{prevText} =~ s/\n/\n/g);
210 0           $self->adjustCurRow(\$text);
211 0           $self->{prevText} = $text;
212 0           print $FH "\033[$self->{currentRow};$self->{startCol}H";
213             }
214             }
215              
216 0           $self->{curText} = $text;
217 0 0         print $FH $text if !$self->{noPrint};
218             }
219              
220              
221             ##
222             ## Keeps track of where current row
223             ## should be for line placements
224             ##
225             sub adjustCurRow{
226 0     0 0   my ($self, $text) = @_;
227 0           my $len = length($$text);
228 0           $$text =~ s/^\n+//;
229 0           $self->{currentRow} += ($len - length($$text));
230             }
231              
232             ##
233             ## Returns length of text
234             ##
235             sub lineLength {
236 0     0 1   length shift()->{shift()};
237             }
238              
239              
240             ##
241             ## Prints out a bar report.
242             ##
243             sub printBarReport {
244 0     0 1   my ($self, $header, $config) = @_;
245            
246 0 0         return if !defined $self->{statusBar};
247 0           $self->printLine($header);
248              
249             ## Backwards compatibility
250 0           my $temp = [];
251 0 0         if (ref($config) eq 'HASH'){
252             ## Just flatten hash
253 0           @$temp = %$config;
254 0           $config = $temp;
255             }
256              
257 0           my $x=0;
258 0           for my $k (@$config){
259 0           my $num = int(($self->{statusBar}->{scale}/$self->{statusBar}->{totalItems}) * $config->[$x+1]);
260            
261 0 0         if ($num < length($config->[$x+1])){
262 0           $num = length($config->[$x+1]);
263             }
264            
265 0           $self->printLine($config->[$x], "\033[7;37m\033[40m", $config->[$x+1], " "x($num), "\033[0m\n");
266 0           $x+=2;
267             }
268             }
269              
270              
271             ##
272             ## Stores information on screen locations for
273             ## easy referencing later in code
274             ##
275             sub savePoint {
276 0     0 1   my ($self, $label, $text, $print) = @_;
277 0 0         return if !defined $label;
278              
279 0 0         if (defined $text){
280 0           $self->{noPrint} = !$print;
281 0           $self->printLine($text);
282 0           $self->{noPrint} = 0;
283             }
284              
285 0           $self->{SP}->{$label} = Term::Report::SP->new({
286             label => $label,
287             text => $self->{curText},
288             textLen => $self->lineLength('curText'),
289             row => $self->currentRow(),
290             col => $self->{startCol},
291             });
292             }
293              
294              
295             ## Internal package to provide easy access
296             ## to the report's save points
297             package Term::Report::SP;
298             *{__PACKAGE__."::AUTOLOAD"} = \&Term::Report::AUTOLOAD;
299              
300             sub new {
301 0   0 0     bless {
      0        
      0        
      0        
302             label => $_[1]->{label} || undef,
303             text => $_[1]->{text} || undef,
304             textLen => $_[1]->{textLen} || undef,
305             row => $_[1]->{row} || undef,
306             col => $_[1]->{col},
307             reset => 0,
308             }, $_[0];
309             }
310              
311              
312             1;
313             __END__