File Coverage

blib/lib/Gtk2/Ex/TreeModelBits.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, 2012 Kevin Ryde
2              
3             # This file is part of Gtk2-Ex-WidgetBits.
4             #
5             # Gtk2-Ex-WidgetBits is free software; you can redistribute it and/or
6             # modify it under the terms of the GNU General Public License as published
7             # by the Free Software Foundation; either version 3, or (at your option) any
8             # later version.
9             #
10             # Gtk2-Ex-WidgetBits is distributed in the hope that it will be useful,
11             # but WITHOUT ANY WARRANTY; without even the implied warranty of
12             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13             # Public License for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Gtk2-Ex-WidgetBits. If not, see .
17              
18             package Gtk2::Ex::TreeModelBits;
19 2     2   1727 use 5.008;
  2         7  
  2         82  
20 2     2   10 use strict;
  2         3  
  2         60  
21 2     2   11 use warnings;
  2         4  
  2         465  
22 2     2   2800 use Gtk2;
  0            
  0            
23              
24             use Exporter;
25             our @ISA = ('Exporter');
26             our @EXPORT_OK = qw(column_contents
27             remove_matching_rows
28             all_column_types
29             iter_prev);
30              
31             our $VERSION = 48;
32              
33             # uncomment this to run the ### lines
34             #use Smart::Comments;
35              
36             sub column_contents {
37             my ($model, $column) = @_;
38             my @ret;
39              
40             # pre-extend, helpful for a list model style, likely to do little for an
41             # actual tree
42             $#ret = $model->iter_n_children(undef) - 1;
43              
44             my $pos = 0;
45             $model->foreach (sub {
46             my ($model, $path, $iter) = @_;
47             $ret[$pos++] = $model->get_value ($iter, $column);
48             return 0; # keep walking
49             });
50             # iterating should give n_children, trim @ret if it doesn't
51             ### assert: $pos >= scalar(@ret)
52             $#ret = $pos-1;
53              
54             return @ret;
55             }
56              
57             # If a remove() might end up removing more than one row then it's expected
58             # to leave $iter at whatever next row then exists (at the same depth).
59             # A multi-remove happens for instance in Gtk2::Ex::ListModelConcat when it's
60             # presenting two or more copies of one submodel.
61             # Gtk2::Ex::TreeModelFilter::Change::remove() asks for similar from its
62             # child remove().
63             #
64             sub remove_matching_rows {
65             my $model = shift;
66             my $subr = shift;
67              
68             my @pending;
69             my $iter = $model->get_iter_first;
70              
71             for (;;) {
72             # undef at end of one level, pop to upper level, or finished if no upper
73             $iter ||= pop @pending || last;
74             ### looking at: $model->get_path($iter)->to_string
75              
76             if ($subr->($model, $iter, @_)) {
77             if (! $model->remove ($iter)) {
78             $iter = undef; # no more at this depth
79             }
80             # otherwise $iter updated to next row
81             next;
82             }
83              
84             my $child = $model->iter_children ($iter);
85             $iter = $model->iter_next ($iter);
86              
87             if ($child) {
88             ### descend to child: $model->get_path($child)->to_string
89             push @pending, $iter;
90             $iter = $child;
91             }
92             }
93             }
94              
95             sub all_column_types {
96             my ($model) = @_;
97             return map { $model->get_column_type($_) } 0 .. $model->get_n_columns - 1;
98             }
99              
100             sub iter_prev {
101             my ($model, $iter) = @_;
102             my $path = $model->get_path ($iter);
103             return ($path->prev
104             ? $model->get_iter ($path) # path moved
105             : undef); # no more nodes (last path index was 0)
106             }
107              
108             1;
109             __END__