File Coverage

blib/lib/Renard/Curie/Model/Outline.pm
Criterion Covered Total %
statement 15 34 44.1
branch 0 2 0.0
condition 0 7 0.0
subroutine 5 6 83.3
pod n/a
total 20 49 40.8


line stmt bran cond sub pod time code
1 1     1   898 use Renard::Curie::Setup;
  1         2  
  1         6  
2             package Renard::Curie::Model::Outline;
3             # ABSTRACT: Model that represents a document outline
4             $Renard::Curie::Model::Outline::VERSION = '0.002';
5 1     1   540 use Moo;
  1         6551  
  1         4  
6 1         13 use Renard::Curie::Types qw(
7             ArrayRef Dict
8             PositiveOrZeroInt Str LaxPageNumber
9 1     1   1193 InstanceOf );
  1         2  
10 1     1   1334 use Type::Utils qw( declare as where message );
  1         2  
  1         7  
11              
12             my $Outline = declare
13             as ArrayRef[Dict[
14             level => PositiveOrZeroInt,
15             text => Str,
16             page => LaxPageNumber
17             ]];
18             my $OutlineLevelCheck = declare
19             as $Outline,
20             where {
21             my @outline = @$_;
22             for my $idx (0..@outline-2) {
23             my $current_level = $outline[$idx]{level};
24             my $next_level = $outline[$idx + 1]{level};
25             if( $current_level < $next_level
26             and $current_level + 1 != $next_level ) {
27             # This is a malformed outline. It should not
28             # be possible to go down multiple levels at
29             # a time.
30             return 0;
31             }
32             }
33             return 1;
34             },
35             message {
36             $Outline->validate($_)
37             or "Outline item data has malformed levels";
38             };
39              
40             has items => (
41             is => 'rw',
42             required => 1,
43             isa => $OutlineLevelCheck,
44             );
45              
46             has tree_store => (
47             is => 'lazy', # _build_tree_store
48             isa => InstanceOf['Gtk3::TreeStore'],
49             );
50              
51              
52 0     0     method _build_tree_store() {
  0            
53             # load Gtk3 dynamically if used outside Gtk3 context
54 0           require Gtk3;
55 0           Gtk3->import(qw(-init));
56              
57 0           my $data = Gtk3::TreeStore->new( 'Glib::String', 'Glib::String', );
58              
59 0           my $outline_items = $self->items;
60 0           my $level = 0;
61 0           my $iter = undef;
62 0           my @parents = ();
63              
64 0           for my $item (@$outline_items) {
65 1     1   1900 no autovivification;
  1         1262  
  1         4  
66              
67             # If we need to go up to the parent iterators.
68 0   0       while( @parents && $item->{level} < @parents ) {
69 0           $iter = pop @parents;
70             }
71              
72 0 0         if( $item->{level} > @parents ) {
73             # If we need to go one level down to a child.
74             # NOTE : This is not a while(...) loop because the
75             # outline should only increase one level at a time.
76 0           push @parents, $iter;
77 0           $iter = $data->append($iter);
78 0           $level++;
79             } else {
80             # We are still at the same level. Just add a new row to
81             # that last parent (or undef if we are at the root).
82 0   0       $iter = $data->append( $parents[-1] // undef );
83             }
84              
85             $data->set( $iter,
86             0 => $item->{text} // '',
87 0   0       1 => $item->{page} );
88             }
89              
90 0           $data;
91             }
92              
93             1;
94              
95             __END__
96              
97             =pod
98              
99             =encoding UTF-8
100              
101             =head1 NAME
102              
103             Renard::Curie::Model::Outline - Model that represents a document outline
104              
105             =head1 VERSION
106              
107             version 0.002
108              
109             =head1 EXTENDS
110              
111             =over 4
112              
113             =item * L<Moo::Object>
114              
115             =back
116              
117             =head1 ATTRIBUTES
118              
119             =head2 items
120              
121             An C<ArrayRef[HashRef]> with a simple representation of an outline where each
122             item of the ArrayRef represents an item in the list of headings displayed in
123             order.
124              
125             Each C<HashRef> element is an element of the outline with the structure:
126              
127             {
128             # The level in the outline that the item is at. Starts at zero (0).
129             level => PositiveOrZeroInt,
130              
131             # The textual description of the item.
132             text => Str,
133              
134             # The page number that the outline item points to.
135             page => LaxPageNumber,
136             }
137              
138             A complete example is:
139              
140             [
141             {
142             level => 0,
143             text => 'Chapter 1',
144             page => 20,
145             },
146             {
147             level => 1,
148             text => 'Section 1.1',
149             page => 25,
150             },
151             {
152             level => 0,
153             text => 'Chapter 2',
154             page => 30,
155             },
156             ]
157              
158             which represents the outline
159              
160             Chapter 1 .......... 20
161             Section 1.1 ...... 25
162             Chapter 2 .......... 30
163              
164             =head2 tree_store
165              
166             The L<Gtk3::TreeStore> representation for this outline. It holds tree data of
167             the heading text and page numbers.
168              
169             =head1 AUTHOR
170              
171             Project Renard
172              
173             =head1 COPYRIGHT AND LICENSE
174              
175             This software is copyright (c) 2016 by Project Renard.
176              
177             This is free software; you can redistribute it and/or modify it under
178             the same terms as the Perl 5 programming language system itself.
179              
180             =cut